1use crate::ffi;
27use crate::libc_types::c_int;
28use foreign_types::{ForeignType, ForeignTypeRef};
29use openssl_macros::corresponds;
30use std::fmt;
31use std::mem;
32use std::ptr;
33
34use crate::bn::{BigNum, BigNumRef};
35use crate::error::ErrorStack;
36use crate::pkey::{HasPrivate, HasPublic, Private, Public};
37use crate::{cvt, cvt_n, cvt_p};
38
39pub const EVP_PKEY_OP_SIGN: c_int = 1 << 3;
40pub const EVP_PKEY_OP_VERIFY: c_int = 1 << 4;
41pub const EVP_PKEY_OP_VERIFYRECOVER: c_int = 1 << 5;
42pub const EVP_PKEY_OP_SIGNCTX: c_int = 1 << 6;
43pub const EVP_PKEY_OP_VERIFYCTX: c_int = 1 << 7;
44pub const EVP_PKEY_OP_ENCRYPT: c_int = 1 << 8;
45pub const EVP_PKEY_OP_DECRYPT: c_int = 1 << 9;
46
47pub const EVP_PKEY_OP_TYPE_SIG: c_int = EVP_PKEY_OP_SIGN
48 | EVP_PKEY_OP_VERIFY
49 | EVP_PKEY_OP_VERIFYRECOVER
50 | EVP_PKEY_OP_SIGNCTX
51 | EVP_PKEY_OP_VERIFYCTX;
52
53pub const EVP_PKEY_OP_TYPE_CRYPT: c_int = EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT;
54
55#[derive(Debug, Copy, Clone, PartialEq, Eq)]
61pub struct Padding(c_int);
62
63impl Padding {
64 pub const NONE: Padding = Padding(ffi::RSA_NO_PADDING);
65 pub const PKCS1: Padding = Padding(ffi::RSA_PKCS1_PADDING);
66 pub const PKCS1_OAEP: Padding = Padding(ffi::RSA_PKCS1_OAEP_PADDING);
67 pub const PKCS1_PSS: Padding = Padding(ffi::RSA_PKCS1_PSS_PADDING);
68
69 #[must_use]
71 pub fn from_raw(value: c_int) -> Padding {
72 Padding(value)
73 }
74
75 #[allow(clippy::trivially_copy_pass_by_ref)]
77 #[must_use]
78 pub fn as_raw(&self) -> c_int {
79 self.0
80 }
81}
82
83generic_foreign_type_and_impl_send_sync! {
84 type CType = ffi::RSA;
85 fn drop = ffi::RSA_free;
86
87 pub struct Rsa<T>;
89
90 pub struct RsaRef<T>;
92}
93
94impl<T> Clone for Rsa<T> {
95 fn clone(&self) -> Rsa<T> {
96 (**self).to_owned()
97 }
98}
99
100impl<T> ToOwned for RsaRef<T> {
101 type Owned = Rsa<T>;
102
103 fn to_owned(&self) -> Rsa<T> {
104 unsafe {
105 ffi::RSA_up_ref(self.as_ptr());
106 Rsa::from_ptr(self.as_ptr())
107 }
108 }
109}
110
111impl<T> RsaRef<T>
112where
113 T: HasPrivate,
114{
115 private_key_to_pem! {
116 #[corresponds(PEM_write_bio_RSAPrivateKey)]
120 private_key_to_pem,
121 #[corresponds(PEM_write_bio_RSAPrivateKey)]
125 private_key_to_pem_passphrase,
126 ffi::PEM_write_bio_RSAPrivateKey
127 }
128
129 to_der! {
130 #[corresponds(i2d_RSAPrivateKey)]
132 private_key_to_der,
133 ffi::i2d_RSAPrivateKey
134 }
135
136 pub fn private_decrypt(
143 &self,
144 from: &[u8],
145 to: &mut [u8],
146 padding: Padding,
147 ) -> Result<usize, ErrorStack> {
148 assert!(i32::try_from(from.len()).is_ok());
149 assert!(to.len() >= self.size() as usize);
150
151 unsafe {
152 let len = cvt_n(ffi::RSA_private_decrypt(
153 from.len(),
154 from.as_ptr(),
155 to.as_mut_ptr(),
156 self.as_ptr(),
157 padding.0,
158 ))?;
159 Ok(len as usize)
160 }
161 }
162
163 pub fn private_encrypt(
170 &self,
171 from: &[u8],
172 to: &mut [u8],
173 padding: Padding,
174 ) -> Result<usize, ErrorStack> {
175 assert!(from.len() <= i32::MAX as usize);
176 assert!(to.len() >= self.size() as usize);
177
178 unsafe {
179 let len = cvt_n(ffi::RSA_private_encrypt(
180 from.len(),
181 from.as_ptr(),
182 to.as_mut_ptr(),
183 self.as_ptr(),
184 padding.0,
185 ))?;
186 Ok(len as usize)
187 }
188 }
189
190 #[corresponds(RSA_get0_key)]
192 #[must_use]
193 pub fn d(&self) -> &BigNumRef {
194 unsafe {
195 let mut d = ptr::null();
196 RSA_get0_key(self.as_ptr(), ptr::null_mut(), ptr::null_mut(), &mut d);
197 BigNumRef::from_ptr(d.cast_mut())
198 }
199 }
200
201 #[corresponds(RSA_get0_factors)]
203 #[must_use]
204 pub fn p(&self) -> Option<&BigNumRef> {
205 unsafe {
206 let mut p = ptr::null();
207 RSA_get0_factors(self.as_ptr(), &mut p, ptr::null_mut());
208 if p.is_null() {
209 None
210 } else {
211 Some(BigNumRef::from_ptr(p.cast_mut()))
212 }
213 }
214 }
215
216 #[corresponds(RSA_get0_factors)]
218 #[must_use]
219 pub fn q(&self) -> Option<&BigNumRef> {
220 unsafe {
221 let mut q = ptr::null();
222 RSA_get0_factors(self.as_ptr(), ptr::null_mut(), &mut q);
223 if q.is_null() {
224 None
225 } else {
226 Some(BigNumRef::from_ptr(q.cast_mut()))
227 }
228 }
229 }
230
231 #[corresponds(RSA_get0_crt_params)]
233 #[must_use]
234 pub fn dmp1(&self) -> Option<&BigNumRef> {
235 unsafe {
236 let mut dp = ptr::null();
237 RSA_get0_crt_params(self.as_ptr(), &mut dp, ptr::null_mut(), ptr::null_mut());
238 if dp.is_null() {
239 None
240 } else {
241 Some(BigNumRef::from_ptr(dp.cast_mut()))
242 }
243 }
244 }
245
246 #[corresponds(RSA_get0_crt_params)]
248 #[must_use]
249 pub fn dmq1(&self) -> Option<&BigNumRef> {
250 unsafe {
251 let mut dq = ptr::null();
252 RSA_get0_crt_params(self.as_ptr(), ptr::null_mut(), &mut dq, ptr::null_mut());
253 if dq.is_null() {
254 None
255 } else {
256 Some(BigNumRef::from_ptr(dq.cast_mut()))
257 }
258 }
259 }
260
261 #[corresponds(RSA_get0_crt_params)]
263 #[must_use]
264 pub fn iqmp(&self) -> Option<&BigNumRef> {
265 unsafe {
266 let mut qi = ptr::null();
267 RSA_get0_crt_params(self.as_ptr(), ptr::null_mut(), ptr::null_mut(), &mut qi);
268 if qi.is_null() {
269 None
270 } else {
271 Some(BigNumRef::from_ptr(qi.cast_mut()))
272 }
273 }
274 }
275
276 #[corresponds(RSA_check_key)]
278 #[allow(clippy::unnecessary_cast)]
279 pub fn check_key(&self) -> Result<bool, ErrorStack> {
280 unsafe {
281 let result = ffi::RSA_check_key(self.as_ptr()) as i32;
282 if result == -1 {
283 Err(ErrorStack::get())
284 } else {
285 Ok(result == 1)
286 }
287 }
288 }
289}
290
291impl<T> RsaRef<T>
292where
293 T: HasPublic,
294{
295 to_pem! {
296 #[corresponds(PEM_write_bio_RSA_PUBKEY)]
300 public_key_to_pem,
301 ffi::PEM_write_bio_RSA_PUBKEY
302 }
303
304 to_der! {
305 #[corresponds(i2d_RSA_PUBKEY)]
307 public_key_to_der,
308 ffi::i2d_RSA_PUBKEY
309 }
310
311 to_pem! {
312 #[corresponds(PEM_write_bio_RSAPublicKey)]
316 public_key_to_pem_pkcs1,
317 ffi::PEM_write_bio_RSAPublicKey
318 }
319
320 to_der! {
321 #[corresponds(i2d_RSAPublicKey)]
323 public_key_to_der_pkcs1,
324 ffi::i2d_RSAPublicKey
325 }
326
327 #[corresponds(RSA_size)]
329 #[allow(clippy::unnecessary_cast)]
330 #[must_use]
331 pub fn size(&self) -> u32 {
332 unsafe { ffi::RSA_size(self.as_ptr()) as u32 }
333 }
334
335 pub fn public_decrypt(
341 &self,
342 from: &[u8],
343 to: &mut [u8],
344 padding: Padding,
345 ) -> Result<usize, ErrorStack> {
346 assert!(i32::try_from(from.len()).is_ok());
347 assert!(to.len() >= self.size() as usize);
348
349 unsafe {
350 let len = cvt_n(ffi::RSA_public_decrypt(
351 from.len(),
352 from.as_ptr(),
353 to.as_mut_ptr(),
354 self.as_ptr(),
355 padding.0,
356 ))?;
357 Ok(len as usize)
358 }
359 }
360
361 pub fn public_encrypt(
367 &self,
368 from: &[u8],
369 to: &mut [u8],
370 padding: Padding,
371 ) -> Result<usize, ErrorStack> {
372 assert!(from.len() <= i32::MAX as usize);
373 assert!(to.len() >= self.size() as usize);
374
375 unsafe {
376 let len = cvt_n(ffi::RSA_public_encrypt(
377 from.len(),
378 from.as_ptr(),
379 to.as_mut_ptr(),
380 self.as_ptr(),
381 padding.0,
382 ))?;
383 Ok(len as usize)
384 }
385 }
386
387 #[corresponds(RSA_get0_key)]
389 #[must_use]
390 pub fn n(&self) -> &BigNumRef {
391 unsafe {
392 let mut n = ptr::null();
393 RSA_get0_key(self.as_ptr(), &mut n, ptr::null_mut(), ptr::null_mut());
394 BigNumRef::from_ptr(n.cast_mut())
395 }
396 }
397
398 #[corresponds(RSA_get0_key)]
400 #[must_use]
401 pub fn e(&self) -> &BigNumRef {
402 unsafe {
403 let mut e = ptr::null();
404 RSA_get0_key(self.as_ptr(), ptr::null_mut(), &mut e, ptr::null_mut());
405 BigNumRef::from_ptr(e.cast_mut())
406 }
407 }
408}
409
410impl Rsa<Public> {
411 #[corresponds(RSA_new)]
416 pub fn from_public_components(n: BigNum, e: BigNum) -> Result<Rsa<Public>, ErrorStack> {
417 unsafe {
418 let rsa = cvt_p(ffi::RSA_new())?;
419 cvt(RSA_set0_key(rsa, n.as_ptr(), e.as_ptr(), ptr::null_mut()))?;
420 mem::forget((n, e));
421 Ok(Rsa::from_ptr(rsa))
422 }
423 }
424
425 from_pem! {
426 #[corresponds(PEM_read_bio_RSA_PUBKEY)]
430 public_key_from_pem,
431 Rsa<Public>,
432 ffi::PEM_read_bio_RSA_PUBKEY
433 }
434
435 from_pem! {
436 #[corresponds(PEM_read_bio_RSAPublicKey)]
440 public_key_from_pem_pkcs1,
441 Rsa<Public>,
442 ffi::PEM_read_bio_RSAPublicKey
443 }
444
445 from_der! {
446 #[corresponds(d2i_RSA_PUBKEY)]
448 public_key_from_der,
449 Rsa<Public>,
450 ffi::d2i_RSA_PUBKEY,
451 crate::libc_types::c_long
452 }
453
454 from_der! {
455 #[corresponds(d2i_RSAPublicKey)]
457 public_key_from_der_pkcs1,
458 Rsa<Public>,
459 ffi::d2i_RSAPublicKey,
460 crate::libc_types::c_long
461 }
462}
463
464pub struct RsaPrivateKeyBuilder {
465 rsa: Rsa<Private>,
466}
467
468impl RsaPrivateKeyBuilder {
469 #[corresponds(RSA_new)]
474 pub fn new(n: BigNum, e: BigNum, d: BigNum) -> Result<RsaPrivateKeyBuilder, ErrorStack> {
475 unsafe {
476 let rsa = cvt_p(ffi::RSA_new())?;
477 cvt(RSA_set0_key(rsa, n.as_ptr(), e.as_ptr(), d.as_ptr()))?;
478 mem::forget((n, e, d));
479 Ok(RsaPrivateKeyBuilder {
480 rsa: Rsa::from_ptr(rsa),
481 })
482 }
483 }
484
485 #[corresponds(RSA_set0_factors)]
491 pub fn set_factors(self, p: BigNum, q: BigNum) -> Result<RsaPrivateKeyBuilder, ErrorStack> {
492 unsafe {
493 cvt(RSA_set0_factors(self.rsa.as_ptr(), p.as_ptr(), q.as_ptr()))?;
494 mem::forget((p, q));
495 }
496 Ok(self)
497 }
498
499 #[corresponds(RSA_set0_crt_params)]
504 pub fn set_crt_params(
505 self,
506 dmp1: BigNum,
507 dmq1: BigNum,
508 iqmp: BigNum,
509 ) -> Result<RsaPrivateKeyBuilder, ErrorStack> {
510 unsafe {
511 cvt(RSA_set0_crt_params(
512 self.rsa.as_ptr(),
513 dmp1.as_ptr(),
514 dmq1.as_ptr(),
515 iqmp.as_ptr(),
516 ))?;
517 mem::forget((dmp1, dmq1, iqmp));
518 }
519 Ok(self)
520 }
521
522 #[must_use]
524 pub fn build(self) -> Rsa<Private> {
525 self.rsa
526 }
527}
528
529impl Rsa<Private> {
530 #[allow(clippy::too_many_arguments, clippy::many_single_char_names)]
535 pub fn from_private_components(
536 n: BigNum,
537 e: BigNum,
538 d: BigNum,
539 p: BigNum,
540 q: BigNum,
541 dmp1: BigNum,
542 dmq1: BigNum,
543 iqmp: BigNum,
544 ) -> Result<Rsa<Private>, ErrorStack> {
545 Ok(RsaPrivateKeyBuilder::new(n, e, d)?
546 .set_factors(p, q)?
547 .set_crt_params(dmp1, dmq1, iqmp)?
548 .build())
549 }
550
551 #[corresponds(RSA_generate_key_ex)]
555 pub fn generate(bits: u32) -> Result<Rsa<Private>, ErrorStack> {
556 let e = BigNum::from_u32(ffi::RSA_F4 as u32)?;
557 Rsa::generate_with_e(bits, &e)
558 }
559
560 #[corresponds(RSA_generate_key_ex)]
564 pub fn generate_with_e(bits: u32, e: &BigNumRef) -> Result<Rsa<Private>, ErrorStack> {
565 unsafe {
566 let rsa = Rsa::from_ptr(cvt_p(ffi::RSA_new())?);
567 cvt(ffi::RSA_generate_key_ex(
568 rsa.0,
569 bits as c_int,
570 e.as_ptr(),
571 ptr::null_mut(),
572 ))?;
573 Ok(rsa)
574 }
575 }
576
577 private_key_from_pem! {
579 #[corresponds(PEM_read_bio_RSAPrivateKey)]
581 private_key_from_pem,
582
583 #[corresponds(PEM_read_bio_RSAPrivateKey)]
585 private_key_from_pem_passphrase,
586
587 #[corresponds(PEM_read_bio_RSAPrivateKey)]
591 private_key_from_pem_callback,
592 Rsa<Private>,
593 ffi::PEM_read_bio_RSAPrivateKey
594 }
595
596 from_der! {
597 #[corresponds(d2i_RSAPrivateKey)]
599 private_key_from_der,
600 Rsa<Private>,
601 ffi::d2i_RSAPrivateKey,
602 crate::libc_types::c_long
603 }
604}
605
606impl<T> fmt::Debug for Rsa<T> {
607 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
608 write!(f, "Rsa")
609 }
610}
611
612use crate::ffi::{
613 RSA_get0_crt_params, RSA_get0_factors, RSA_get0_key, RSA_set0_crt_params, RSA_set0_factors,
614 RSA_set0_key,
615};
616
617#[cfg(test)]
618mod test {
619 use crate::symm::Cipher;
620
621 use super::*;
622
623 #[test]
624 fn test_from_password() {
625 let key = include_bytes!("../test/rsa-encrypted.pem");
626 Rsa::private_key_from_pem_passphrase(key, b"mypass").unwrap();
627 }
628
629 #[test]
630 fn test_from_password_callback() {
631 let mut password_queried = false;
632 let key = include_bytes!("../test/rsa-encrypted.pem");
633 Rsa::private_key_from_pem_callback(key, |password| {
634 password_queried = true;
635 password[..6].copy_from_slice(b"mypass");
636 Ok(6)
637 })
638 .unwrap();
639
640 assert!(password_queried);
641 }
642
643 #[test]
644 fn test_to_password() {
645 let key = Rsa::generate(2048).unwrap();
646 let pem = key
647 .private_key_to_pem_passphrase(Cipher::aes_128_cbc(), b"foobar")
648 .unwrap();
649 Rsa::private_key_from_pem_passphrase(&pem, b"foobar").unwrap();
650 assert!(Rsa::private_key_from_pem_passphrase(&pem, b"fizzbuzz").is_err());
651 }
652
653 #[test]
654 fn test_public_encrypt_private_decrypt_with_padding() {
655 let key = include_bytes!("../test/rsa.pem.pub");
656 let public_key = Rsa::public_key_from_pem(key).unwrap();
657
658 let mut result = vec![0; public_key.size() as usize];
659 let original_data = b"This is test";
660 let len = public_key
661 .public_encrypt(original_data, &mut result, Padding::PKCS1)
662 .unwrap();
663 assert_eq!(len, 256);
664
665 let pkey = include_bytes!("../test/rsa.pem");
666 let private_key = Rsa::private_key_from_pem(pkey).unwrap();
667 let mut dec_result = vec![0; private_key.size() as usize];
668 let len = private_key
669 .private_decrypt(&result, &mut dec_result, Padding::PKCS1)
670 .unwrap();
671
672 assert_eq!(&dec_result[..len], original_data);
673 }
674
675 #[test]
676 fn test_private_encrypt() {
677 let k0 = super::Rsa::generate(512).unwrap();
678 let k0pkey = k0.public_key_to_pem().unwrap();
679 let k1 = super::Rsa::public_key_from_pem(&k0pkey).unwrap();
680
681 let msg = vec![0xdeu8, 0xadu8, 0xd0u8, 0x0du8];
682
683 let mut emesg = vec![0; k0.size() as usize];
684 k0.private_encrypt(&msg, &mut emesg, Padding::PKCS1)
685 .unwrap();
686 let mut dmesg = vec![0; k1.size() as usize];
687 let len = k1
688 .public_decrypt(&emesg, &mut dmesg, Padding::PKCS1)
689 .unwrap();
690 assert_eq!(msg, &dmesg[..len]);
691 }
692
693 #[test]
694 fn test_public_encrypt() {
695 let k0 = super::Rsa::generate(512).unwrap();
696 let k0pkey = k0.private_key_to_pem().unwrap();
697 let k1 = super::Rsa::private_key_from_pem(&k0pkey).unwrap();
698
699 let msg = vec![0xdeu8, 0xadu8, 0xd0u8, 0x0du8];
700
701 let mut emesg = vec![0; k0.size() as usize];
702 k0.public_encrypt(&msg, &mut emesg, Padding::PKCS1).unwrap();
703 let mut dmesg = vec![0; k1.size() as usize];
704 let len = k1
705 .private_decrypt(&emesg, &mut dmesg, Padding::PKCS1)
706 .unwrap();
707 assert_eq!(msg, &dmesg[..len]);
708 }
709
710 #[test]
711 fn test_public_key_from_pem_pkcs1() {
712 let key = include_bytes!("../test/pkcs1.pem.pub");
713 Rsa::public_key_from_pem_pkcs1(key).unwrap();
714 }
715
716 #[test]
717 #[should_panic]
718 fn test_public_key_from_pem_pkcs1_file_panic() {
719 let key = include_bytes!("../test/key.pem.pub");
720 Rsa::public_key_from_pem_pkcs1(key).unwrap();
721 }
722
723 #[test]
724 fn test_public_key_to_pem_pkcs1() {
725 let keypair = super::Rsa::generate(512).unwrap();
726 let pubkey_pem = keypair.public_key_to_pem_pkcs1().unwrap();
727 super::Rsa::public_key_from_pem_pkcs1(&pubkey_pem).unwrap();
728 }
729
730 #[test]
731 #[should_panic]
732 fn test_public_key_from_pem_pkcs1_generate_panic() {
733 let keypair = super::Rsa::generate(512).unwrap();
734 let pubkey_pem = keypair.public_key_to_pem().unwrap();
735 super::Rsa::public_key_from_pem_pkcs1(&pubkey_pem).unwrap();
736 }
737
738 #[test]
739 fn test_pem_pkcs1_encrypt() {
740 let keypair = super::Rsa::generate(2048).unwrap();
741 let pubkey_pem = keypair.public_key_to_pem_pkcs1().unwrap();
742 let pubkey = super::Rsa::public_key_from_pem_pkcs1(&pubkey_pem).unwrap();
743 let msg = b"Hello, world!";
744
745 let mut encrypted = vec![0; pubkey.size() as usize];
746 let len = pubkey
747 .public_encrypt(msg, &mut encrypted, Padding::PKCS1)
748 .unwrap();
749 assert!(len > msg.len());
750 let mut decrypted = vec![0; keypair.size() as usize];
751 let len = keypair
752 .private_decrypt(&encrypted, &mut decrypted, Padding::PKCS1)
753 .unwrap();
754 assert_eq!(len, msg.len());
755 assert_eq!(&decrypted[..len], msg);
756 }
757
758 #[test]
759 fn test_pem_pkcs1_padding() {
760 let keypair = super::Rsa::generate(2048).unwrap();
761 let pubkey_pem = keypair.public_key_to_pem_pkcs1().unwrap();
762 let pubkey = super::Rsa::public_key_from_pem_pkcs1(&pubkey_pem).unwrap();
763 let msg = b"foo";
764
765 let mut encrypted1 = vec![0; pubkey.size() as usize];
766 let mut encrypted2 = vec![0; pubkey.size() as usize];
767 let len1 = pubkey
768 .public_encrypt(msg, &mut encrypted1, Padding::PKCS1)
769 .unwrap();
770 let len2 = pubkey
771 .public_encrypt(msg, &mut encrypted2, Padding::PKCS1)
772 .unwrap();
773 assert!(len1 > (msg.len() + 1));
774 assert_eq!(len1, len2);
775 assert_ne!(encrypted1, encrypted2);
776 }
777
778 #[test]
779 #[allow(clippy::redundant_clone)]
780 fn clone() {
781 let key = Rsa::generate(2048).unwrap();
782 drop(key.clone());
783 }
784
785 #[test]
786 fn generate_with_e() {
787 let e = BigNum::from_u32(0x10001).unwrap();
788 Rsa::generate_with_e(2048, &e).unwrap();
789 }
790}