use crate::crypto::digest::Digest;
use crate::crypto::key::{AbstractKey, Nonce};
use crate::error::*;
use serde::{Deserialize, Serialize};
use tracing::debug;
#[derive(Deserialize, Serialize)]
pub struct WrappedKey {
data: Vec<u8>,
nonce: Option<Nonce>,
wrapping_digest: Digest,
}
impl WrappedKey {
pub fn wrap<KA: AbstractKey, KB: AbstractKey>(to_wrap: &KA, wrap_with: &KB) -> Result<Self> {
let data = match to_wrap.serialize() {
Err(e) => return Err(Error::Crypto(format!("serializing key failed: {}", e))),
Ok(d) => d,
};
let (nonce, data) = match wrap_with.encrypt(&data, None) {
Err(e) => return Err(Error::Crypto(format!("wrapping key failed: {}", e))),
Ok(nd) => nd,
};
Ok(WrappedKey {
data: data,
nonce: nonce,
wrapping_digest: wrap_with.get_digest(),
})
}
pub fn unwrap<KA: AbstractKey, KB: AbstractKey>(&self, wrapped_with: &KB) -> Result<KA> {
debug!(
"trying to unwrap key {:?} with wrapping key {:?}, expected wrapping digest {:?}",
self.get_digest(),
wrapped_with.get_digest(),
self.wrapping_digest
);
if wrapped_with.get_digest() != self.wrapping_digest {
return Err(Error::InvalidArgument(format!(
"the specified key is not the correct wrapping key"
)));
}
let data = match wrapped_with.decrypt(self.nonce.as_ref(), self.data.as_slice()) {
Err(e) => return Err(Error::Crypto(format!("unwrapping key failed: {}", e))),
Ok(d) => d,
};
match KA::deserialize(data) {
Err(e) => return Err(Error::Crypto(format!("deserializing key failed: {}", e))),
Ok(k) => Ok(k),
}
}
pub fn get_digest(&self) -> Digest {
Digest::from_bytes(self.data.as_slice())
}
pub fn get_wrapping_digest(&self) -> &Digest {
&self.wrapping_digest
}
}