libcryptsetup_rs/
keyfile.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
5use std::{path::Path, ptr};
6
7use libc::{c_char, c_void};
8
9use crate::{
10    consts::flags::CryptKeyfile, device::CryptDevice, err::LibcryptErr, mem::SafeMemHandle,
11};
12
13/// Contents of a keyfile that have been read
14pub struct CryptKeyfileContents {
15    key_mem: SafeMemHandle,
16}
17
18impl AsRef<[u8]> for CryptKeyfileContents {
19    fn as_ref(&self) -> &[u8] {
20        self.key_mem.as_ref()
21    }
22}
23
24/// Handle for keyfile operations
25pub struct CryptKeyfileHandle<'a> {
26    reference: &'a mut CryptDevice,
27}
28
29impl<'a> CryptKeyfileHandle<'a> {
30    /// Create a new keyfile operation handle
31    pub(crate) fn new(reference: &'a mut CryptDevice) -> Self {
32        CryptKeyfileHandle { reference }
33    }
34
35    /// Read keyfile into memory - these bindings will automatically
36    /// safely clean it up after `CryptKeyfileContents` is dropped
37    pub fn device_read(
38        &mut self,
39        keyfile: &Path,
40        keyfile_offset: u64,
41        key_size: Option<crate::size_t>,
42        flags: CryptKeyfile,
43    ) -> Result<CryptKeyfileContents, LibcryptErr> {
44        let keyfile_cstring = path_to_cstring!(keyfile)?;
45        let keyfile_size = match key_size {
46            Some(i) => i,
47            None => std::fs::metadata(keyfile)
48                .map_err(LibcryptErr::IOError)?
49                .len() as crate::size_t,
50        };
51
52        let mut key: *mut c_char = ptr::null_mut();
53        let mut size: crate::size_t = 0;
54        errno!(mutex!(libcryptsetup_rs_sys::crypt_keyfile_device_read(
55            self.reference.as_ptr(),
56            keyfile_cstring.as_ptr(),
57            &mut key as *mut *mut c_char,
58            &mut size as *mut crate::size_t,
59            keyfile_offset,
60            keyfile_size,
61            flags.bits(),
62        )))?;
63        Ok(CryptKeyfileContents {
64            key_mem: unsafe { SafeMemHandle::from_ptr(key.cast::<c_void>(), size) },
65        })
66    }
67}