ockam_vault/software/legacy/
secret_attributes.rs

1use crate::{
2    VaultError, ECDSA_SHA256_CURVEP256_PUBLIC_KEY_LENGTH, EDDSA_CURVE25519_SECRET_KEY_LENGTH,
3    X25519_SECRET_KEY_LENGTH,
4};
5use core::fmt;
6use core::fmt::{Display, Formatter};
7use minicbor::{CborLen, Decode, Encode};
8use serde::{Deserialize, Serialize};
9use zeroize::Zeroize;
10
11/// Attributes for secrets
12///   - a type indicating how the secret is generated: Aes, Ed25519
13///   - an expected length corresponding to the type
14#[derive(Serialize, Deserialize, Copy, Clone, Debug, Eq, PartialEq)]
15#[rustfmt::skip]
16pub enum SecretAttributes {
17    /// Buffer secret type with user defined length
18    Buffer(u32),
19    /// Aes secret with length 16
20    Aes128,
21    /// Aes secret with length 32
22    Aes256,
23    /// Ed225519 secret with length 32
24    Ed25519,
25    /// X225519 secret with length 32
26    X25519,
27    /// NistP256 secret with length 32
28    NistP256,
29}
30
31impl From<SecretAttributes> for SecretType {
32    fn from(value: SecretAttributes) -> Self {
33        match value {
34            SecretAttributes::Buffer(_) => SecretType::Buffer,
35            SecretAttributes::Aes128 => SecretType::Aes,
36            SecretAttributes::Aes256 => SecretType::Aes,
37            SecretAttributes::Ed25519 => SecretType::Ed25519,
38            SecretAttributes::X25519 => SecretType::X25519,
39            SecretAttributes::NistP256 => SecretType::NistP256,
40        }
41    }
42}
43
44impl TryFrom<SecretType> for SecretAttributes {
45    type Error = ockam_core::Error;
46
47    fn try_from(value: SecretType) -> Result<Self, Self::Error> {
48        match value {
49            SecretType::Buffer | SecretType::Aes => Err(VaultError::InvalidKeyType)?,
50            SecretType::X25519 => Ok(SecretAttributes::X25519),
51            SecretType::Ed25519 => Ok(SecretAttributes::Ed25519),
52            SecretType::NistP256 => Ok(SecretAttributes::NistP256),
53        }
54    }
55}
56
57impl SecretAttributes {
58    /// Return the type of a secret
59    pub fn secret_type(&self) -> SecretType {
60        (*self).into()
61    }
62
63    /// Return the length of a secret
64    pub fn length(&self) -> u32 {
65        match self {
66            SecretAttributes::Buffer(s) => *s,
67            SecretAttributes::Aes128 => 16u32,
68            SecretAttributes::Aes256 => 32u32,
69            SecretAttributes::Ed25519 => EDDSA_CURVE25519_SECRET_KEY_LENGTH as u32,
70            SecretAttributes::X25519 => X25519_SECRET_KEY_LENGTH as u32,
71            SecretAttributes::NistP256 => ECDSA_SHA256_CURVEP256_PUBLIC_KEY_LENGTH as u32,
72        }
73    }
74}
75
76/// All possible [`SecretType`]s
77#[derive(Serialize, Deserialize, Copy, Clone, Debug, Encode, Decode, CborLen, Eq, PartialEq, Zeroize, PartialOrd, Ord)]
78#[rustfmt::skip]
79#[cbor(index_only)]
80pub enum SecretType {
81    /// Secret buffer
82    #[n(1)] Buffer,
83    /// AES key
84    #[n(2)] Aes,
85    /// Curve 22519 key
86    #[n(3)] X25519,
87    /// Ed 22519 key
88    #[n(4)] Ed25519,
89    /// NIST P-256 key
90    #[n(5)] NistP256
91}
92
93impl Display for SecretType {
94    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
95        match self {
96            SecretType::Buffer => write!(f, "Buffer"),
97            SecretType::Aes => write!(f, "Aes"),
98            SecretType::X25519 => write!(f, "X25519"),
99            SecretType::Ed25519 => write!(f, "Ed25519"),
100            SecretType::NistP256 => write!(f, "NistP256"),
101        }
102    }
103}
104
105impl Display for SecretAttributes {
106    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
107        write!(f, "{:?} len:{}", self.secret_type(), self.length())
108    }
109}
110
111#[cfg(test)]
112mod tests {
113    use super::*;
114
115    #[test]
116    fn test_serialize_deserialize_json() {
117        for (attributes, expected_json) in [
118            (SecretAttributes::Ed25519, r#""Ed25519""#),
119            (SecretAttributes::X25519, r#""X25519""#),
120            (SecretAttributes::Buffer(32), r#"{"Buffer":32}"#),
121            (SecretAttributes::Aes128, r#""Aes128""#),
122            (SecretAttributes::Aes256, r#""Aes256""#),
123            (SecretAttributes::NistP256, r#""NistP256""#),
124        ] {
125            let actual_json = serde_json::to_string(&attributes).unwrap();
126            assert_eq!(actual_json, expected_json);
127
128            let actual_attributes: SecretAttributes = serde_json::from_str(expected_json).unwrap();
129            assert_eq!(actual_attributes, attributes);
130        }
131    }
132
133    #[test]
134    fn test_serialize_deserialize_bare() {
135        for (attributes, expected_bare) in [
136            (SecretAttributes::Buffer(32), r#"0020000000"#),
137            (SecretAttributes::Aes128, r#"01"#),
138            (SecretAttributes::Aes256, r#"02"#),
139            (SecretAttributes::Ed25519, r#"03"#),
140            (SecretAttributes::X25519, r#"04"#),
141            (SecretAttributes::NistP256, r#"05"#),
142        ] {
143            let actual_bare = hex::encode(serde_bare::to_vec(&attributes).unwrap());
144            assert_eq!(actual_bare, expected_bare);
145
146            let actual_attributes: SecretAttributes =
147                serde_bare::from_slice(&hex::decode(expected_bare).unwrap()).unwrap();
148            assert_eq!(actual_attributes, attributes);
149        }
150    }
151}