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