ockam_vault/software/legacy/
secret.rs

1use core::fmt;
2use minicbor::{CborLen, Decode, Encode};
3use ockam_core::compat::string::String;
4use ockam_core::compat::vec::Vec;
5use ockam_core::hex_encoding;
6use p256::elliptic_curve::subtle;
7use serde::{Deserialize, Deserializer, Serialize};
8use zeroize::{Zeroize, ZeroizeOnDrop};
9
10/// KeyId.
11pub type KeyId = String;
12
13/// Binary representation of a Secret.
14#[derive(Serialize, Clone, Zeroize, ZeroizeOnDrop, Encode, Decode, CborLen)]
15#[cbor(transparent)]
16pub struct Secret(
17    #[serde(with = "hex_encoding")]
18    #[n(0)]
19    Vec<u8>,
20);
21
22impl<'de> Deserialize<'de> for Secret {
23    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
24    where
25        D: Deserializer<'de>,
26    {
27        #[derive(Deserialize)]
28        struct SecretV2(#[serde(with = "hex_encoding")] Vec<u8>);
29
30        #[derive(Deserialize)]
31        #[serde(untagged)]
32        enum Secrets {
33            V2(SecretV2),
34        }
35        match Secrets::deserialize(deserializer) {
36            Ok(Secrets::V2(SecretV2(secret))) => Ok(Secret(secret)),
37            Err(e) => Err(e),
38        }
39    }
40}
41
42impl Secret {
43    /// Create a new secret key.
44    pub fn new(data: Vec<u8>) -> Self {
45        Self(data)
46    }
47
48    /// Return the secret length
49    pub fn length(&self) -> usize {
50        self.0.len()
51    }
52}
53
54impl fmt::Debug for Secret {
55    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
56        f.pad("<secret key omitted>")
57    }
58}
59
60impl Eq for Secret {}
61
62impl PartialEq for Secret {
63    fn eq(&self, o: &Self) -> bool {
64        subtle::ConstantTimeEq::ct_eq(&self.0[..], &o.0[..]).into()
65    }
66}
67
68impl AsRef<[u8]> for Secret {
69    fn as_ref(&self) -> &[u8] {
70        &self.0
71    }
72}
73
74#[cfg(test)]
75mod tests {
76    use super::*;
77    use serde_json::de;
78
79    #[test]
80    fn test_serialize_secret() {
81        let secret = Secret(vec![1, 2, 3]);
82        let actual: String = serde_json::to_string(&secret).unwrap();
83        assert_eq!(actual, "\"010203\"".to_string());
84    }
85
86    #[test]
87    fn test_deserialize_secret() {
88        let actual: Secret = de::from_str("\"010203\"").unwrap();
89        assert_eq!(actual, Secret(vec![1, 2, 3]));
90    }
91}