Skip to main content

wasi_crypto/key_exchange/
secretkey.rs

1use 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}