wasi_crypto_preview/asymmetric_common/
keypair.rs1use 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}