wasi_crypto/key_exchange/
secretkey.rs1use std::sync::{Arc, Mutex, MutexGuard};
2
3use super::*;
4use crate::asymmetric_common::*;
5use crate::CryptoCtx;
6
7pub trait KxSecretKeyBuilder {
8 fn from_raw(&self, raw: &[u8]) -> Result<KxSecretKey, CryptoError>;
9}
10
11#[derive(Clone)]
12pub struct KxSecretKey {
13 inner: Arc<Mutex<Box<dyn KxSecretKeyLike>>>,
14}
15
16impl KxSecretKey {
17 pub fn new(kx_secretkey_like: Box<dyn KxSecretKeyLike>) -> Self {
18 KxSecretKey {
19 inner: Arc::new(Mutex::new(kx_secretkey_like)),
20 }
21 }
22
23 pub fn inner(&self) -> MutexGuard<'_, Box<dyn KxSecretKeyLike>> {
24 self.inner.lock().unwrap()
25 }
26
27 pub fn locked<T, U>(&self, mut f: T) -> U
28 where
29 T: FnMut(MutexGuard<'_, Box<dyn KxSecretKeyLike>>) -> U,
30 {
31 f(self.inner())
32 }
33
34 pub fn alg(&self) -> KxAlgorithm {
35 self.inner().alg()
36 }
37
38 pub(crate) fn as_raw(&self) -> Result<Vec<u8>, CryptoError> {
39 Ok(self.inner().as_raw()?.to_vec())
40 }
41
42 pub(crate) fn export(&self, encoding: SecretKeyEncoding) -> Result<Vec<u8>, CryptoError> {
43 match encoding {
44 SecretKeyEncoding::Raw => Ok(self.inner().as_raw()?.to_vec()),
45 _ => bail!(CryptoError::UnsupportedEncoding),
46 }
47 }
48
49 pub(crate) fn publickey(&self) -> Result<KxPublicKey, CryptoError> {
50 self.inner().publickey()
51 }
52
53 pub fn dh(&self, pk: &KxPublicKey) -> Result<Vec<u8>, CryptoError> {
54 ensure!(pk.alg() == self.alg(), CryptoError::IncompatibleKeys);
55 self.inner().dh(pk)
56 }
57
58 fn decapsulate(&self, encapsulated_secret: &[u8]) -> Result<Vec<u8>, CryptoError> {
59 self.inner().decapsulate(encapsulated_secret)
60 }
61}
62
63pub trait KxSecretKeyLike: Sync + Send {
64 fn as_any(&self) -> &dyn Any;
65 fn alg(&self) -> KxAlgorithm;
66 fn len(&self) -> Result<usize, CryptoError>;
67 fn as_raw(&self) -> Result<&[u8], CryptoError>;
68 fn publickey(&self) -> Result<KxPublicKey, CryptoError>;
69
70 fn dh(&self, _pk: &KxPublicKey) -> Result<Vec<u8>, CryptoError> {
71 bail!(CryptoError::InvalidOperation);
72 }
73
74 fn decapsulate(&self, _encapsulated_secret: &[u8]) -> Result<Vec<u8>, CryptoError> {
75 bail!(CryptoError::InvalidOperation);
76 }
77}
78
79impl CryptoCtx {
80 pub fn kx_dh(&self, pk_handle: Handle, sk_handle: Handle) -> Result<Handle, CryptoError> {
81 let pk = self
82 .handles
83 .publickey
84 .get(pk_handle)?
85 .into_kx_public_key()?;
86 let sk = self
87 .handles
88 .secretkey
89 .get(sk_handle)?
90 .into_kx_secret_key()?;
91 let shared_secret = sk.dh(&pk)?;
92 ArrayOutput::register(&self.handles, shared_secret)
93 }
94
95 pub fn kx_decapsulate(
96 &self,
97 sk_handle: Handle,
98 encapsulated_secret: &[u8],
99 ) -> Result<Handle, CryptoError> {
100 let sk = self
101 .handles
102 .secretkey
103 .get(sk_handle)?
104 .into_kx_secret_key()?;
105 let shared_secret = sk.decapsulate(encapsulated_secret)?;
106 ArrayOutput::register(&self.handles, shared_secret)
107 }
108}