1use crate::utils::*;
2use botan_sys::*;
3
4use crate::pubkey::{Privkey, Pubkey};
5use crate::rng::RandomNumberGenerator;
6
7#[derive(Debug)]
8pub struct Signer {
20 obj: botan_pk_op_sign_t,
21 sig_len: usize,
22}
23
24unsafe impl Sync for Signer {}
25unsafe impl Send for Signer {}
26
27botan_impl_drop!(Signer, botan_pk_op_sign_destroy);
28
29impl Signer {
30 pub fn new(key: &Privkey, padding: &str) -> Result<Signer> {
32 let padding = make_cstr(padding)?;
33 let obj = botan_init!(
34 botan_pk_op_sign_create,
35 key.handle(),
36 padding.as_ptr(),
37 0u32
38 )?;
39 let sig_len = botan_usize!(botan_pk_op_sign_output_length, obj)?;
40 Ok(Signer { obj, sig_len })
41 }
42
43 pub fn new_with_der_formatted_signatures(key: &Privkey, padding: &str) -> Result<Signer> {
45 let padding = make_cstr(padding)?;
46 let obj = botan_init!(
47 botan_pk_op_sign_create,
48 key.handle(),
49 padding.as_ptr(),
50 1u32
51 )?;
52 let sig_len = botan_usize!(botan_pk_op_sign_output_length, obj)?;
53 Ok(Signer { obj, sig_len })
54 }
55
56 pub fn signature_length(&self) -> usize {
58 self.sig_len
59 }
60
61 pub fn update(&mut self, data: &[u8]) -> Result<()> {
63 botan_call!(botan_pk_op_sign_update, self.obj, data.as_ptr(), data.len())
64 }
65
66 pub fn finish(&mut self, rng: &mut RandomNumberGenerator) -> Result<Vec<u8>> {
68 let rng_handle = rng.handle();
69 call_botan_ffi_returning_vec_u8(self.sig_len, &|out_buf, out_len| unsafe {
70 botan_pk_op_sign_finish(self.obj, rng_handle, out_buf, out_len)
71 })
72 }
73}
74
75#[derive(Debug)]
76pub struct Decryptor {
78 obj: botan_pk_op_decrypt_t,
79}
80
81unsafe impl Sync for Decryptor {}
82unsafe impl Send for Decryptor {}
83
84botan_impl_drop!(Decryptor, botan_pk_op_decrypt_destroy);
85
86impl Decryptor {
87 pub fn new(key: &Privkey, padding: &str) -> Result<Decryptor> {
89 let padding = make_cstr(padding)?;
90 let obj = botan_init!(
91 botan_pk_op_decrypt_create,
92 key.handle(),
93 padding.as_ptr(),
94 0u32
95 )?;
96 Ok(Decryptor { obj })
97 }
98
99 pub fn decrypt(&mut self, ctext: &[u8]) -> Result<Vec<u8>> {
101 let mut ptext_len = 0;
102
103 botan_call!(
104 botan_pk_op_decrypt_output_length,
105 self.obj,
106 ctext.len(),
107 &mut ptext_len
108 )?;
109
110 call_botan_ffi_returning_vec_u8(ptext_len, &|out_buf, out_len| unsafe {
111 botan_pk_op_decrypt(self.obj, out_buf, out_len, ctext.as_ptr(), ctext.len())
112 })
113 }
114}
115
116#[derive(Debug)]
117pub struct Verifier {
119 obj: botan_pk_op_verify_t,
120}
121
122unsafe impl Sync for Verifier {}
123unsafe impl Send for Verifier {}
124
125botan_impl_drop!(Verifier, botan_pk_op_verify_destroy);
126
127impl Verifier {
128 pub fn new(key: &Pubkey, padding: &str) -> Result<Verifier> {
130 let padding = make_cstr(padding)?;
131 let obj = botan_init!(
132 botan_pk_op_verify_create,
133 key.handle(),
134 padding.as_ptr(),
135 0u32
136 )?;
137 Ok(Verifier { obj })
138 }
139
140 pub fn new_with_der_formatted_signatures(key: &Pubkey, padding: &str) -> Result<Verifier> {
142 let padding = make_cstr(padding)?;
143 let obj = botan_init!(
144 botan_pk_op_verify_create,
145 key.handle(),
146 padding.as_ptr(),
147 1u32
148 )?;
149 Ok(Verifier { obj })
150 }
151
152 pub fn update(&mut self, data: &[u8]) -> Result<()> {
154 botan_call!(
155 botan_pk_op_verify_update,
156 self.obj,
157 data.as_ptr(),
158 data.len()
159 )
160 }
161
162 pub fn finish(&mut self, signature: &[u8]) -> Result<bool> {
164 match unsafe { botan_pk_op_verify_finish(self.obj, signature.as_ptr(), signature.len()) } {
165 0 => Ok(true),
166 BOTAN_FFI_INVALID_VERIFIER => Ok(false),
167 e => Err(Error::from_rc(e)),
168 }
169 }
170}
171
172#[derive(Debug)]
173pub struct Encryptor {
185 obj: botan_pk_op_encrypt_t,
186}
187
188unsafe impl Sync for Encryptor {}
189unsafe impl Send for Encryptor {}
190
191botan_impl_drop!(Encryptor, botan_pk_op_encrypt_destroy);
192
193impl Encryptor {
194 pub fn new(key: &Pubkey, padding: &str) -> Result<Encryptor> {
196 let padding = make_cstr(padding)?;
197 let obj = botan_init!(
198 botan_pk_op_encrypt_create,
199 key.handle(),
200 padding.as_ptr(),
201 0u32
202 )?;
203 Ok(Encryptor { obj })
204 }
205
206 pub fn encrypt(&mut self, ptext: &[u8], rng: &mut RandomNumberGenerator) -> Result<Vec<u8>> {
208 let mut ctext_len = 0;
209 botan_call!(
210 botan_pk_op_encrypt_output_length,
211 self.obj,
212 ptext.len(),
213 &mut ctext_len
214 )?;
215
216 let rng_handle = rng.handle();
217
218 call_botan_ffi_returning_vec_u8(ctext_len, &|out_buf, out_len| unsafe {
219 botan_pk_op_encrypt(
220 self.obj,
221 rng_handle,
222 out_buf,
223 out_len,
224 ptext.as_ptr(),
225 ptext.len(),
226 )
227 })
228 }
229}
230
231#[derive(Debug)]
232pub struct KeyAgreement {
234 obj: botan_pk_op_ka_t,
235}
236
237unsafe impl Sync for KeyAgreement {}
238unsafe impl Send for KeyAgreement {}
239
240botan_impl_drop!(KeyAgreement, botan_pk_op_key_agreement_destroy);
241
242impl KeyAgreement {
243 pub fn new(key: &Privkey, kdf: &str) -> Result<KeyAgreement> {
245 let kdf = make_cstr(kdf)?;
246 let obj = botan_init!(
247 botan_pk_op_key_agreement_create,
248 key.handle(),
249 kdf.as_ptr(),
250 0u32
251 )?;
252 Ok(KeyAgreement { obj })
253 }
254
255 pub fn agree(
257 &mut self,
258 requested_output: usize,
259 counterparty_key: &[u8],
260 salt: &[u8],
261 ) -> Result<Vec<u8>> {
262 let mut ka_len = requested_output;
263
264 if ka_len == 0 {
265 ka_len = botan_usize!(botan_pk_op_key_agreement_size, self.obj)?;
266 }
267
268 call_botan_ffi_returning_vec_u8(ka_len, &|out_buf, out_len| unsafe {
269 botan_pk_op_key_agreement(
270 self.obj,
271 out_buf,
272 out_len,
273 counterparty_key.as_ptr(),
274 counterparty_key.len(),
275 salt.as_ptr(),
276 salt.len(),
277 )
278 })
279 }
280}