Skip to main content

wasi_crypto/
options.rs

1use std::any::Any;
2
3use crate::error::*;
4use crate::handles::*;
5use crate::key_exchange::KxOptions;
6use crate::signatures::SignatureOptions;
7use crate::symmetric::SymmetricOptions;
8use crate::{AlgorithmType, CryptoCtx};
9
10pub trait OptionsLike: Send + Sized {
11    fn as_any(&self) -> &dyn Any;
12
13    fn set(&mut self, _name: &str, _value: &[u8]) -> Result<(), CryptoError> {
14        bail!(CryptoError::UnsupportedOption)
15    }
16
17    fn set_guest_buffer(
18        &mut self,
19        _name: &str,
20        _buffer: &'static mut [u8],
21    ) -> Result<(), CryptoError> {
22        bail!(CryptoError::UnsupportedOption)
23    }
24
25    fn get(&self, _name: &str) -> Result<Vec<u8>, CryptoError> {
26        bail!(CryptoError::UnsupportedOption)
27    }
28
29    fn set_u64(&mut self, _name: &str, _value: u64) -> Result<(), CryptoError> {
30        bail!(CryptoError::UnsupportedOption)
31    }
32
33    fn get_u64(&self, _name: &str) -> Result<u64, CryptoError> {
34        bail!(CryptoError::UnsupportedOption)
35    }
36}
37
38#[derive(Clone, Debug)]
39pub enum Options {
40    Signatures(SignatureOptions),
41    Symmetric(SymmetricOptions),
42    KeyExchange(KxOptions),
43}
44
45impl Options {
46    pub fn into_signatures(self) -> Result<SignatureOptions, CryptoError> {
47        match self {
48            Options::Signatures(options) => Ok(options),
49            _ => bail!(CryptoError::InvalidHandle),
50        }
51    }
52
53    pub fn into_symmetric(self) -> Result<SymmetricOptions, CryptoError> {
54        match self {
55            Options::Symmetric(options) => Ok(options),
56            _ => bail!(CryptoError::InvalidHandle),
57        }
58    }
59
60    pub fn into_key_exchange(self) -> Result<KxOptions, CryptoError> {
61        match self {
62            Options::KeyExchange(options) => Ok(options),
63            _ => bail!(CryptoError::InvalidHandle),
64        }
65    }
66
67    pub fn set(&mut self, name: &str, value: &[u8]) -> Result<(), CryptoError> {
68        match self {
69            Options::Signatures(options) => options.set(name, value),
70            Options::Symmetric(options) => options.set(name, value),
71            Options::KeyExchange(options) => options.set(name, value),
72        }
73    }
74
75    pub fn set_guest_buffer(
76        &mut self,
77        name: &str,
78        buffer: &'static mut [u8],
79    ) -> Result<(), CryptoError> {
80        match self {
81            Options::Signatures(options) => options.set_guest_buffer(name, buffer),
82            Options::Symmetric(options) => options.set_guest_buffer(name, buffer),
83            Options::KeyExchange(options) => options.set_guest_buffer(name, buffer),
84        }
85    }
86
87    pub fn get(&mut self, name: &str) -> Result<Vec<u8>, CryptoError> {
88        match self {
89            Options::Signatures(options) => options.get(name),
90            Options::Symmetric(options) => options.get(name),
91            Options::KeyExchange(options) => options.get(name),
92        }
93    }
94
95    pub fn set_u64(&mut self, name: &str, value: u64) -> Result<(), CryptoError> {
96        match self {
97            Options::Signatures(options) => options.set_u64(name, value),
98            Options::Symmetric(options) => options.set_u64(name, value),
99            Options::KeyExchange(options) => options.set_u64(name, value),
100        }
101    }
102
103    pub fn get_u64(&mut self, name: &str) -> Result<u64, CryptoError> {
104        match self {
105            Options::Signatures(options) => options.get_u64(name),
106            Options::Symmetric(options) => options.get_u64(name),
107            Options::KeyExchange(options) => options.get_u64(name),
108        }
109    }
110}
111
112impl CryptoCtx {
113    pub fn options_open(&self, algorithm_type: AlgorithmType) -> Result<Handle, CryptoError> {
114        let options = match algorithm_type {
115            AlgorithmType::Signatures => Options::Signatures(SignatureOptions::default()),
116            AlgorithmType::Symmetric => Options::Symmetric(SymmetricOptions::default()),
117            AlgorithmType::KeyExchange => Options::KeyExchange(KxOptions::default()),
118        };
119        let handle = self.handles.options.register(options)?;
120        Ok(handle)
121    }
122
123    pub fn options_close(&self, options_handle: Handle) -> Result<(), CryptoError> {
124        self.handles.options.close(options_handle)
125    }
126
127    pub fn options_set(
128        &self,
129        options_handle: Handle,
130        name: &str,
131        value: &[u8],
132    ) -> Result<(), CryptoError> {
133        let mut options = self.handles.options.get(options_handle)?;
134        options.set(name, value)
135    }
136
137    pub fn options_set_guest_buffer(
138        &self,
139        options_handle: Handle,
140        name: &str,
141        buffer: &'static mut [u8],
142    ) -> Result<(), CryptoError> {
143        let mut options = self.handles.options.get(options_handle)?;
144        options.set_guest_buffer(name, buffer)
145    }
146
147    pub fn options_set_u64(
148        &self,
149        options_handle: Handle,
150        name: &str,
151        value: u64,
152    ) -> Result<(), CryptoError> {
153        let mut options = self.handles.options.get(options_handle)?;
154        options.set_u64(name, value)
155    }
156
157    pub fn options_get(
158        &self,
159        options_handle: Handle,
160        name: &str,
161        value: &mut [u8],
162    ) -> Result<usize, CryptoError> {
163        let mut options = self.handles.options.get(options_handle)?;
164        let v = options.get(name)?;
165        let v_len = v.len();
166        ensure!(v_len <= value.len(), CryptoError::Overflow);
167        value[..v_len].copy_from_slice(&v);
168        Ok(v_len)
169    }
170
171    pub fn options_get_u64(&self, options_handle: Handle, name: &str) -> Result<u64, CryptoError> {
172        let mut options = self.handles.options.get(options_handle)?;
173        let v = options.get_u64(name)?;
174        Ok(v)
175    }
176}