Skip to main content

wasi_crypto/key_exchange/
publickey.rs

1use std::sync::{Arc, Mutex, MutexGuard};
2
3use super::*;
4use crate::asymmetric_common::*;
5use crate::CryptoCtx;
6
7pub trait KxPublicKeyBuilder {
8    fn from_raw(&self, raw: &[u8]) -> Result<KxPublicKey, CryptoError>;
9}
10
11#[derive(Clone)]
12pub struct KxPublicKey {
13    inner: Arc<Mutex<Box<dyn KxPublicKeyLike>>>,
14}
15
16impl KxPublicKey {
17    pub fn new(kx_publickey_like: Box<dyn KxPublicKeyLike>) -> Self {
18        KxPublicKey {
19            inner: Arc::new(Mutex::new(kx_publickey_like)),
20        }
21    }
22
23    pub fn inner(&self) -> MutexGuard<'_, Box<dyn KxPublicKeyLike>> {
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 KxPublicKeyLike>>) -> 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: PublicKeyEncoding) -> Result<Vec<u8>, CryptoError> {
43        match encoding {
44            PublicKeyEncoding::Raw => Ok(self.inner().as_raw()?.to_vec()),
45            _ => bail!(CryptoError::UnsupportedEncoding),
46        }
47    }
48
49    pub(crate) fn verify(&self) -> Result<(), CryptoError> {
50        self.inner().verify()
51    }
52
53    pub(crate) fn encapsulate(&self) -> Result<EncapsulatedSecret, CryptoError> {
54        self.inner().encapsulate()
55    }
56}
57
58pub trait KxPublicKeyLike: Sync + Send {
59    fn as_any(&self) -> &dyn Any;
60    fn alg(&self) -> KxAlgorithm;
61    fn len(&self) -> Result<usize, CryptoError>;
62    fn as_raw(&self) -> Result<&[u8], CryptoError>;
63
64    fn verify(&self) -> Result<(), CryptoError> {
65        Ok(())
66    }
67
68    fn encapsulate(&self) -> Result<EncapsulatedSecret, CryptoError> {
69        bail!(CryptoError::InvalidOperation);
70    }
71}
72
73impl CryptoCtx {
74    pub fn kx_encapsulate(&self, pk_handle: Handle) -> Result<(Handle, Handle), CryptoError> {
75        let pk = self
76            .handles
77            .publickey
78            .get(pk_handle)?
79            .into_kx_public_key()?;
80        let encapsulated_secret = pk.encapsulate()?;
81        let secret_handle = ArrayOutput::register(&self.handles, encapsulated_secret.secret)?;
82        let encapsulated_secret_handle =
83            ArrayOutput::register(&self.handles, encapsulated_secret.encapsulated_secret)?;
84        Ok((secret_handle, encapsulated_secret_handle))
85    }
86}