1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
use crate::software::legacy::{Secret, SecretAttributes};
use crate::{
    ECDSASHA256CurveP256SecretKey, EdDSACurve25519SecretKey, SigningSecret, VaultError,
    X25519SecretKey,
};
use ockam_core::{Error, Result};
use serde::{Deserialize, Serialize};

/// Stored secret: binary data + secret metadata
#[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize)]
pub struct StoredSecret {
    secret: Secret,
    attributes: SecretAttributes,
}

impl StoredSecret {
    /// Create a new stored secret
    pub(crate) fn new(secret: Secret, attributes: SecretAttributes) -> Self {
        StoredSecret { secret, attributes }
    }

    /// Create a new stored secret and check the secret length
    pub fn create(secret: Secret, attributes: SecretAttributes) -> Result<Self> {
        Self::check(&secret, &attributes)?;
        Ok(StoredSecret::new(secret, attributes))
    }

    /// Secret's Attributes
    pub fn attributes(&self) -> SecretAttributes {
        self.attributes
    }

    /// Get the secret part of this stored secret
    pub fn secret(&self) -> &Secret {
        &self.secret
    }

    /// Get the secret part of this stored secret
    pub fn take_secret(self) -> Secret {
        self.secret
    }

    /// Check if the length of the secret is the same as the length prescribed by the attributes
    fn check(secret: &Secret, attributes: &SecretAttributes) -> Result<()> {
        // the secret must be equal to length mentioned in the attributes
        if secret.length() != attributes.length() as usize {
            Err(VaultError::InvalidSecretLength)?
        } else {
            Ok(())
        }
    }
}

impl From<SigningSecret> for StoredSecret {
    fn from(value: SigningSecret) -> Self {
        let (secret, attributes) = match value {
            SigningSecret::EdDSACurve25519(value) => {
                (value.key().to_vec(), SecretAttributes::Ed25519)
            }
            SigningSecret::ECDSASHA256CurveP256(value) => {
                (value.key().to_vec(), SecretAttributes::NistP256)
            }
        };

        let secret = Secret::new(secret);

        Self::new(secret, attributes)
    }
}

impl TryFrom<StoredSecret> for SigningSecret {
    type Error = Error;

    fn try_from(value: StoredSecret) -> Result<Self, Self::Error> {
        match &value.attributes {
            SecretAttributes::Ed25519 => {
                let secret = value.secret;

                let secret = secret
                    .as_ref()
                    .try_into()
                    .map_err(|_| VaultError::InvalidSecretLength)?;
                let secret = EdDSACurve25519SecretKey::new(secret);

                Ok(Self::EdDSACurve25519(secret))
            }
            SecretAttributes::NistP256 => {
                let secret = value.secret;

                let secret = secret
                    .as_ref()
                    .try_into()
                    .map_err(|_| VaultError::InvalidSecretLength)?;
                let secret = ECDSASHA256CurveP256SecretKey::new(secret);

                Ok(Self::ECDSASHA256CurveP256(secret))
            }

            SecretAttributes::X25519
            | SecretAttributes::Buffer(_)
            | SecretAttributes::Aes128
            | SecretAttributes::Aes256 => Err(VaultError::InvalidKeyType)?,
        }
    }
}

impl From<X25519SecretKey> for StoredSecret {
    fn from(value: X25519SecretKey) -> Self {
        let secret = Secret::new(value.key().to_vec());

        Self::new(secret, SecretAttributes::X25519)
    }
}

impl TryFrom<StoredSecret> for X25519SecretKey {
    type Error = Error;

    fn try_from(value: StoredSecret) -> Result<Self, Self::Error> {
        match &value.attributes {
            SecretAttributes::X25519 => {
                let secret = value.secret;

                let secret = secret
                    .as_ref()
                    .try_into()
                    .map_err(|_| VaultError::InvalidSecretLength)?;

                Ok(Self::new(secret))
            }

            SecretAttributes::Ed25519
            | SecretAttributes::NistP256
            | SecretAttributes::Buffer(_)
            | SecretAttributes::Aes128
            | SecretAttributes::Aes256 => Err(VaultError::InvalidKeyType)?,
        }
    }
}