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))] 43 use libc::{c_int, c_void}; 44 use std::{marker::PhantomData, ptr}; 45 46 use crate::error::ErrorStack; 47 use crate::hash::MessageDigest; 48 use crate::pkey::{HasPrivate, HasPublic, PKeyRef}; 49 use crate::rsa::Padding; 50 use crate::{cvt, cvt_p}; 51 use foreign_types::ForeignTypeRef; 52 53 /// A type which encrypts data. 54 pub struct Encrypter<'a> { 55 pctx: *mut ffi::EVP_PKEY_CTX, 56 _p: PhantomData<&'a ()>, 57 } 58 59 unsafe impl<'a> Sync for Encrypter<'a> {} 60 unsafe impl<'a> Send for Encrypter<'a> {} 61 62 impl<'a> Drop for Encrypter<'a> { drop(&mut self)63 fn drop(&mut self) { 64 unsafe { 65 ffi::EVP_PKEY_CTX_free(self.pctx); 66 } 67 } 68 } 69 70 impl<'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 new<T>(pkey: &'a PKeyRef<T>) -> Result<Encrypter<'a>, ErrorStack> where T: HasPublic,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`. rsa_padding(&self) -> Result<Padding, ErrorStack>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 set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack>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 set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack>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))] set_rsa_oaep_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack>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))] set_rsa_oaep_label(&mut self, label: &[u8]) -> Result<(), ErrorStack>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 as *mut c_void, 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 encrypt(&self, from: &[u8], to: &mut [u8]) -> Result<usize, ErrorStack>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 encrypt_len(&self, from: &[u8]) -> Result<usize, ErrorStack>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. 258 pub struct Decrypter<'a> { 259 pctx: *mut ffi::EVP_PKEY_CTX, 260 _p: PhantomData<&'a ()>, 261 } 262 263 unsafe impl<'a> Sync for Decrypter<'a> {} 264 unsafe impl<'a> Send for Decrypter<'a> {} 265 266 impl<'a> Drop for Decrypter<'a> { drop(&mut self)267 fn drop(&mut self) { 268 unsafe { 269 ffi::EVP_PKEY_CTX_free(self.pctx); 270 } 271 } 272 } 273 274 impl<'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 new<T>(pkey: &'a PKeyRef<T>) -> Result<Decrypter<'a>, ErrorStack> where T: HasPrivate,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`. rsa_padding(&self) -> Result<Padding, ErrorStack>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 set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack>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 set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack>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))] set_rsa_oaep_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack>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))] set_rsa_oaep_label(&mut self, label: &[u8]) -> Result<(), ErrorStack>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 as *mut c_void, 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 decrypt(&self, from: &[u8], to: &mut [u8]) -> Result<usize, ErrorStack>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 decrypt_len(&self, from: &[u8]) -> Result<usize, ErrorStack>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)] 477 mod 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] rsa_encrypt_decrypt()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))] rsa_encrypt_decrypt_with_sha256()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))] rsa_encrypt_decrypt_oaep_label()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