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}