wasi_crypto/asymmetric_common/
keypair.rs

1use std::convert::TryFrom;
2
3use super::*;
4use crate::options::Options;
5use crate::AlgorithmType;
6
7#[derive(Clone, Copy, Debug, Eq, PartialEq)]
8pub enum KeyPairEncoding {
9    Raw,
10    Pkcs8,
11    Pem,
12    Local,
13}
14
15#[derive(Clone)]
16pub enum KeyPair {
17    Signature(SignatureKeyPair),
18    KeyExchange(KxKeyPair),
19}
20
21impl KeyPair {
22    pub(crate) fn into_signature_keypair(self) -> Result<SignatureKeyPair, CryptoError> {
23        match self {
24            KeyPair::Signature(kp) => Ok(kp),
25            _ => bail!(CryptoError::InvalidHandle),
26        }
27    }
28
29    pub(crate) fn into_kx_keypair(self) -> Result<KxKeyPair, CryptoError> {
30        match self {
31            KeyPair::KeyExchange(kp) => Ok(kp),
32            _ => bail!(CryptoError::InvalidHandle),
33        }
34    }
35
36    pub fn export(&self, encoding: KeyPairEncoding) -> Result<Vec<u8>, CryptoError> {
37        match self {
38            KeyPair::Signature(key_pair) => key_pair.export(encoding),
39            KeyPair::KeyExchange(key_pair) => key_pair.export(encoding),
40        }
41    }
42
43    pub fn generate(
44        alg_type: AlgorithmType,
45        alg_str: &str,
46        options: Option<Options>,
47    ) -> Result<KeyPair, CryptoError> {
48        match alg_type {
49            AlgorithmType::Signatures => {
50                let options = match options {
51                    None => None,
52                    Some(options) => Some(options.into_signatures()?),
53                };
54                Ok(KeyPair::Signature(SignatureKeyPair::generate(
55                    SignatureAlgorithm::try_from(alg_str)?,
56                    options,
57                )?))
58            }
59            AlgorithmType::KeyExchange => {
60                let options = match options {
61                    None => None,
62                    Some(options) => Some(options.into_key_exchange()?),
63                };
64                Ok(KeyPair::KeyExchange(KxKeyPair::generate(
65                    KxAlgorithm::try_from(alg_str)?,
66                    options,
67                )?))
68            }
69            _ => bail!(CryptoError::InvalidOperation),
70        }
71    }
72
73    pub fn import(
74        alg_type: AlgorithmType,
75        alg_str: &str,
76        encoded: &[u8],
77        encoding: KeyPairEncoding,
78    ) -> Result<KeyPair, CryptoError> {
79        match alg_type {
80            AlgorithmType::Signatures => Ok(KeyPair::Signature(SignatureKeyPair::import(
81                SignatureAlgorithm::try_from(alg_str)?,
82                encoded,
83                encoding,
84            )?)),
85            _ => bail!(CryptoError::InvalidOperation),
86        }
87    }
88
89    pub fn from_pk_and_sk(_pk: PublicKey, _sk: SecretKey) -> Result<KeyPair, CryptoError> {
90        match (_pk, _sk) {
91            (PublicKey::Signature(pk), SecretKey::Signature(sk)) => {
92                ensure!(pk.alg() == sk.alg(), CryptoError::IncompatibleKeys);
93            }
94            (PublicKey::KeyExchange(pk), SecretKey::KeyExchange(sk)) => {
95                ensure!(pk.alg() == sk.alg(), CryptoError::IncompatibleKeys);
96            }
97            _ => bail!(CryptoError::IncompatibleKeys),
98        }
99        bail!(CryptoError::NotImplemented);
100    }
101
102    pub fn public_key(&self) -> Result<PublicKey, CryptoError> {
103        match self {
104            KeyPair::Signature(key_pair) => Ok(PublicKey::Signature(key_pair.public_key()?)),
105            KeyPair::KeyExchange(key_pair) => Ok(PublicKey::KeyExchange(key_pair.public_key()?)),
106        }
107    }
108
109    pub fn secret_key(&self) -> Result<SecretKey, CryptoError> {
110        match self {
111            KeyPair::Signature(key_pair) => Ok(SecretKey::Signature(key_pair.secret_key()?)),
112            KeyPair::KeyExchange(key_pair) => Ok(SecretKey::KeyExchange(key_pair.secret_key()?)),
113        }
114    }
115}
116
117impl CryptoCtx {
118    pub fn keypair_generate(
119        &self,
120        alg_type: AlgorithmType,
121        alg_str: &str,
122        options_handle: Option<Handle>,
123    ) -> Result<Handle, CryptoError> {
124        let options = match options_handle {
125            None => None,
126            Some(options_handle) => Some(self.handles.options.get(options_handle)?),
127        };
128        let kp = KeyPair::generate(alg_type, alg_str, options)?;
129        let handle = self.handles.keypair.register(kp)?;
130        Ok(handle)
131    }
132
133    pub fn keypair_import(
134        &self,
135        alg_type: AlgorithmType,
136        alg_str: &str,
137        encoded: &[u8],
138        encoding: KeyPairEncoding,
139    ) -> Result<Handle, CryptoError> {
140        let kp = KeyPair::import(alg_type, alg_str, encoded, encoding)?;
141        let handle = self.handles.keypair.register(kp)?;
142        Ok(handle)
143    }
144
145    pub fn keypair_id(&self, kp_handle: Handle) -> Result<(Vec<u8>, Version), CryptoError> {
146        let _kp = self.handles.keypair.get(kp_handle)?;
147        bail!(CryptoError::UnsupportedFeature)
148    }
149
150    pub fn keypair_from_pk_and_sk(
151        &self,
152        pk_handle: Handle,
153        sk_handle: Handle,
154    ) -> Result<Handle, CryptoError> {
155        let pk = self.handles.publickey.get(pk_handle)?;
156        let sk = self.handles.secretkey.get(sk_handle)?;
157        let kp = KeyPair::from_pk_and_sk(pk, sk)?;
158        let handle = self.handles.keypair.register(kp)?;
159        Ok(handle)
160    }
161
162    pub fn keypair_export(
163        &self,
164        kp_handle: Handle,
165        encoding: KeyPairEncoding,
166    ) -> Result<Handle, CryptoError> {
167        let kp = self.handles.keypair.get(kp_handle)?;
168        let encoded = kp.export(encoding)?;
169        let array_output_handle = ArrayOutput::register(&self.handles, encoded)?;
170        Ok(array_output_handle)
171    }
172
173    pub fn keypair_publickey(&self, kp_handle: Handle) -> Result<Handle, CryptoError> {
174        let kp = self.handles.keypair.get(kp_handle)?;
175        let pk = kp.public_key()?;
176        let handle = self.handles.publickey.register(pk)?;
177        Ok(handle)
178    }
179
180    pub fn keypair_secretkey(&self, kp_handle: Handle) -> Result<Handle, CryptoError> {
181        let kp = self.handles.keypair.get(kp_handle)?;
182        let sk = kp.secret_key()?;
183        let handle = self.handles.secretkey.register(sk)?;
184        Ok(handle)
185    }
186
187    pub fn keypair_close(&self, kp_handle: Handle) -> Result<(), CryptoError> {
188        self.handles.keypair.close(kp_handle)
189    }
190}