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