Skip to main content

wasi_crypto_preview/asymmetric_common/
keypair.rs

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