use zbus::zvariant::{self, Type};
use zeroize::{Zeroize, ZeroizeOnDrop};
use crate::{crypto, portal};
#[derive(Debug, Zeroize, ZeroizeOnDrop)]
pub struct Key {
key: Vec<u8>,
#[zeroize(skip)]
strength: Result<(), portal::WeakKeyError>,
}
impl AsRef<[u8]> for Key {
fn as_ref(&self) -> &[u8] {
self.key.as_slice()
}
}
impl AsMut<[u8]> for Key {
fn as_mut(&mut self) -> &mut [u8] {
&mut self.key
}
}
impl Key {
pub(crate) fn new(key: Vec<u8>) -> Self {
Self::new_with_strength(key, Err(portal::WeakKeyError::StrengthUnknown))
}
pub(crate) fn check_strength(&self) -> Result<(), portal::WeakKeyError> {
self.strength.clone()
}
pub(crate) fn new_with_strength(
key: Vec<u8>,
strength: Result<(), portal::WeakKeyError>,
) -> Self {
Self { key, strength }
}
pub(crate) fn generate_private_key() -> Self {
Self::new(crypto::generate_private_key().to_vec())
}
pub(crate) fn generate_public_key(private_key: &Self) -> Self {
Self::new(crypto::generate_public_key(private_key))
}
pub(crate) fn generate_aes_key(private_key: &Self, server_public_key: &Self) -> Self {
Self::new(crypto::generate_aes_key(private_key, server_public_key).to_vec())
}
}
impl From<&Key> for zvariant::Value<'_> {
fn from(key: &Key) -> Self {
let mut array = zvariant::Array::new(u8::signature());
for byte in key.as_ref() {
array
.append(zvariant::Value::U8(*byte))
.expect("Element of valid type");
}
array.into()
}
}
impl From<zvariant::OwnedValue> for Key {
fn from(value: zvariant::OwnedValue) -> Self {
let mut key = zeroize::Zeroizing::new(vec![]);
for value in value.downcast_ref::<zvariant::Array>().unwrap().get() {
key.push(*value.downcast_ref::<u8>().unwrap());
}
Key::new(key.to_vec())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn private_public_pair() {
let private_key = Key::new(vec![
41, 20, 63, 236, 246, 132, 109, 70, 172, 121, 45, 66, 129, 21, 247, 91, 96, 217, 56,
201, 205, 56, 17, 178, 202, 81, 71, 104, 233, 89, 87, 32, 88, 146, 107, 224, 56, 103,
111, 74, 143, 80, 170, 40, 5, 52, 48, 90, 75, 71, 193, 224, 222, 57, 91, 81, 66, 1, 6,
88, 137, 66, 102, 207, 55, 95, 67, 92, 140, 227, 242, 153, 185, 195, 89, 236, 146, 242,
88, 215, 1, 7, 135, 254, 85, 165, 236, 110, 22, 79, 107, 254, 149, 164, 243, 94, 129,
198, 45, 208, 132, 166, 0, 153, 243, 160, 255, 188, 59, 216, 99, 221, 85, 162, 116,
210, 160, 117, 201, 39, 179, 123, 107, 8, 242, 139, 207, 250,
]);
let server_public_key = Key::new(vec![
50, 233, 76, 88, 47, 206, 235, 107, 9, 232, 98, 14, 188, 214, 209, 77, 35, 66, 109,
119, 24, 191, 120, 90, 242, 198, 240, 115, 200, 66, 51, 180, 8, 164, 89, 9, 229, 31,
160, 31, 156, 101, 169, 60, 63, 247, 37, 255, 75, 198, 62, 235, 50, 29, 221, 245, 29,
248, 140, 209, 62, 215, 2, 137, 82, 77, 248, 242, 56, 176, 118, 183, 124, 74, 26, 133,
188, 47, 31, 141, 232, 194, 92, 18, 69, 3, 56, 153, 42, 9, 143, 81, 197, 159, 200, 197,
221, 74, 186, 157, 158, 36, 74, 125, 11, 234, 33, 2, 5, 36, 206, 248, 155, 157, 145,
159, 238, 19, 185, 194, 134, 3, 195, 198, 60, 100, 159, 31,
]);
let expected_public_key = &[
9, 192, 210, 81, 212, 191, 74, 119, 22, 172, 81, 142, 124, 89, 17, 71, 118, 190, 81,
71, 49, 149, 200, 204, 14, 47, 111, 165, 119, 103, 216, 102, 111, 93, 242, 64, 73, 224,
165, 11, 127, 219, 197, 188, 168, 222, 254, 10, 104, 81, 8, 206, 237, 119, 225, 100,
78, 196, 89, 163, 63, 169, 77, 236, 80, 241, 189, 49, 27, 40, 243, 229, 66, 53, 80, 86,
44, 213, 87, 186, 68, 55, 216, 56, 236, 51, 229, 44, 174, 18, 87, 141, 85, 71, 185,
203, 208, 144, 190, 117, 141, 255, 153, 106, 123, 28, 152, 200, 237, 189, 176, 20, 80,
211, 33, 158, 232, 194, 145, 45, 194, 35, 108, 106, 214, 221, 159, 137,
];
let expected_aes_key = &[
132, 3, 113, 222, 81, 209, 49, 43, 81, 232, 243, 46, 1, 103, 184, 42,
];
let public_key = Key::generate_public_key(&private_key);
let aes_key = Key::generate_aes_key(&private_key, &server_public_key);
assert_eq!(public_key.as_ref(), expected_public_key);
assert_eq!(aes_key.as_ref(), expected_aes_key);
}
}