Coverage Report

Created: 2025-12-28 06:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/openssl-0.10.62/src/encrypt.rs
Line
Count
Source
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;
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> {
63
0
    fn drop(&mut self) {
64
0
        unsafe {
65
0
            ffi::EVP_PKEY_CTX_free(self.pctx);
66
0
        }
67
0
    }
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
76
0
    pub fn new<T>(pkey: &'a PKeyRef<T>) -> Result<Encrypter<'a>, ErrorStack>
77
0
    where
78
0
        T: HasPublic,
79
    {
80
        unsafe {
81
0
            ffi::init();
82
83
0
            let pctx = cvt_p(ffi::EVP_PKEY_CTX_new(pkey.as_ptr(), ptr::null_mut()))?;
84
0
            let r = ffi::EVP_PKEY_encrypt_init(pctx);
85
0
            if r != 1 {
86
0
                ffi::EVP_PKEY_CTX_free(pctx);
87
0
                return Err(ErrorStack::get());
88
0
            }
89
90
0
            Ok(Encrypter {
91
0
                pctx,
92
0
                _p: PhantomData,
93
0
            })
94
        }
95
0
    }
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
0
    pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> {
103
        unsafe {
104
0
            let mut pad = 0;
105
0
            cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.pctx, &mut pad))
106
0
                .map(|_| Padding::from_raw(pad))
107
        }
108
0
    }
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
0
    pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> {
118
        unsafe {
119
0
            cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(
120
0
                self.pctx,
121
0
                padding.as_raw(),
122
            ))
123
0
            .map(|_| ())
124
        }
125
0
    }
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
0
    pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
135
        unsafe {
136
0
            cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md(
137
0
                self.pctx,
138
0
                md.as_ptr() as *mut _,
139
            ))
140
0
            .map(|_| ())
141
        }
142
0
    }
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
0
    pub fn set_rsa_oaep_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
153
        unsafe {
154
0
            cvt(ffi::EVP_PKEY_CTX_set_rsa_oaep_md(
155
0
                self.pctx,
156
0
                md.as_ptr() as *mut _,
157
            ))
158
0
            .map(|_| ())
159
        }
160
0
    }
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
0
    pub fn set_rsa_oaep_label(&mut self, label: &[u8]) -> Result<(), ErrorStack> {
171
        unsafe {
172
0
            let p = cvt_p(ffi::OPENSSL_malloc(label.len() as _))?;
173
0
            ptr::copy_nonoverlapping(label.as_ptr(), p as *mut u8, label.len());
174
175
0
            cvt(ffi::EVP_PKEY_CTX_set0_rsa_oaep_label(
176
0
                self.pctx,
177
0
                p,
178
0
                label.len() as c_int,
179
            ))
180
0
            .map(|_| ())
181
0
            .map_err(|e| {
182
0
                ffi::OPENSSL_free(p);
183
0
                e
184
0
            })
185
        }
186
0
    }
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
0
    pub fn encrypt(&self, from: &[u8], to: &mut [u8]) -> Result<usize, ErrorStack> {
222
0
        let mut written = to.len();
223
        unsafe {
224
0
            cvt(ffi::EVP_PKEY_encrypt(
225
0
                self.pctx,
226
0
                to.as_mut_ptr(),
227
0
                &mut written,
228
0
                from.as_ptr(),
229
0
                from.len(),
230
0
            ))?;
231
        }
232
233
0
        Ok(written)
234
0
    }
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
0
    pub fn encrypt_len(&self, from: &[u8]) -> Result<usize, ErrorStack> {
242
0
        let mut written = 0;
243
        unsafe {
244
0
            cvt(ffi::EVP_PKEY_encrypt(
245
0
                self.pctx,
246
0
                ptr::null_mut(),
247
0
                &mut written,
248
0
                from.as_ptr(),
249
0
                from.len(),
250
0
            ))?;
251
        }
252
253
0
        Ok(written)
254
0
    }
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> {
267
0
    fn drop(&mut self) {
268
0
        unsafe {
269
0
            ffi::EVP_PKEY_CTX_free(self.pctx);
270
0
        }
271
0
    }
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
280
0
    pub fn new<T>(pkey: &'a PKeyRef<T>) -> Result<Decrypter<'a>, ErrorStack>
281
0
    where
282
0
        T: HasPrivate,
283
    {
284
        unsafe {
285
0
            ffi::init();
286
287
0
            let pctx = cvt_p(ffi::EVP_PKEY_CTX_new(pkey.as_ptr(), ptr::null_mut()))?;
288
0
            let r = ffi::EVP_PKEY_decrypt_init(pctx);
289
0
            if r != 1 {
290
0
                ffi::EVP_PKEY_CTX_free(pctx);
291
0
                return Err(ErrorStack::get());
292
0
            }
293
294
0
            Ok(Decrypter {
295
0
                pctx,
296
0
                _p: PhantomData,
297
0
            })
298
        }
299
0
    }
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
0
    pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> {
307
        unsafe {
308
0
            let mut pad = 0;
309
0
            cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.pctx, &mut pad))
310
0
                .map(|_| Padding::from_raw(pad))
311
        }
312
0
    }
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
0
    pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> {
322
        unsafe {
323
0
            cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(
324
0
                self.pctx,
325
0
                padding.as_raw(),
326
            ))
327
0
            .map(|_| ())
328
        }
