1use zeroize::{Zeroize, ZeroizeOnDrop};
2
3use crate::{crypto, file};
4
5#[derive(Zeroize, ZeroizeOnDrop)]
7pub struct Key {
8 key: Vec<u8>,
9 #[zeroize(skip)]
10 strength: Result<(), file::WeakKeyError>,
11}
12
13impl std::fmt::Debug for Key {
14 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
15 write!(
16 f,
17 "Key {{ key: [REDACTED], strength: {:?} }}",
18 self.strength
19 )
20 }
21}
22
23impl AsRef<[u8]> for Key {
24 fn as_ref(&self) -> &[u8] {
25 self.key.as_slice()
26 }
27}
28
29impl AsMut<[u8]> for Key {
30 fn as_mut(&mut self) -> &mut [u8] {
31 &mut self.key
32 }
33}
34
35impl Key {
36 pub const fn new(key: Vec<u8>) -> Self {
37 Self::new_with_strength(key, Err(file::WeakKeyError::StrengthUnknown))
38 }
39
40 pub(crate) const fn check_strength(&self) -> Result<(), file::WeakKeyError> {
41 self.strength
42 }
43
44 pub(crate) const fn new_with_strength(
45 key: Vec<u8>,
46 strength: Result<(), file::WeakKeyError>,
47 ) -> Self {
48 Self { key, strength }
49 }
50
51 pub fn generate_private_key() -> Result<Self, crypto::Error> {
52 Ok(Self::new(crypto::generate_private_key()?.to_vec()))
53 }
54
55 pub fn generate_public_key(private_key: &Self) -> Result<Self, crypto::Error> {
56 Ok(Self::new(crypto::generate_public_key(private_key)?))
57 }
58
59 pub fn generate_aes_key(
60 private_key: &Self,
61 server_public_key: &Self,
62 ) -> Result<Self, crypto::Error> {
63 Ok(Self::new(
64 crypto::generate_aes_key(private_key, server_public_key)?.to_vec(),
65 ))
66 }
67}
68
69impl From<Key> for zvariant::Value<'static> {
70 fn from(key: Key) -> Self {
71 let mut key = key;
72 let inner: Vec<u8> = std::mem::take(&mut key.key);
73 zvariant::Array::from(inner).into()
74 }
75}
76
77impl From<Key> for zvariant::OwnedValue {
78 fn from(key: Key) -> Self {
79 zvariant::Value::from(key).try_into_owned().unwrap()
80 }
81}
82
83impl TryFrom<zvariant::Value<'_>> for Key {
84 type Error = zvariant::Error;
85
86 fn try_from(value: zvariant::Value<'_>) -> Result<Self, Self::Error> {
87 Ok(Key::new(value.try_into()?))
88 }
89}
90
91impl TryFrom<zvariant::OwnedValue> for Key {
92 type Error = zvariant::Error;
93
94 fn try_from(value: zvariant::OwnedValue) -> Result<Self, Self::Error> {
95 Self::try_from(zvariant::Value::from(value))
96 }
97}
98
99#[cfg(test)]
100mod tests {
101 use super::*;
102
103 #[test]
104 fn private_public_pair() {
105 let private_key = Key::new(vec![
106 41, 20, 63, 236, 246, 132, 109, 70, 172, 121, 45, 66, 129, 21, 247, 91, 96, 217, 56,
107 201, 205, 56, 17, 178, 202, 81, 71, 104, 233, 89, 87, 32, 88, 146, 107, 224, 56, 103,
108 111, 74, 143, 80, 170, 40, 5, 52, 48, 90, 75, 71, 193, 224, 222, 57, 91, 81, 66, 1, 6,
109 88, 137, 66, 102, 207, 55, 95, 67, 92, 140, 227, 242, 153, 185, 195, 89, 236, 146, 242,
110 88, 215, 1, 7, 135, 254, 85, 165, 236, 110, 22, 79, 107, 254, 149, 164, 243, 94, 129,
111 198, 45, 208, 132, 166, 0, 153, 243, 160, 255, 188, 59, 216, 99, 221, 85, 162, 116,
112 210, 160, 117, 201, 39, 179, 123, 107, 8, 242, 139, 207, 250,
113 ]);
114 let server_public_key = Key::new(vec![
115 50, 233, 76, 88, 47, 206, 235, 107, 9, 232, 98, 14, 188, 214, 209, 77, 35, 66, 109,
116 119, 24, 191, 120, 90, 242, 198, 240, 115, 200, 66, 51, 180, 8, 164, 89, 9, 229, 31,
117 160, 31, 156, 101, 169, 60, 63, 247, 37, 255, 75, 198, 62, 235, 50, 29, 221, 245, 29,
118 248, 140, 209, 62, 215, 2, 137, 82, 77, 248, 242, 56, 176, 118, 183, 124, 74, 26, 133,
119 188, 47, 31, 141, 232, 194, 92, 18, 69, 3, 56, 153, 42, 9, 143, 81, 197, 159, 200, 197,
120 221, 74, 186, 157, 158, 36, 74, 125, 11, 234, 33, 2, 5, 36, 206, 248, 155, 157, 145,
121 159, 238, 19, 185, 194, 134, 3, 195, 198, 60, 100, 159, 31,
122 ]);
123
124 let expected_public_key = &[
125 9, 192, 210, 81, 212, 191, 74, 119, 22, 172, 81, 142, 124, 89, 17, 71, 118, 190, 81,
126 71, 49, 149, 200, 204, 14, 47, 111, 165, 119, 103, 216, 102, 111, 93, 242, 64, 73, 224,
127 165, 11, 127, 219, 197, 188, 168, 222, 254, 10, 104, 81, 8, 206, 237, 119, 225, 100,
128 78, 196, 89, 163, 63, 169, 77, 236, 80, 241, 189, 49, 27, 40, 243, 229, 66, 53, 80, 86,
129 44, 213, 87, 186, 68, 55, 216, 56, 236, 51, 229, 44, 174, 18, 87, 141, 85, 71, 185,
130 203, 208, 144, 190, 117, 141, 255, 153, 106, 123, 28, 152, 200, 237, 189, 176, 20, 80,
131 211, 33, 158, 232, 194, 145, 45, 194, 35, 108, 106, 214, 221, 159, 137,
132 ];
133 let expected_aes_key = &[
134 132, 3, 113, 222, 81, 209, 49, 43, 81, 232, 243, 46, 1, 103, 184, 42,
135 ];
136
137 let public_key = Key::generate_public_key(&private_key);
138 let aes_key = Key::generate_aes_key(&private_key, &server_public_key);
139
140 assert_eq!(public_key.unwrap().as_ref(), expected_public_key);
141 assert_eq!(aes_key.unwrap().as_ref(), expected_aes_key);
142 }
143
144 #[test]
145 fn key_debug_is_redacted() {
146 let key = Key::new(vec![1, 2, 3, 4]);
147 let debug_output = format!("{:?}", key);
148
149 assert!(debug_output.contains("key: [REDACTED]"));
150 assert!(debug_output.contains("strength:"));
151 }
152}