1use foreign_types::{ForeignType, ForeignTypeRef};
27use libc::c_int;
28use std::fmt;
29use std::mem;
30use std::ptr;
31
32use crate::bn::{BigNum, BigNumRef};
33use crate::error::ErrorStack;
34use crate::pkey::{HasPrivate, HasPublic, Private, Public};
35use crate::util::ForeignTypeRefExt;
36use crate::{cvt, cvt_n, cvt_p, LenType};
37use openssl_macros::corresponds;
38
39#[derive(Debug, Copy, Clone, PartialEq, Eq)]
45pub struct Padding(c_int);
46
47impl Padding {
48 pub const NONE: Padding = Padding(ffi::RSA_NO_PADDING);
49 pub const PKCS1: Padding = Padding(ffi::RSA_PKCS1_PADDING);
50 pub const PKCS1_OAEP: Padding = Padding(ffi::RSA_PKCS1_OAEP_PADDING);
51 pub const PKCS1_PSS: Padding = Padding(ffi::RSA_PKCS1_PSS_PADDING);
52
53 pub fn from_raw(value: c_int) -> Padding {
55 Padding(value)
56 }
57
58 #[allow(clippy::trivially_copy_pass_by_ref)]
60 pub fn as_raw(&self) -> c_int {
61 self.0
62 }
63}
64
65generic_foreign_type_and_impl_send_sync! {
66 type CType = ffi::RSA;
67 fn drop = ffi::RSA_free;
68
69 pub struct Rsa<T>;
71
72 pub struct RsaRef<T>;
74}
75
76impl<T> Clone for Rsa<T> {
77 fn clone(&self) -> Rsa<T> {
78 (**self).to_owned()
79 }
80}
81
82impl<T> ToOwned for RsaRef<T> {
83 type Owned = Rsa<T>;
84
85 fn to_owned(&self) -> Rsa<T> {
86 unsafe {
87 ffi::RSA_up_ref(self.as_ptr());
88 Rsa::from_ptr(self.as_ptr())
89 }
90 }
91}
92
93impl<T> RsaRef<T>
94where
95 T: HasPrivate,
96{
97 private_key_to_pem! {
98 #[corresponds(PEM_write_bio_RSAPrivateKey)]
102 private_key_to_pem,
103 #[corresponds(PEM_write_bio_RSAPrivateKey)]
107 private_key_to_pem_passphrase,
108 ffi::PEM_write_bio_RSAPrivateKey
109 }
110
111 to_der! {
112 #[corresponds(i2d_RSAPrivateKey)]
114 private_key_to_der,
115 ffi::i2d_RSAPrivateKey
116 }
117
118 #[corresponds(RSA_private_decrypt)]
125 pub fn private_decrypt(
126 &self,
127 from: &[u8],
128 to: &mut [u8],
129 padding: Padding,
130 ) -> Result<usize, ErrorStack> {
131 assert!(from.len() <= i32::MAX as usize);
132 assert!(to.len() >= self.size() as usize);
133
134 unsafe {
135 let len = cvt_n(ffi::RSA_private_decrypt(
136 from.len() as LenType,
137 from.as_ptr(),
138 to.as_mut_ptr(),
139 self.as_ptr(),
140 padding.0,
141 ))?;
142 Ok(len as usize)
143 }
144 }
145
146 #[corresponds(RSA_private_encrypt)]
153 pub fn private_encrypt(
154 &self,
155 from: &[u8],
156 to: &mut [u8],
157 padding: Padding,
158 ) -> Result<usize, ErrorStack> {
159 assert!(from.len() <= i32::MAX as usize);
160 assert!(to.len() >= self.size() as usize);
161
162 unsafe {
163 let len = cvt_n(ffi::RSA_private_encrypt(
164 from.len() as LenType,
165 from.as_ptr(),
166 to.as_mut_ptr(),
167 self.as_ptr(),
168 padding.0,
169 ))?;
170 Ok(len as usize)
171 }
172 }
173
174 #[corresponds(RSA_get0_key)]
176 pub fn d(&self) -> &BigNumRef {
177 unsafe {
178 let mut d = ptr::null();
179 RSA_get0_key(self.as_ptr(), ptr::null_mut(), ptr::null_mut(), &mut d);
180 BigNumRef::from_const_ptr(d)
181 }
182 }
183
184 #[corresponds(RSA_get0_factors)]
186 pub fn p(&self) -> Option<&BigNumRef> {
187 unsafe {
188 let mut p = ptr::null();
189 RSA_get0_factors(self.as_ptr(), &mut p, ptr::null_mut());
190 BigNumRef::from_const_ptr_opt(p)
191 }
192 }
193
194 #[corresponds(RSA_get0_factors)]
196 pub fn q(&self) -> Option<&BigNumRef> {
197 unsafe {
198 let mut q = ptr::null();
199 RSA_get0_factors(self.as_ptr(), ptr::null_mut(), &mut q);
200 BigNumRef::from_const_ptr_opt(q)
201 }
202 }
203
204 #[corresponds(RSA_get0_crt_params)]
206 pub fn dmp1(&self) -> Option<&BigNumRef> {
207 unsafe {
208 let mut dp = ptr::null();
209 RSA_get0_crt_params(self.as_ptr(), &mut dp, ptr::null_mut(), ptr::null_mut());
210 BigNumRef::from_const_ptr_opt(dp)
211 }
212 }
213
214 #[corresponds(RSA_get0_crt_params)]
216 pub fn dmq1(&self) -> Option<&BigNumRef> {
217 unsafe {
218 let mut dq = ptr::null();
219 RSA_get0_crt_params(self.as_ptr(), ptr::null_mut(), &mut dq, ptr::null_mut());
220 BigNumRef::from_const_ptr_opt(dq)
221 }
222 }
223
224 #[corresponds(RSA_get0_crt_params)]
226 pub fn iqmp(&self) -> Option<&BigNumRef> {
227 unsafe {
228 let mut qi = ptr::null();
229 RSA_get0_crt_params(self.as_ptr(), ptr::null_mut(), ptr::null_mut(), &mut qi);
230 BigNumRef::from_const_ptr_opt(qi)
231 }
232 }
233
234 #[corresponds(RSA_check_key)]
236 pub fn check_key(&self) -> Result<bool, ErrorStack> {
237 unsafe {
238 let result = ffi::RSA_check_key(self.as_ptr());
239 if result != 1 {
240 let errors = ErrorStack::get();
241 if errors.errors().is_empty() {
242 Ok(false)
243 } else {
244 Err(errors)
245 }
246 } else {
247 Ok(true)
248 }
249 }
250 }
251}
252
253impl<T> RsaRef<T>
254where
255 T: HasPublic,
256{
257 to_pem! {
258 #[corresponds(PEM_write_bio_RSA_PUBKEY)]
262 public_key_to_pem,
263 ffi::PEM_write_bio_RSA_PUBKEY
264 }
265
266 to_der! {
267 #[corresponds(i2d_RSA_PUBKEY)]
269 public_key_to_der,
270 ffi::i2d_RSA_PUBKEY
271 }
272
273 to_pem! {
274 #[corresponds(PEM_write_bio_RSAPublicKey)]
278 public_key_to_pem_pkcs1,
279 ffi::PEM_write_bio_RSAPublicKey
280 }
281
282 to_der! {
283 #[corresponds(i2d_RSAPublicKey)]
285 public_key_to_der_pkcs1,
286 ffi::i2d_RSAPublicKey
287 }
288
289 #[corresponds(RSA_size)]
291 pub fn size(&self) -> u32 {
292 unsafe { ffi::RSA_size(self.as_ptr()) as u32 }
293 }
294
295 #[corresponds(RSA_public_decrypt)]
301 pub fn public_decrypt(
302 &self,
303 from: &[u8],
304 to: &mut [u8],
305 padding: Padding,
306 ) -> Result<usize, ErrorStack> {
307 assert!(from.len() <= i32::MAX as usize);
308 assert!(to.len() >= self.size() as usize);
309
310 unsafe {
311 let len = cvt_n(ffi::RSA_public_decrypt(
312 from.len() as LenType,
313 from.as_ptr(),
314 to.as_mut_ptr(),
315 self.as_ptr(),
316 padding.0,
317 ))?;
318 Ok(len as usize)
319 }
320 }
321
322 #[corresponds(RSA_public_encrypt)]
328 pub fn public_encrypt(
329 &self,
330 from: &[u8],
331 to: &mut [u8],
332 padding: Padding,
333 ) -> Result<usize, ErrorStack> {
334 assert!(from.len() <= i32::MAX as usize);
335 assert!(to.len() >= self.size() as usize);
336
337 unsafe {
338 let len = cvt_n(ffi::RSA_public_encrypt(
339 from.len() as LenType,
340 from.as_ptr(),
341 to.as_mut_ptr(),
342 self.as_ptr(),
343 padding.0,
344 ))?;
345 Ok(len as usize)
346 }
347 }
348
349 #[corresponds(RSA_get0_key)]
351 pub fn n(&self) -> &BigNumRef {
352 unsafe {
353 let mut n = ptr::null();
354 RSA_get0_key(self.as_ptr(), &mut n, ptr::null_mut(), ptr::null_mut());
355 BigNumRef::from_const_ptr(n)
356 }
357 }
358
359 #[corresponds(RSA_get0_key)]
361 pub fn e(&self) -> &BigNumRef {
362 unsafe {
363 let mut e = ptr::null();
364 RSA_get0_key(self.as_ptr(), ptr::null_mut(), &mut e, ptr::null_mut());
365 BigNumRef::from_const_ptr(e)
366 }
367 }
368}
369
370impl Rsa<Public> {
371 pub fn from_public_components(n: BigNum, e: BigNum) -> Result<Rsa<Public>, ErrorStack> {
381 unsafe {
382 let rsa = cvt_p(ffi::RSA_new())?;
383 RSA_set0_key(rsa, n.as_ptr(), e.as_ptr(), ptr::null_mut());
384 mem::forget((n, e));
385 Ok(Rsa::from_ptr(rsa))
386 }
387 }
388
389 from_pem! {
390 #[corresponds(PEM_read_bio_RSA_PUBKEY)]
394 public_key_from_pem,
395 Rsa<Public>,
396 ffi::PEM_read_bio_RSA_PUBKEY
397 }
398
399 from_pem! {
400 #[corresponds(PEM_read_bio_RSAPublicKey)]
404 public_key_from_pem_pkcs1,
405 Rsa<Public>,
406 ffi::PEM_read_bio_RSAPublicKey
407 }
408
409 from_der! {
410 #[corresponds(d2i_RSA_PUBKEY)]
412 public_key_from_der,
413 Rsa<Public>,
414 ffi::d2i_RSA_PUBKEY
415 }
416
417 from_der! {
418 #[corresponds(d2i_RSAPublicKey)]
420 public_key_from_der_pkcs1,
421 Rsa<Public>,
422 ffi::d2i_RSAPublicKey
423 }
424}
425
426pub struct RsaPrivateKeyBuilder {
427 rsa: Rsa<Private>,
428}
429
430impl RsaPrivateKeyBuilder {
431 pub fn new(n: BigNum, e: BigNum, d: BigNum) -> Result<RsaPrivateKeyBuilder, ErrorStack> {
441 unsafe {
442 let rsa = cvt_p(ffi::RSA_new())?;
443 RSA_set0_key(rsa, n.as_ptr(), e.as_ptr(), d.as_ptr());
444 mem::forget((n, e, d));
445 Ok(RsaPrivateKeyBuilder {
446 rsa: Rsa::from_ptr(rsa),
447 })
448 }
449 }
450
451 #[corresponds(RSA_set0_factors)]
455 pub fn set_factors(self, p: BigNum, q: BigNum) -> Result<RsaPrivateKeyBuilder, ErrorStack> {
457 unsafe {
458 RSA_set0_factors(self.rsa.as_ptr(), p.as_ptr(), q.as_ptr());
459 mem::forget((p, q));
460 }
461 Ok(self)
462 }
463
464 #[corresponds(RSA_set0_crt_params)]
469 pub fn set_crt_params(
471 self,
472 dmp1: BigNum,
473 dmq1: BigNum,
474 iqmp: BigNum,
475 ) -> Result<RsaPrivateKeyBuilder, ErrorStack> {
476 unsafe {
477 RSA_set0_crt_params(
478 self.rsa.as_ptr(),
479 dmp1.as_ptr(),
480 dmq1.as_ptr(),
481 iqmp.as_ptr(),
482 );
483 mem::forget((dmp1, dmq1, iqmp));
484 }
485 Ok(self)
486 }
487
488 pub fn build(self) -> Rsa<Private> {
490 self.rsa
491 }
492}
493
494impl Rsa<Private> {
495 #[allow(clippy::too_many_arguments, clippy::many_single_char_names)]
510 pub fn from_private_components(
511 n: BigNum,
512 e: BigNum,
513 d: BigNum,
514 p: BigNum,
515 q: BigNum,
516 dmp1: BigNum,
517 dmq1: BigNum,
518 iqmp: BigNum,
519 ) -> Result<Rsa<Private>, ErrorStack> {
520 Ok(RsaPrivateKeyBuilder::new(n, e, d)?
521 .set_factors(p, q)?
522 .set_crt_params(dmp1, dmq1, iqmp)?
523 .build())
524 }
525
526 #[corresponds(RSA_generate_key_ex)]
530 pub fn generate(bits: u32) -> Result<Rsa<Private>, ErrorStack> {
531 let e = BigNum::from_u32(ffi::RSA_F4 as u32)?;
532 Rsa::generate_with_e(bits, &e)
533 }
534
535 #[corresponds(RSA_generate_key_ex)]
539 pub fn generate_with_e(bits: u32, e: &BigNumRef) -> Result<Rsa<Private>, ErrorStack> {
540 unsafe {
541 let rsa = Rsa::from_ptr(cvt_p(ffi::RSA_new())?);
542 cvt(ffi::RSA_generate_key_ex(
543 rsa.0,
544 bits as c_int,
545 e.as_ptr(),
546 ptr::null_mut(),
547 ))?;
548 Ok(rsa)
549 }
550 }
551
552 private_key_from_pem! {
554 #[corresponds(PEM_read_bio_RSAPrivateKey)]
556 private_key_from_pem,
557
558 #[corresponds(PEM_read_bio_RSAPrivateKey)]
560 private_key_from_pem_passphrase,
561
562 #[corresponds(PEM_read_bio_RSAPrivateKey)]
566 private_key_from_pem_callback,
567 Rsa<Private>,
568 ffi::PEM_read_bio_RSAPrivateKey
569 }
570
571 from_der! {
572 #[corresponds(d2i_RSAPrivateKey)]
574 private_key_from_der,
575 Rsa<Private>,
576 ffi::d2i_RSAPrivateKey
577 }
578}
579
580impl<T> fmt::Debug for Rsa<T> {
581 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
582 write!(f, "Rsa")
583 }
584}
585
586use ffi::{
587 RSA_get0_crt_params, RSA_get0_factors, RSA_get0_key, RSA_set0_crt_params, RSA_set0_factors,
588 RSA_set0_key,
589};
590
591#[cfg(test)]
592mod test {
593 use crate::symm::Cipher;
594
595 use super::*;
596
597 #[test]
598 fn test_from_password() {
599 let key = include_bytes!("../test/rsa-encrypted.pem");
600 Rsa::private_key_from_pem_passphrase(key, b"mypass").unwrap();
601 }
602
603 #[test]
604 fn test_from_password_callback() {
605 let mut password_queried = false;
606 let key = include_bytes!("../test/rsa-encrypted.pem");
607 Rsa::private_key_from_pem_callback(key, |password| {
608 password_queried = true;
609 password[..6].copy_from_slice(b"mypass");
610 Ok(6)
611 })
612 .unwrap();
613
614 assert!(password_queried);
615 }
616
617 #[test]
618 fn test_to_password() {
619 let key = Rsa::generate(2048).unwrap();
620 let pem = key
621 .private_key_to_pem_passphrase(Cipher::aes_128_cbc(), b"foobar")
622 .unwrap();
623 Rsa::private_key_from_pem_passphrase(&pem, b"foobar").unwrap();
624 assert!(Rsa::private_key_from_pem_passphrase(&pem, b"fizzbuzz").is_err());
625 }
626
627 #[test]
628 fn test_public_encrypt_private_decrypt_with_padding() {
629 let key = include_bytes!("../test/rsa.pem.pub");
630 let public_key = Rsa::public_key_from_pem(key).unwrap();
631
632 let mut result = vec![0; public_key.size() as usize];
633 let original_data = b"This is test";
634 let len = public_key
635 .public_encrypt(original_data, &mut result, Padding::PKCS1)
636 .unwrap();
637 assert_eq!(len, 256);
638
639 let pkey = include_bytes!("../test/rsa.pem");
640 let private_key = Rsa::private_key_from_pem(pkey).unwrap();
641 let mut dec_result = vec![0; private_key.size() as usize];
642 let len = private_key
643 .private_decrypt(&result, &mut dec_result, Padding::PKCS1)
644 .unwrap();
645
646 assert_eq!(&dec_result[..len], original_data);
647 }
648
649 #[test]
650 fn test_private_encrypt() {
651 let k0 = super::Rsa::generate(512).unwrap();
652 let k0pkey = k0.public_key_to_pem().unwrap();
653 let k1 = super::Rsa::public_key_from_pem(&k0pkey).unwrap();
654
655 let msg = vec![0xdeu8, 0xadu8, 0xd0u8, 0x0du8];
656
657 let mut emesg = vec![0; k0.size() as usize];
658 k0.private_encrypt(&msg, &mut emesg, Padding::PKCS1)
659 .unwrap();
660 let mut dmesg = vec![0; k1.size() as usize];
661 let len = k1
662 .public_decrypt(&emesg, &mut dmesg, Padding::PKCS1)
663 .unwrap();
664 assert_eq!(msg, &dmesg[..len]);
665 }
666
667 #[test]
668 fn test_public_encrypt() {
669 let k0 = super::Rsa::generate(512).unwrap();
670 let k0pkey = k0.private_key_to_pem().unwrap();
671 let k1 = super::Rsa::private_key_from_pem(&k0pkey).unwrap();
672
673 let msg = vec![0xdeu8, 0xadu8, 0xd0u8, 0x0du8];
674
675 let mut emesg = vec![0; k0.size() as usize];
676 k0.public_encrypt(&msg, &mut emesg, Padding::PKCS1).unwrap();
677 let mut dmesg = vec![0; k1.size() as usize];
678 let len = k1
679 .private_decrypt(&emesg, &mut dmesg, Padding::PKCS1)
680 .unwrap();
681 assert_eq!(msg, &dmesg[..len]);
682 }
683
684 #[test]
685 fn test_public_key_from_pem_pkcs1() {
686 let key = include_bytes!("../test/pkcs1.pem.pub");
687 Rsa::public_key_from_pem_pkcs1(key).unwrap();
688 }
689
690 #[test]
691 #[should_panic]
692 fn test_public_key_from_pem_pkcs1_file_panic() {
693 let key = include_bytes!("../test/key.pem.pub");
694 Rsa::public_key_from_pem_pkcs1(key).unwrap();
695 }
696
697 #[test]
698 fn test_public_key_to_pem_pkcs1() {
699 let keypair = super::Rsa::generate(512).unwrap();
700 let pubkey_pem = keypair.public_key_to_pem_pkcs1().unwrap();
701 super::Rsa::public_key_from_pem_pkcs1(&pubkey_pem).unwrap();
702 }
703
704 #[test]
705 #[should_panic]
706 fn test_public_key_from_pem_pkcs1_generate_panic() {
707 let keypair = super::Rsa::generate(512).unwrap();
708 let pubkey_pem = keypair.public_key_to_pem().unwrap();
709 super::Rsa::public_key_from_pem_pkcs1(&pubkey_pem).unwrap();
710 }
711
712 #[test]
713 fn test_pem_pkcs1_encrypt() {
714 let keypair = super::Rsa::generate(2048).unwrap();
715 let pubkey_pem = keypair.public_key_to_pem_pkcs1().unwrap();
716 let pubkey = super::Rsa::public_key_from_pem_pkcs1(&pubkey_pem).unwrap();
717 let msg = b"Hello, world!";
718
719 let mut encrypted = vec![0; pubkey.size() as usize];
720 let len = pubkey
721 .public_encrypt(msg, &mut encrypted, Padding::PKCS1)
722 .unwrap();
723 assert!(len > msg.len());
724 let mut decrypted = vec![0; keypair.size() as usize];
725 let len = keypair
726 .private_decrypt(&encrypted, &mut decrypted, Padding::PKCS1)
727 .unwrap();
728 assert_eq!(len, msg.len());
729 assert_eq!(&decrypted[..len], msg);
730 }
731
732 #[test]
733 fn test_pem_pkcs1_padding() {
734 let keypair = super::Rsa::generate(2048).unwrap();
735 let pubkey_pem = keypair.public_key_to_pem_pkcs1().unwrap();
736 let pubkey = super::Rsa::public_key_from_pem_pkcs1(&pubkey_pem).unwrap();
737 let msg = b"foo";
738
739 let mut encrypted1 = vec![0; pubkey.size() as usize];
740 let mut encrypted2 = vec![0; pubkey.size() as usize];
741 let len1 = pubkey
742 .public_encrypt(msg, &mut encrypted1, Padding::PKCS1)
743 .unwrap();
744 let len2 = pubkey
745 .public_encrypt(msg, &mut encrypted2, Padding::PKCS1)
746 .unwrap();
747 assert!(len1 > (msg.len() + 1));
748 assert_eq!(len1, len2);
749 assert_ne!(encrypted1, encrypted2);
750 }
751
752 #[test]
753 #[allow(clippy::redundant_clone)]
754 fn clone() {
755 let key = Rsa::generate(2048).unwrap();
756 drop(key.clone());
757 }
758
759 #[test]
760 fn generate_with_e() {
761 let e = BigNum::from_u32(0x10001).unwrap();
762 Rsa::generate_with_e(2048, &e).unwrap();
763 }
764
765 #[test]
766 fn test_check_key() {
767 let k = Rsa::private_key_from_pem_passphrase(
768 include_bytes!("../test/rsa-encrypted.pem"),
769 b"mypass",
770 )
771 .unwrap();
772 assert!(matches!(k.check_key(), Ok(true)));
773 assert!(ErrorStack::get().errors().is_empty());
774
775 if let Ok(k) = Rsa::private_key_from_pem(include_bytes!("../test/corrupted-rsa.pem")) {
777 assert!(matches!(k.check_key(), Ok(false) | Err(_)));
778 assert!(ErrorStack::get().errors().is_empty());
779 }
780 }
781}