329
0
    }
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
0
    pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
339
        unsafe {
340
0
            cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md(
341
0
                self.pctx,
342
0
                md.as_ptr() as *mut _,
343
            ))
344
0
            .map(|_| ())
345
        }
346
0
    }
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
0
    pub fn set_rsa_oaep_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> {
357
        unsafe {
358
0
            cvt(ffi::EVP_PKEY_CTX_set_rsa_oaep_md(
359
0
                self.pctx,
360
0
                md.as_ptr() as *mut _,
361
            ))
362
0
            .map(|_| ())
363
        }
364
0
    }
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
0
    pub fn set_rsa_oaep_label(&mut self, label: &[u8]) -> Result<(), ErrorStack> {
375
        unsafe {
376
0
            let p = cvt_p(ffi::OPENSSL_malloc(label.len() as _))?;
377
0
            ptr::copy_nonoverlapping(label.as_ptr(), p as *mut u8, label.len());
378
379
0
            cvt(ffi::EVP_PKEY_CTX_set0_rsa_oaep_label(
380
0
                self.pctx,
381
0
                p,
382
0
                label.len() as c_int,
383
            ))
384
0
            .map(|_| ())
385
0
            .map_err(|e| {
386
0
                ffi::OPENSSL_free(p);
387
0
                e
388
0
            })
389
        }
390
0
    }
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
0
    pub fn decrypt(&self, from: &[u8], to: &mut [u8]) -> Result<usize, ErrorStack> {
441
0
        let mut written = to.len();
442
        unsafe {
443
0
            cvt(ffi::EVP_PKEY_decrypt(
444
0
                self.pctx,
445
0
                to.as_mut_ptr(),
446
0
                &mut written,
447
0
                from.as_ptr(),
448
0
                from.len(),
449
0
            ))?;
450
        }
451
452
0
        Ok(written)
453
0
    }
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
0
    pub fn decrypt_len(&self, from: &[u8]) -> Result<usize, ErrorStack> {
461
0
        let mut written = 0;
462
        unsafe {
463
0
            cvt(ffi::EVP_PKEY_decrypt(
464
0
                self.pctx,
465
0
                ptr::null_mut(),
466
0
                &mut written,
467
0
                from.as_ptr(),
468
0
                from.len(),
469
0
            ))?;
470
        }
471
472
0
        Ok(written)
473
0
    }
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]
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
}