1//! Message encryption.
2//!
3//! The [`Encrypter`] allows for encryption of data given a public key. The [`Decrypter`] can be
4//! used with the corresponding private key to decrypt the data.
5//!
6//! # Examples
7//!
8//! Encrypt and decrypt data given an RSA keypair:
9//!
10//! ```rust
11//! use openssl::encrypt::{Encrypter, Decrypter};
12//! use openssl::rsa::{Rsa, Padding};
13//! use openssl::pkey::PKey;
14//!
15//! // Generate a keypair
16//! let keypair = Rsa::generate(2048).unwrap();
17//! let keypair = PKey::from_rsa(keypair).unwrap();
18//!
19//! let data = b"hello, world!";
20//!
21//! // Encrypt the data with RSA PKCS1
22//! let mut encrypter = Encrypter::new(&keypair).unwrap();
23//! encrypter.set_rsa_padding(Padding::PKCS1).unwrap();
24//! // Create an output buffer
25//! let buffer_len = encrypter.encrypt_len(data).unwrap();
26//! let mut encrypted = vec![0; buffer_len];
27//! // Encrypt and truncate the buffer
28//! let encrypted_len = encrypter.encrypt(data, &mut encrypted).unwrap();
29//! encrypted.truncate(encrypted_len);
30//!
31//! // Decrypt the data
32//! let mut decrypter = Decrypter::new(&keypair).unwrap();
33//! decrypter.set_rsa_padding(Padding::PKCS1).unwrap();
34//! // Create an output buffer
35//! let buffer_len = decrypter.decrypt_len(&encrypted).unwrap();
36//! let mut decrypted = vec![0; buffer_len];
37//! // Encrypt and truncate the buffer
38//! let decrypted_len = decrypter.decrypt(&encrypted, &mut decrypted).unwrap();
39//! decrypted.truncate(decrypted_len);
40//! assert_eq!(&*decrypted, data);
41//! ```
42#[cfg(any(ossl102, libressl310))]
43use libc::c_int;
44use std::{marker::PhantomData, ptr};
45
46use crate::error::ErrorStack;
47use crate::hash::MessageDigest;
48use crate::pkey::{HasPrivate, HasPublic, PKeyRef};
49use crate::rsa::Padding;
50use crate::{cvt, cvt_p};
51use foreign_types::ForeignTypeRef;
52
53/// A type which encrypts data.
54pub struct Encrypter<'a> {
55 pctx: *mut ffi::EVP_PKEY_CTX,
56 _p: PhantomData<&'a ()>,
57}
58
59unsafe impl<'a> Sync for Encrypter<'a> {}
60unsafe impl<'a> Send for Encrypter<'a> {}
61
62impl<'a> Drop for Encrypter<'a> {
63 fn drop(&mut self) {
64 unsafe {
65 ffi::EVP_PKEY_CTX_free(self.pctx);
66 }
67 }
68}
69
70impl<'a> Encrypter<'a> {
71 /// Creates a new `Encrypter`.
72 ///
73 /// OpenSSL documentation at [`EVP_PKEY_encrypt_init`].
74 ///
75 /// [`EVP_PKEY_encrypt_init`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_encrypt_init.html
76 pub fn new<T>(pkey: &'a PKeyRef<T>) -> Result<Encrypter<'a>, ErrorStack>
77 where
78 T: HasPublic,
79 {
80 unsafe {
81 ffi::init();
82
83 let pctx = cvt_p(ffi::EVP_PKEY_CTX_new(pkey.as_ptr(), ptr::null_mut()))?;
84 let r = ffi::EVP_PKEY_encrypt_init(pctx);
85 if r != 1 {
86 ffi::EVP_PKEY_CTX_free(pctx);
87 return Err(ErrorStack::get());
88 }
89
90 Ok(Encrypter {
91 pctx,
92 _p: PhantomData,
93 })
94 }
95 }
96
97 /// Returns the RSA padding mode in use.
98 ///
99 /// This is only useful for RSA keys.
100 ///
101 /// This corresponds to `EVP_PKEY_CTX_get_rsa_padding`.
102 pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> {
103 unsafe {
104 let mut pad = 0;
105 cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.pctx, &mut pad))
106 .map(|_| Padding::from_raw(pad))
107 }
108 }
109
110 /// Sets the RSA padding mode.
111 ///
112 /// This is only useful for RSA keys.
113 ///
114 /// This corresponds to [`EVP_PKEY_CTX_set_rsa_padding`].
115 ///
116 /// [`EVP_PKEY_CTX_set_rsa_padding`]: https://www.openssl.org/docs/manmaster/crypto/EVP_PKEY_CTX_set_rsa_padding.html
117 pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> {
118 unsafe {
119 cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(
120 self.pctx,
121 padding.as_raw(),
122 ))
123 .map(|_| ())
124 }
125 }
126
127 /// Sets the RSA MGF1 algorithm.
128 ///
129 /// This is only useful for RSA keys.
130 ///
131 /// This corresponds to [`EVP_PKEY_CTX_set_rsa_mgf1_md`].
132 ///
133 /// [`EVP_PKEY_CTX_set_rsa_mgf1_md`]: https://www.openssl.org/docs/manmaster/man7/RSA-PSS.html
134 pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
135 unsafe {
136 cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md(
137 self.pctx,
138 md.as_ptr() as *mut _,
139 ))
140 .map(|_| ())
141 }
142 }
143
144 /// Sets the RSA OAEP algorithm.
145 ///
146 /// This is only useful for RSA keys.
147 ///
148 /// This corresponds to [`EVP_PKEY_CTX_set_rsa_oaep_md`].
149 ///
150 /// [`EVP_PKEY_CTX_set_rsa_oaep_md`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_CTX_set_rsa_oaep_md.html
151 #[cfg(any(ossl102, libressl310))]
152 pub fn set_rsa_oaep_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
153 unsafe {
154 cvt(ffi::EVP_PKEY_CTX_set_rsa_oaep_md(
155 self.pctx,
156 md.as_ptr() as *mut _,
157 ))
158 .map(|_| ())
159 }
160 }
161
162 /// Sets the RSA OAEP label.
163 ///
164 /// This is only useful for RSA keys.
165 ///
166 /// This corresponds to [`EVP_PKEY_CTX_set0_rsa_oaep_label`].
167 ///
168 /// [`EVP_PKEY_CTX_set0_rsa_oaep_label`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_CTX_set0_rsa_oaep_label.html
169 #[cfg(any(ossl102, libressl310))]
170 pub fn set_rsa_oaep_label(&mut self, label: &[u8]) -> Result<(), ErrorStack> {
171 unsafe {
172 let p = cvt_p(ffi::OPENSSL_malloc(label.len() as _))?;
173 ptr::copy_nonoverlapping(label.as_ptr(), p as *mut u8, label.len());
174
175 cvt(ffi::EVP_PKEY_CTX_set0_rsa_oaep_label(
176 self.pctx,
177 p,
178 label.len() as c_int,
179 ))
180 .map(|_| ())
181 .map_err(|e| {
182 ffi::OPENSSL_free(p);
183 e
184 })
185 }
186 }
187
188 /// Performs public key encryption.
189 ///
190 /// In order to know the size needed for the output buffer, use [`encrypt_len`](Encrypter::encrypt_len).
191 /// Note that the length of the output buffer can be greater of the length of the encoded data.
192 /// ```
193 /// # use openssl::{
194 /// # encrypt::Encrypter,
195 /// # pkey::PKey,
196 /// # rsa::{Rsa, Padding},
197 /// # };
198 /// #
199 /// # let key = include_bytes!("../test/rsa.pem");
200 /// # let private_key = Rsa::private_key_from_pem(key).unwrap();
201 /// # let pkey = PKey::from_rsa(private_key).unwrap();
202 /// # let input = b"hello world".to_vec();
203 /// #
204 /// let mut encrypter = Encrypter::new(&pkey).unwrap();
205 /// encrypter.set_rsa_padding(Padding::PKCS1).unwrap();
206 ///
207 /// // Get the length of the output buffer
208 /// let buffer_len = encrypter.encrypt_len(&input).unwrap();
209 /// let mut encoded = vec![0u8; buffer_len];
210 ///
211 /// // Encode the data and get its length
212 /// let encoded_len = encrypter.encrypt(&input, &mut encoded).unwrap();
213 ///
214 /// // Use only the part of the buffer with the encoded data
215 /// let encoded = &encoded[..encoded_len];
216 /// ```
217 ///
218 /// This corresponds to [`EVP_PKEY_encrypt`].
219 ///
220 /// [`EVP_PKEY_encrypt`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_encrypt.html
221 pub fn encrypt(&self, from: &[u8], to: &mut [u8]) -> Result<usize, ErrorStack> {
222 let mut written = to.len();
223 unsafe {
224 cvt(ffi::EVP_PKEY_encrypt(
225 self.pctx,
226 to.as_mut_ptr(),
227 &mut written,
228 from.as_ptr(),
229 from.len(),
230 ))?;
231 }
232
233 Ok(written)
234 }
235
236 /// Gets the size of the buffer needed to encrypt the input data.
237 ///
238 /// This corresponds to [`EVP_PKEY_encrypt`] called with a null pointer as output argument.
239 ///
240 /// [`EVP_PKEY_encrypt`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_encrypt.html
241 pub fn encrypt_len(&self, from: &[u8]) -> Result<usize, ErrorStack> {
242 let mut written = 0;
243 unsafe {
244 cvt(ffi::EVP_PKEY_encrypt(
245 self.pctx,
246 ptr::null_mut(),
247 &mut written,
248 from.as_ptr(),
249 from.len(),
250 ))?;
251 }
252
253 Ok(written)
254 }
255}
256
257/// A type which decrypts data.
258pub struct Decrypter<'a> {
259 pctx: *mut ffi::EVP_PKEY_CTX,
260 _p: PhantomData<&'a ()>,
261}
262
263unsafe impl<'a> Sync for Decrypter<'a> {}
264unsafe impl<'a> Send for Decrypter<'a> {}
265
266impl<'a> Drop for Decrypter<'a> {
267 fn drop(&mut self) {
268 unsafe {
269 ffi::EVP_PKEY_CTX_free(self.pctx);
270 }
271 }
272}
273
274impl<'a> Decrypter<'a> {
275 /// Creates a new `Decrypter`.
276 ///
277 /// OpenSSL documentation at [`EVP_PKEY_decrypt_init`].
278 ///
279 /// [`EVP_PKEY_decrypt_init`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_decrypt_init.html
280 pub fn new<T>(pkey: &'a PKeyRef<T>) -> Result<Decrypter<'a>, ErrorStack>
281 where
282 T: HasPrivate,
283 {
284 unsafe {
285 ffi::init();
286
287 let pctx = cvt_p(ffi::EVP_PKEY_CTX_new(pkey.as_ptr(), ptr::null_mut()))?;
288 let r = ffi::EVP_PKEY_decrypt_init(pctx);
289 if r != 1 {
290 ffi::EVP_PKEY_CTX_free(pctx);
291 return Err(ErrorStack::get());
292 }
293
294 Ok(Decrypter {
295 pctx,
296 _p: PhantomData,
297 })
298 }
299 }
300
301 /// Returns the RSA padding mode in use.
302 ///
303 /// This is only useful for RSA keys.
304 ///
305 /// This corresponds to `EVP_PKEY_CTX_get_rsa_padding`.
306 pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> {
307 unsafe {
308 let mut pad = 0;
309 cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.pctx, &mut pad))
310 .map(|_| Padding::from_raw(pad))
311 }
312 }
313
314 /// Sets the RSA padding mode.
315 ///
316 /// This is only useful for RSA keys.
317 ///
318 /// This corresponds to [`EVP_PKEY_CTX_set_rsa_padding`].
319 ///
320 /// [`EVP_PKEY_CTX_set_rsa_padding`]: https://www.openssl.org/docs/manmaster/crypto/EVP_PKEY_CTX_set_rsa_padding.html
321 pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> {
322 unsafe {
323 cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(
324 self.pctx,
325 padding.as_raw(),
326 ))
327 .map(|_| ())
328 }
329 }
330
331 /// Sets the RSA MGF1 algorithm.
332 ///
333 /// This is only useful for RSA keys.
334 ///
335 /// This corresponds to [`EVP_PKEY_CTX_set_rsa_mgf1_md`].
336 ///
337 /// [`EVP_PKEY_CTX_set_rsa_mgf1_md`]: https://www.openssl.org/docs/manmaster/man7/RSA-PSS.html
338 pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
339 unsafe {
340 cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md(
341 self.pctx,
342 md.as_ptr() as *mut _,
343 ))
344 .map(|_| ())
345 }
346 }
347
348 /// Sets the RSA OAEP algorithm.
349 ///
350 /// This is only useful for RSA keys.
351 ///
352 /// This corresponds to [`EVP_PKEY_CTX_set_rsa_oaep_md`].
353 ///
354 /// [`EVP_PKEY_CTX_set_rsa_oaep_md`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_CTX_set_rsa_oaep_md.html
355 #[cfg(any(ossl102, libressl310))]
356 pub fn set_rsa_oaep_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
357 unsafe {
358 cvt(ffi::EVP_PKEY_CTX_set_rsa_oaep_md(
359 self.pctx,
360 md.as_ptr() as *mut _,
361 ))
362 .map(|_| ())
363 }
364 }
365
366 /// Sets the RSA OAEP label.
367 ///
368 /// This is only useful for RSA keys.
369 ///
370 /// This corresponds to [`EVP_PKEY_CTX_set0_rsa_oaep_label`].
371 ///
372 /// [`EVP_PKEY_CTX_set0_rsa_oaep_label`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_CTX_set0_rsa_oaep_label.html
373 #[cfg(any(ossl102, libressl310))]
374 pub fn set_rsa_oaep_label(&mut self, label: &[u8]) -> Result<(), ErrorStack> {
375 unsafe {
376 let p = cvt_p(ffi::OPENSSL_malloc(label.len() as _))?;
377 ptr::copy_nonoverlapping(label.as_ptr(), p as *mut u8, label.len());
378
379 cvt(ffi::EVP_PKEY_CTX_set0_rsa_oaep_label(
380 self.pctx,
381 p,
382 label.len() as c_int,
383 ))
384 .map(|_| ())
385 .map_err(|e| {
386 ffi::OPENSSL_free(p);
387 e
388 })
389 }
390 }
391
392 /// Performs public key decryption.
393 ///
394 /// In order to know the size needed for the output buffer, use [`decrypt_len`](Decrypter::decrypt_len).
395 /// Note that the length of the output buffer can be greater of the length of the decoded data.
396 /// ```
397 /// # use openssl::{
398 /// # encrypt::Decrypter,
399 /// # pkey::PKey,
400 /// # rsa::{Rsa, Padding},
401 /// # };
402 /// #
403 /// # const INPUT: &[u8] = b"\
404 /// # \x26\xa1\xc1\x13\xc5\x7f\xb4\x9f\xa0\xb4\xde\x61\x5e\x2e\xc6\xfb\x76\x5c\xd1\x2b\x5f\
405 /// # \x1d\x36\x60\xfa\xf8\xe8\xb3\x21\xf4\x9c\x70\xbc\x03\xea\xea\xac\xce\x4b\xb3\xf6\x45\
406 /// # \xcc\xb3\x80\x9e\xa8\xf7\xc3\x5d\x06\x12\x7a\xa3\x0c\x30\x67\xf1\xe7\x94\x6c\xf6\x26\
407 /// # \xac\x28\x17\x59\x69\xe1\xdc\xed\x7e\xc0\xe9\x62\x57\x49\xce\xdd\x13\x07\xde\x18\x03\
408 /// # \x0f\x9d\x61\x65\xb9\x23\x8c\x78\x4b\xad\x23\x49\x75\x47\x64\xa0\xa0\xa2\x90\xc1\x49\
409 /// # \x1b\x05\x24\xc2\xe9\x2c\x0d\x49\x78\x72\x61\x72\xed\x8b\x6f\x8a\xe8\xca\x05\x5c\x58\
410 /// # \xd6\x95\xd6\x7b\xe3\x2d\x0d\xaa\x3e\x6d\x3c\x9a\x1c\x1d\xb4\x6c\x42\x9d\x9a\x82\x55\
411 /// # \xd9\xde\xc8\x08\x7b\x17\xac\xd7\xaf\x86\x7b\x69\x9e\x3c\xf4\x5e\x1c\x39\x52\x6d\x62\
412 /// # \x50\x51\xbd\xa6\xc8\x4e\xe9\x34\xf0\x37\x0d\xa9\xa9\x77\xe6\xf5\xc2\x47\x2d\xa8\xee\
413 /// # \x3f\x69\x78\xff\xa9\xdc\x70\x22\x20\x9a\x5c\x9b\x70\x15\x90\xd3\xb4\x0e\x54\x9e\x48\
414 /// # \xed\xb6\x2c\x88\xfc\xb4\xa9\x37\x10\xfa\x71\xb2\xec\x75\xe7\xe7\x0e\xf4\x60\x2c\x7b\
415 /// # \x58\xaf\xa0\x53\xbd\x24\xf1\x12\xe3\x2e\x99\x25\x0a\x54\x54\x9d\xa1\xdb\xca\x41\x85\
416 /// # \xf4\x62\x78\x64";
417 /// #
418 /// # let key = include_bytes!("../test/rsa.pem");
419 /// # let private_key = Rsa::private_key_from_pem(key).unwrap();
420 /// # let pkey = PKey::from_rsa(private_key).unwrap();
421 /// # let input = INPUT.to_vec();
422 /// #
423 /// let mut decrypter = Decrypter::new(&pkey).unwrap();
424 /// decrypter.set_rsa_padding(Padding::PKCS1).unwrap();
425 ///
426 /// // Get the length of the output buffer
427 /// let buffer_len = decrypter.decrypt_len(&input).unwrap();
428 /// let mut decoded = vec![0u8; buffer_len];
429 ///
430 /// // Decrypt the data and get its length
431 /// let decoded_len = decrypter.decrypt(&input, &mut decoded).unwrap();
432 ///
433 /// // Use only the part of the buffer with the decrypted data
434 /// let decoded = &decoded[..decoded_len];
435 /// ```
436 ///
437 /// This corresponds to [`EVP_PKEY_decrypt`].
438 ///
439 /// [`EVP_PKEY_decrypt`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_decrypt.html
440 pub fn decrypt(&self, from: &[u8], to: &mut [u8]) -> Result<usize, ErrorStack> {
441 let mut written = to.len();
442 unsafe {
443 cvt(ffi::EVP_PKEY_decrypt(
444 self.pctx,
445 to.as_mut_ptr(),
446 &mut written,
447 from.as_ptr(),
448 from.len(),
449 ))?;
450 }
451
452 Ok(written)
453 }
454
455 /// Gets the size of the buffer needed to decrypt the input data.
456 ///
457 /// This corresponds to [`EVP_PKEY_decrypt`] called with a null pointer as output argument.
458 ///
459 /// [`EVP_PKEY_decrypt`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_decrypt.html
460 pub fn decrypt_len(&self, from: &[u8]) -> Result<usize, ErrorStack> {
461 let mut written = 0;
462 unsafe {
463 cvt(ffi::EVP_PKEY_decrypt(
464 self.pctx,
465 ptr::null_mut(),
466 &mut written,
467 from.as_ptr(),
468 from.len(),
469 ))?;
470 }
471
472 Ok(written)
473 }
474}
475
476#[cfg(test)]
477mod test {
478 use hex::FromHex;
479
480 use crate::encrypt::{Decrypter, Encrypter};
481 #[cfg(any(ossl102, libressl310))]
482 use crate::hash::MessageDigest;
483 use crate::pkey::PKey;
484 use crate::rsa::{Padding, Rsa};
485
486 const INPUT: &str =
487 "65794a68624763694f694a53557a49314e694a392e65794a7063334d694f694a71623255694c41304b49434a6c\
488 654841694f6a457a4d4441344d546b7a4f44417344516f67496d6830644841364c79396c654746746347786c4c\
489 6d4e76625339706331397962323930496a7030636e566c6651";
490
491 #[test]
492 fn rsa_encrypt_decrypt() {
493 let key = include_bytes!("../test/rsa.pem");
494 let private_key = Rsa::private_key_from_pem(key).unwrap();
495 let pkey = PKey::from_rsa(private_key).unwrap();
496
497 let mut encrypter = Encrypter::new(&pkey).unwrap();
498 encrypter.set_rsa_padding(Padding::PKCS1).unwrap();
499 let input = Vec::from_hex(INPUT).unwrap();
500 let buffer_len = encrypter.encrypt_len(&input).unwrap();
501 let mut encoded = vec![0u8; buffer_len];
502 let encoded_len = encrypter.encrypt(&input, &mut encoded).unwrap();
503 let encoded = &encoded[..encoded_len];
504
505 let mut decrypter = Decrypter::new(&pkey).unwrap();
506 decrypter.set_rsa_padding(Padding::PKCS1).unwrap();
507 let buffer_len = decrypter.decrypt_len(encoded).unwrap();
508 let mut decoded = vec![0u8; buffer_len];
509 let decoded_len = decrypter.decrypt(encoded, &mut decoded).unwrap();
510 let decoded = &decoded[..decoded_len];
511
512 assert_eq!(decoded, &*input);
513 }
514
515 #[test]
516 #[cfg(any(ossl102, libressl310))]
517 fn rsa_encrypt_decrypt_with_sha256() {
518 let key = include_bytes!("../test/rsa.pem");
519 let private_key = Rsa::private_key_from_pem(key).unwrap();
520 let pkey = PKey::from_rsa(private_key).unwrap();
521
522 let md = MessageDigest::sha256();
523
524 let mut encrypter = Encrypter::new(&pkey).unwrap();
525 encrypter.set_rsa_padding(Padding::PKCS1_OAEP).unwrap();
526 encrypter.set_rsa_oaep_md(md).unwrap();
527 encrypter.set_rsa_mgf1_md(md).unwrap();
528 let input = Vec::from_hex(INPUT).unwrap();
529 let buffer_len = encrypter.encrypt_len(&input).unwrap();
530 let mut encoded = vec![0u8; buffer_len];
531 let encoded_len = encrypter.encrypt(&input, &mut encoded).unwrap();
532 let encoded = &encoded[..encoded_len];
533
534 let mut decrypter = Decrypter::new(&pkey).unwrap();
535 decrypter.set_rsa_padding(Padding::PKCS1_OAEP).unwrap();
536 decrypter.set_rsa_oaep_md(md).unwrap();
537 decrypter.set_rsa_mgf1_md(md).unwrap();
538 let buffer_len = decrypter.decrypt_len(encoded).unwrap();
539 let mut decoded = vec![0u8; buffer_len];
540 let decoded_len = decrypter.decrypt(encoded, &mut decoded).unwrap();
541 let decoded = &decoded[..decoded_len];
542
543 assert_eq!(decoded, &*input);
544 }
545
546 #[test]
547 #[cfg(any(ossl102, libressl310))]
548 fn rsa_encrypt_decrypt_oaep_label() {
549 let key = include_bytes!("../test/rsa.pem");
550 let private_key = Rsa::private_key_from_pem(key).unwrap();
551 let pkey = PKey::from_rsa(private_key).unwrap();
552
553 let mut encrypter = Encrypter::new(&pkey).unwrap();
554 encrypter.set_rsa_padding(Padding::PKCS1_OAEP).unwrap();
555 encrypter.set_rsa_oaep_label(b"test_oaep_label").unwrap();
556 let input = Vec::from_hex(INPUT).unwrap();
557 let buffer_len = encrypter.encrypt_len(&input).unwrap();
558 let mut encoded = vec![0u8; buffer_len];
559 let encoded_len = encrypter.encrypt(&input, &mut encoded).unwrap();
560 let encoded = &encoded[..encoded_len];
561
562 let mut decrypter = Decrypter::new(&pkey).unwrap();
563 decrypter.set_rsa_padding(Padding::PKCS1_OAEP).unwrap();
564 decrypter.set_rsa_oaep_label(b"test_oaep_label").unwrap();
565 let buffer_len = decrypter.decrypt_len(encoded).unwrap();
566 let mut decoded = vec![0u8; buffer_len];
567 let decoded_len = decrypter.decrypt(encoded, &mut decoded).unwrap();
568 let decoded = &decoded[..decoded_len];
569
570 assert_eq!(decoded, &*input);
571
572 decrypter.set_rsa_oaep_label(b"wrong_oaep_label").unwrap();
573 let buffer_len = decrypter.decrypt_len(encoded).unwrap();
574 let mut decoded = vec![0u8; buffer_len];
575
576 assert!(decrypter.decrypt(encoded, &mut decoded).is_err());
577 }
578}
579