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 update(&mut self, data: &[u8]) -> Result<()> {
58 botan_call!(botan_pk_op_sign_update, self.obj, data.as_ptr(), data.len())
59 }
60
61 pub fn finish(&mut self, rng: &mut RandomNumberGenerator) -> Result<Vec<u8>> {
63 let rng_handle = rng.handle();
64 call_botan_ffi_returning_vec_u8(self.sig_len, &|out_buf, out_len| unsafe {
65 botan_pk_op_sign_finish(self.obj, rng_handle, out_buf, out_len)
66 })
67 }
68}
69
70#[derive(Debug)]
71pub struct Decryptor {
73 obj: botan_pk_op_decrypt_t,
74}
75
76unsafe impl Sync for Decryptor {}
77unsafe impl Send for Decryptor {}
78
79botan_impl_drop!(Decryptor, botan_pk_op_decrypt_destroy);
80
81impl Decryptor {
82 pub fn new(key: &Privkey, padding: &str) -> Result<Decryptor> {
84 let padding = make_cstr(padding)?;
85 let obj = botan_init!(
86 botan_pk_op_decrypt_create,
87 key.handle(),
88 padding.as_ptr(),
89 0u32
90 )?;
91 Ok(Decryptor { obj })
92 }
93
94 pub fn decrypt(&mut self, ctext: &[u8]) -> Result<Vec<u8>> {
96 let mut ptext_len = 0;
97
98 botan_call!(
99 botan_pk_op_decrypt_output_length,
100 self.obj,
101 ctext.len(),
102 &mut ptext_len
103 )?;
104
105 call_botan_ffi_returning_vec_u8(ptext_len, &|out_buf, out_len| unsafe {
106 botan_pk_op_decrypt(self.obj, out_buf, out_len, ctext.as_ptr(), ctext.len())
107 })
108 }
109}
110
111#[derive(Debug)]
112pub struct Verifier {
114 obj: botan_pk_op_verify_t,
115}
116
117unsafe impl Sync for Verifier {}
118unsafe impl Send for Verifier {}
119
120botan_impl_drop!(Verifier, botan_pk_op_verify_destroy);
121
122impl Verifier {
123 pub fn new(key: &Pubkey, padding: &str) -> Result<Verifier> {
125 let padding = make_cstr(padding)?;
126 let obj = botan_init!(
127 botan_pk_op_verify_create,
128 key.handle(),
129 padding.as_ptr(),
130 0u32
131 )?;
132 Ok(Verifier { obj })
133 }
134
135 pub fn new_with_der_formatted_signatures(key: &Pubkey, padding: &str) -> Result<Verifier> {
137 let padding = make_cstr(padding)?;
138 let obj = botan_init!(
139 botan_pk_op_verify_create,
140 key.handle(),
141 padding.as_ptr(),
142 1u32
143 )?;
144 Ok(Verifier { obj })
145 }
146
147 pub fn update(&mut self, data: &[u8]) -> Result<()> {
149 botan_call!(
150 botan_pk_op_verify_update,
151 self.obj,
152 data.as_ptr(),
153 data.len()
154 )
155 }
156
157 pub fn finish(&mut self, signature: &[u8]) -> Result<bool> {
159 match unsafe { botan_pk_op_verify_finish(self.obj, signature.as_ptr(), signature.len()) } {
160 0 => Ok(true),
161 BOTAN_FFI_INVALID_VERIFIER => Ok(false),
162 e => Err(Error::from_rc(e)),
163 }
164 }
165}
166
167#[derive(Debug)]
168pub struct Encryptor {
180 obj: botan_pk_op_encrypt_t,
181}
182
183unsafe impl Sync for Encryptor {}
184unsafe impl Send for Encryptor {}
185
186botan_impl_drop!(Encryptor, botan_pk_op_encrypt_destroy);
187
188impl Encryptor {
189 pub fn new(key: &Pubkey, padding: &str) -> Result<Encryptor> {
191 let padding = make_cstr(padding)?;
192 let obj = botan_init!(
193 botan_pk_op_encrypt_create,
194 key.handle(),
195 padding.as_ptr(),
196 0u32
197 )?;
198 Ok(Encryptor { obj })
199 }
200
201 pub fn encrypt(&mut self, ptext: &[u8], rng: &mut RandomNumberGenerator) -> Result<Vec<u8>> {
203 let mut ctext_len = 0;
204 botan_call!(
205 botan_pk_op_encrypt_output_length,
206 self.obj,
207 ptext.len(),
208 &mut ctext_len
209 )?;
210
211 let rng_handle = rng.handle();
212
213 call_botan_ffi_returning_vec_u8(ctext_len, &|out_buf, out_len| unsafe {
214 botan_pk_op_encrypt(
215 self.obj,
216 rng_handle,
217 out_buf,
218 out_len,
219 ptext.as_ptr(),
220 ptext.len(),
221 )
222 })
223 }
224}
225
226#[derive(Debug)]
227pub struct KeyAgreement {
229 obj: botan_pk_op_ka_t,
230}
231
232unsafe impl Sync for KeyAgreement {}
233unsafe impl Send for KeyAgreement {}
234
235botan_impl_drop!(KeyAgreement, botan_pk_op_key_agreement_destroy);
236
237impl KeyAgreement {
238 pub fn new(key: &Privkey, kdf: &str) -> Result<KeyAgreement> {
240 let kdf = make_cstr(kdf)?;
241 let obj = botan_init!(
242 botan_pk_op_key_agreement_create,
243 key.handle(),
244 kdf.as_ptr(),
245 0u32
246 )?;
247 Ok(KeyAgreement { obj })
248 }
249
250 pub fn agree(
252 &mut self,
253 requested_output: usize,
254 counterparty_key: &[u8],
255 salt: &[u8],
256 ) -> Result<Vec<u8>> {
257 let mut ka_len = requested_output;
258
259 if ka_len == 0 {
260 ka_len = botan_usize!(botan_pk_op_key_agreement_size, self.obj)?;
261 }
262
263 call_botan_ffi_returning_vec_u8(ka_len, &|out_buf, out_len| unsafe {
264 botan_pk_op_key_agreement(
265 self.obj,
266 out_buf,
267 out_len,
268 counterparty_key.as_ptr(),
269 counterparty_key.len(),
270 salt.as_ptr(),
271 salt.len(),
272 )
273 })
274 }
275}