diff --git a/pbs-api-types/Cargo.toml b/pbs-api-types/Cargo.toml index 840d36bd..585bb9c6 100644 --- a/pbs-api-types/Cargo.toml +++ b/pbs-api-types/Cargo.toml @@ -7,6 +7,7 @@ description = "general API type helpers for PBS" [dependencies] anyhow = "1.0" +hex = "0.4.3" lazy_static = "1.4" libc = "0.2" nix = "0.19.1" @@ -21,4 +22,3 @@ proxmox-time = "1.0.0" proxmox-uuid = { version = "1.0.0", features = [ "serde" ] } proxmox-systemd = { path = "../proxmox-systemd" } -pbs-tools = { path = "../pbs-tools" } diff --git a/pbs-api-types/src/crypto.rs b/pbs-api-types/src/crypto.rs index 016970f8..eda92e23 100644 --- a/pbs-api-types/src/crypto.rs +++ b/pbs-api-types/src/crypto.rs @@ -5,8 +5,6 @@ use serde::{Deserialize, Serialize}; use proxmox_schema::api; -use pbs_tools::format::{as_fingerprint, bytes_as_fingerprint}; - #[api(default: "encrypt")] #[derive(Copy, Clone, Debug, Eq, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "kebab-case")] @@ -55,3 +53,43 @@ impl std::str::FromStr for Fingerprint { } } +fn as_fingerprint(bytes: &[u8]) -> String { + hex::encode(bytes) + .as_bytes() + .chunks(2) + .map(|v| unsafe { std::str::from_utf8_unchecked(v) }) // it's a hex string + .collect::>().join(":") +} + +pub mod bytes_as_fingerprint { + use std::mem::MaybeUninit; + + use serde::{Deserialize, Serializer, Deserializer}; + + pub fn serialize( + bytes: &[u8; 32], + serializer: S, + ) -> Result + where + S: Serializer, + { + let s = super::as_fingerprint(bytes); + serializer.serialize_str(&s) + } + + pub fn deserialize<'de, D>( + deserializer: D, + ) -> Result<[u8; 32], D::Error> + where + D: Deserializer<'de>, + { + // TODO: more efficiently implement with a Visitor implementing visit_str using split() and + // hex::decode by-byte + let mut s = String::deserialize(deserializer)?; + s.retain(|c| c != ':'); + let mut out = MaybeUninit::<[u8; 32]>::uninit(); + hex::decode_to_slice(s.as_bytes(), unsafe { &mut (*out.as_mut_ptr())[..] }) + .map_err(serde::de::Error::custom)?; + Ok(unsafe { out.assume_init() }) + } +} diff --git a/pbs-api-types/src/lib.rs b/pbs-api-types/src/lib.rs index a61de960..eebf5794 100644 --- a/pbs-api-types/src/lib.rs +++ b/pbs-api-types/src/lib.rs @@ -64,7 +64,7 @@ pub use user::*; pub use proxmox_schema::upid::*; mod crypto; -pub use crypto::{CryptMode, Fingerprint}; +pub use crypto::{CryptMode, Fingerprint, bytes_as_fingerprint}; pub mod file_restore; diff --git a/pbs-config/src/key_config.rs b/pbs-config/src/key_config.rs index 9397633d..def83aba 100644 --- a/pbs-config/src/key_config.rs +++ b/pbs-config/src/key_config.rs @@ -100,7 +100,7 @@ impl From<&KeyConfig> for KeyInfo { fingerprint: key_config .fingerprint .as_ref() - .map(|fp| pbs_tools::format::as_fingerprint(fp.bytes())), + .map(|fp| fp.to_string()), hint: key_config.hint.clone(), } } diff --git a/pbs-config/src/tape_encryption_keys.rs b/pbs-config/src/tape_encryption_keys.rs index 4919ad86..eb34bdd6 100644 --- a/pbs-config/src/tape_encryption_keys.rs +++ b/pbs-config/src/tape_encryption_keys.rs @@ -190,5 +190,5 @@ pub fn complete_key_fingerprint(_arg: &str, _param: &HashMap) -> Err(_) => return Vec::new(), }; - data.keys().map(|fp| pbs_tools::format::as_fingerprint(fp.bytes())).collect() + data.keys().map(|fp| fp.to_string()).collect() } diff --git a/pbs-tools/src/format.rs b/pbs-tools/src/format.rs index 0823ea29..feabd8f1 100644 --- a/pbs-tools/src/format.rs +++ b/pbs-tools/src/format.rs @@ -103,47 +103,6 @@ impl From for HumanByte { } } -pub fn as_fingerprint(bytes: &[u8]) -> String { - hex::encode(bytes) - .as_bytes() - .chunks(2) - .map(|v| unsafe { std::str::from_utf8_unchecked(v) }) // it's a hex string - .collect::>().join(":") -} - -pub mod bytes_as_fingerprint { - use std::mem::MaybeUninit; - - use serde::{Deserialize, Serializer, Deserializer}; - - pub fn serialize( - bytes: &[u8; 32], - serializer: S, - ) -> Result - where - S: Serializer, - { - let s = super::as_fingerprint(bytes); - serializer.serialize_str(&s) - } - - pub fn deserialize<'de, D>( - deserializer: D, - ) -> Result<[u8; 32], D::Error> - where - D: Deserializer<'de>, - { - // TODO: more efficiently implement with a Visitor implementing visit_str using split() and - // hex::decode by-byte - let mut s = String::deserialize(deserializer)?; - s.retain(|c| c != ':'); - let mut out = MaybeUninit::<[u8; 32]>::uninit(); - hex::decode_to_slice(s.as_bytes(), unsafe { &mut (*out.as_mut_ptr())[..] }) - .map_err(serde::de::Error::custom)?; - Ok(unsafe { out.assume_init() }) - } -} - #[test] fn correct_byte_convert() { fn convert(b: usize) -> String { diff --git a/src/api2/tape/drive.rs b/src/api2/tape/drive.rs index f3bd8c63..1f42a4a6 100644 --- a/src/api2/tape/drive.rs +++ b/src/api2/tape/drive.rs @@ -21,6 +21,7 @@ use pbs_api_types::{ }; use pbs_api_types::{PRIV_TAPE_AUDIT, PRIV_TAPE_READ, PRIV_TAPE_WRITE}; + use pbs_config::CachedUserInfo; use pbs_tape::{ BlockReadError, @@ -695,7 +696,7 @@ pub async fn read_label( flat.encryption_key_fingerprint = set .encryption_key_fingerprint .as_ref() - .map(|fp| pbs_tools::format::as_fingerprint(fp.bytes())); + .map(|fp| fp.to_string()); let encrypt_fingerprint = set.encryption_key_fingerprint.clone() .map(|fp| (fp, set.uuid.clone())); diff --git a/src/tape/drive/lto/mod.rs b/src/tape/drive/lto/mod.rs index 8b87ca4f..1ba706ef 100644 --- a/src/tape/drive/lto/mod.rs +++ b/src/tape/drive/lto/mod.rs @@ -317,7 +317,7 @@ impl TapeDriver for LtoTapeHandle { } let output = if let Some((fingerprint, uuid)) = key_fingerprint { - let fingerprint = pbs_tools::format::as_fingerprint(fingerprint.bytes()); + let fingerprint = fingerprint.to_string(); run_sg_tape_cmd("encryption", &[ "--fingerprint", &fingerprint, "--uuid", &uuid.to_string(),