1use crate::ffi;
27use foreign_types::{ForeignType, ForeignTypeRef};
28use libc::c_int;
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 pub fn from_raw(value: c_int) -> Padding {
71 Padding(value)
72 }
73
74 #[allow(clippy::trivially_copy_pass_by_ref)]
76 pub fn as_raw(&self) -> c_int {
77 self.0
78 }
79}
80
81generic_foreign_type_and_impl_send_sync! {
82 type CType = ffi::RSA;
83 fn drop = ffi::RSA_free;
84
85 pub struct Rsa<T>;
87
88 pub struct RsaRef<T>;
90}
91
92impl<T> Clone for Rsa<T> {
93 fn clone(&self) -> Rsa<T> {
94 (**self).to_owned()
95 }
96}
97
98impl<T> ToOwned for RsaRef<T> {
99 type Owned = Rsa<T>;
100
101 fn to_owned(&self) -> Rsa<T> {
102 unsafe {
103 ffi::RSA_up_ref(self.as_ptr());
104 Rsa::from_ptr(self.as_ptr())
105 }
106 }
107}
108
109impl<T> RsaRef<T>
110where
111 T: HasPrivate,
112{
113 private_key_to_pem! {
114 #[corresponds(PEM_write_bio_RSAPrivateKey)]
118 private_key_to_pem,
119 #[corresponds(PEM_write_bio_RSAPrivateKey)]
123 private_key_to_pem_passphrase,
124 ffi::PEM_write_bio_RSAPrivateKey
125 }
126
127 to_der! {
128 #[corresponds(i2d_RSAPrivateKey)]
130 private_key_to_der,
131 ffi::i2d_RSAPrivateKey
132 }
133
134 pub fn private_decrypt(
141 &self,
142 from: &[u8],
143 to: &mut [u8],
144 padding: Padding,
145 ) -> Result<usize, ErrorStack> {
146 assert!(from.len() <= i32::MAX as usize);
147 assert!(to.len() >= self.size() as usize);
148
149 unsafe {
150 let len = cvt_n(ffi::RSA_private_decrypt(
151 from.len(),
152 from.as_ptr(),
153 to.as_mut_ptr(),
154 self.as_ptr(),
155 padding.0,
156 ))?;
157 Ok(len as usize)
158 }
159 }
160
161 pub fn private_encrypt(
168 &self,
169 from: &[u8],
170 to: &mut [u8],
171 padding: Padding,
172 ) -> Result<usize, ErrorStack> {
173 assert!(from.len() <= i32::MAX as usize);
174 assert!(to.len() >= self.size() as usize);
175
176 unsafe {
177 let len = cvt_n(ffi::RSA_private_encrypt(
178 from.len(),
179 from.as_ptr(),
180 to.as_mut_ptr(),
181 self.as_ptr(),
182 padding.0,
183 ))?;
184 Ok(len as usize)
185 }
186 }
187
188 #[corresponds(RSA_get0_key)]
190 pub fn d(&self) -> &BigNumRef {
191 unsafe {
192 let mut d = ptr::null();
193 RSA_get0_key(self.as_ptr(), ptr::null_mut(), ptr::null_mut(), &mut d);
194 BigNumRef::from_ptr(d as *mut _)
195 }
196 }
197
198 #[corresponds(RSA_get0_factors)]
200 pub fn p(&self) -> Option<&BigNumRef> {
201 unsafe {
202 let mut p = ptr::null();
203 RSA_get0_factors(self.as_ptr(), &mut p, ptr::null_mut());
204 if p.is_null() {
205 None
206 } else {
207 Some(BigNumRef::from_ptr(p as *mut _))
208 }
209 }
210 }
211
212 #[corresponds(RSA_get0_factors)]
214 pub fn q(&self) -> Option<&BigNumRef> {
215 unsafe {
216 let mut q = ptr::null();
217 RSA_get0_factors(self.as_ptr(), ptr::null_mut(), &mut q);
218 if q.is_null() {
219 None
220 } else {
221 Some(BigNumRef::from_ptr(q as *mut _))
222 }
223 }
224 }
225
226 #[corresponds(RSA_get0_crt_params)]
228 pub fn dmp1(&self) -> Option<&BigNumRef> {
229 unsafe {
230 let mut dp = ptr::null();
231 RSA_get0_crt_params(self.as_ptr(), &mut dp, ptr::null_mut(), ptr::null_mut());
232 if dp.is_null() {
233 None
234 } else {
235 Some(BigNumRef::from_ptr(dp as *mut _))
236 }
237 }
238 }
239
240 #[corresponds(RSA_get0_crt_params)]
242 pub fn dmq1(&self) -> Option<&BigNumRef> {
243 unsafe {
244 let mut dq = ptr::null();
245 RSA_get0_crt_params(self.as_ptr(), ptr::null_mut(), &mut dq, ptr::null_mut());
246 if dq.is_null() {
247 None
248 } else {
249 Some(BigNumRef::from_ptr(dq as *mut _))
250 }
251 }
252 }
253
254 #[corresponds(RSA_get0_crt_params)]
256 pub fn iqmp(&self) -> Option<&BigNumRef> {
257 unsafe {
258 let mut qi = ptr::null();
259 RSA_get0_crt_params(self.as_ptr(), ptr::null_mut(), ptr::null_mut(), &mut qi);
260 if qi.is_null() {
261 None
262 } else {
263 Some(BigNumRef::from_ptr(qi as *mut _))
264 }
265 }
266 }
267
268 #[corresponds(RSA_check_key)]
270 #[allow(clippy::unnecessary_cast)]
271 pub fn check_key(&self) -> Result<bool, ErrorStack> {
272 unsafe {
273 let result = ffi::RSA_check_key(self.as_ptr()) as i32;
274 if result == -1 {
275 Err(ErrorStack::get())
276 } else {
277 Ok(result == 1)
278 }
279 }
280 }
281}
282
283impl<T> RsaRef<T>
284where
285 T: HasPublic,
286{
287 to_pem! {
288 #[corresponds(PEM_write_bio_RSA_PUBKEY)]
292 public_key_to_pem,
293 ffi::PEM_write_bio_RSA_PUBKEY
294 }
295
296 to_der! {
297 #[corresponds(i2d_RSA_PUBKEY)]
299 public_key_to_der,
300 ffi::i2d_RSA_PUBKEY
301 }
302
303 to_pem! {
304 #[corresponds(PEM_write_bio_RSAPublicKey)]
308 public_key_to_pem_pkcs1,
309 ffi::PEM_write_bio_RSAPublicKey
310 }
311
312 to_der! {
313 #[corresponds(i2d_RSAPublicKey)]
315 public_key_to_der_pkcs1,
316 ffi::i2d_RSAPublicKey
317 }
318
319 #[corresponds(RSA_size)]
321 #[allow(clippy::unnecessary_cast)]
322 pub fn size(&self) -> u32 {
323 unsafe { ffi::RSA_size(self.as_ptr()) as u32 }
324 }
325
326 pub fn public_decrypt(
332 &self,
333 from: &[u8],
334 to: &mut [u8],
335 padding: Padding,
336 ) -> Result<usize, ErrorStack> {
337 assert!(from.len() <= i32::MAX as usize);
338 assert!(to.len() >= self.size() as usize);
339
340 unsafe {
341 let len = cvt_n(ffi::RSA_public_decrypt(
342 from.len(),
343 from.as_ptr(),
344 to.as_mut_ptr(),
345 self.as_ptr(),
346 padding.0,
347 ))?;
348 Ok(len as usize)
349 }
350 }
351
352 pub fn public_encrypt(
358 &self,
359 from: &[u8],
360 to: &mut [u8],
361 padding: Padding,
362 ) -> Result<usize, ErrorStack> {
363 assert!(from.len() <= i32::MAX as usize);
364 assert!(to.len() >= self.size() as usize);
365
366 unsafe {
367 let len = cvt_n(ffi::RSA_public_encrypt(
368 from.len(),
369 from.as_ptr(),
370 to.as_mut_ptr(),
371 self.as_ptr(),
372 padding.0,
373 ))?;
374 Ok(len as usize)
375 }
376 }
377
378 #[corresponds(RSA_get0_key)]
380 pub fn n(&self) -> &BigNumRef {
381 unsafe {
382 let mut n = ptr::null();
383 RSA_get0_key(self.as_ptr(), &mut n, ptr::null_mut(), ptr::null_mut());
384 BigNumRef::from_ptr(n as *mut _)
385 }
386 }
387
388 #[corresponds(RSA_get0_key)]
390 pub fn e(&self) -> &BigNumRef {
391 unsafe {
392 let mut e = ptr::null();
393 RSA_get0_key(self.as_ptr(), ptr::null_mut(), &mut e, ptr::null_mut());
394 BigNumRef::from_ptr(e as *mut _)
395 }
396 }
397}
398
399impl Rsa<Public> {
400 #[corresponds(RSA_new)]
405 pub fn from_public_components(n: BigNum, e: BigNum) -> Result<Rsa<Public>, ErrorStack> {
407 unsafe {
408 let rsa = cvt_p(ffi::RSA_new())?;
409 RSA_set0_key(rsa, n.as_ptr(), e.as_ptr(), ptr::null_mut());
410 mem::forget((n, e));
411 Ok(Rsa::from_ptr(rsa))
412 }
413 }
414
415 from_pem! {
416 #[corresponds(PEM_read_bio_RSA_PUBKEY)]
420 public_key_from_pem,
421 Rsa<Public>,
422 ffi::PEM_read_bio_RSA_PUBKEY
423 }
424
425 from_pem! {
426 #[corresponds(PEM_read_bio_RSAPublicKey)]
430 public_key_from_pem_pkcs1,
431 Rsa<Public>,
432 ffi::PEM_read_bio_RSAPublicKey
433 }
434
435 from_der! {
436 #[corresponds(d2i_RSA_PUBKEY)]
438 public_key_from_der,
439 Rsa<Public>,
440 ffi::d2i_RSA_PUBKEY,
441 ::libc::c_long
442 }
443
444 from_der! {
445 #[corresponds(d2i_RSAPublicKey)]
447 public_key_from_der_pkcs1,
448 Rsa<Public>,
449 ffi::d2i_RSAPublicKey,
450 ::libc::c_long
451 }
452}
453
454pub struct RsaPrivateKeyBuilder {
455 rsa: Rsa<Private>,
456}
457
458impl RsaPrivateKeyBuilder {
459 #[corresponds(RSA_new)]
464 pub fn new(n: BigNum, e: BigNum, d: BigNum) -> Result<RsaPrivateKeyBuilder, ErrorStack> {
466 unsafe {
467 let rsa = cvt_p(ffi::RSA_new())?;
468 RSA_set0_key(rsa, n.as_ptr(), e.as_ptr(), d.as_ptr());
469 mem::forget((n, e, d));
470 Ok(RsaPrivateKeyBuilder {
471 rsa: Rsa::from_ptr(rsa),
472 })
473 }
474 }
475
476 #[corresponds(RSA_set0_factors)]
482 pub fn set_factors(self, p: BigNum, q: BigNum) -> Result<RsaPrivateKeyBuilder, ErrorStack> {
483 unsafe {
484 RSA_set0_factors(self.rsa.as_ptr(), p.as_ptr(), q.as_ptr());
485 mem::forget((p, q));
486 }
487 Ok(self)
488 }
489
490 #[corresponds(RSA_set0_crt_params)]
497 pub fn set_crt_params(
498 self,
499 dmp1: BigNum,
500 dmq1: BigNum,
501 iqmp: BigNum,
502 ) -> Result<RsaPrivateKeyBuilder, ErrorStack> {
503 unsafe {
504 RSA_set0_crt_params(
505 self.rsa.as_ptr(),
506 dmp1.as_ptr(),
507 dmq1.as_ptr(),
508 iqmp.as_ptr(),
509 );
510 mem::forget((dmp1, dmq1, iqmp));
511 }
512 Ok(self)
513 }
514
515 pub fn build(self) -> Rsa<Private> {
517 self.rsa
518 }
519}
520
521impl Rsa<Private> {
522 #[allow(clippy::too_many_arguments, clippy::many_single_char_names)]
527 pub fn from_private_components(
528 n: BigNum,
529 e: BigNum,
530 d: BigNum,
531 p: BigNum,
532 q: BigNum,
533 dmp1: BigNum,
534 dmq1: BigNum,
535 iqmp: BigNum,
536 ) -> Result<Rsa<Private>, ErrorStack> {
537 Ok(RsaPrivateKeyBuilder::new(n, e, d)?
538 .set_factors(p, q)?
539 .set_crt_params(dmp1, dmq1, iqmp)?
540 .build())
541 }
542
543 #[corresponds(RSA_generate_key_ex)]
547 pub fn generate(bits: u32) -> Result<Rsa<Private>, ErrorStack> {
548 let e = BigNum::from_u32(ffi::RSA_F4 as u32)?;
549 Rsa::generate_with_e(bits, &e)
550 }
551
552 #[corresponds(RSA_generate_key_ex)]
556 pub fn generate_with_e(bits: u32, e: &BigNumRef) -> Result<Rsa<Private>, ErrorStack> {
557 unsafe {
558 let rsa = Rsa::from_ptr(cvt_p(ffi::RSA_new())?);
559 cvt(ffi::RSA_generate_key_ex(
560 rsa.0,
561 bits as c_int,
562 e.as_ptr(),
563 ptr::null_mut(),
564 ))?;
565 Ok(rsa)
566 }
567 }
568
569 private_key_from_pem! {
571 #[corresponds(PEM_read_bio_RSAPrivateKey)]
573 private_key_from_pem,
574
575 #[corresponds(PEM_read_bio_RSAPrivateKey)]
577 private_key_from_pem_passphrase,
578
579 #[corresponds(PEM_read_bio_RSAPrivateKey)]
583 private_key_from_pem_callback,
584 Rsa<Private>,
585 ffi::PEM_read_bio_RSAPrivateKey
586 }
587
588 from_der! {
589 #[corresponds(d2i_RSAPrivateKey)]
591 private_key_from_der,
592 Rsa<Private>,
593 ffi::d2i_RSAPrivateKey,
594 ::libc::c_long
595 }
596}
597
598impl<T> fmt::Debug for Rsa<T> {
599 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
600 write!(f, "Rsa")
601 }
602}
603
604use crate::ffi::{
605 RSA_get0_crt_params, RSA_get0_factors, RSA_get0_key, RSA_set0_crt_params, RSA_set0_factors,
606 RSA_set0_key,
607};
608
609#[cfg(test)]
610mod test {
611 use crate::symm::Cipher;
612
613 use super::*;
614
615 #[test]
616 fn test_from_password() {
617 let key = include_bytes!("../test/rsa-encrypted.pem");
618 Rsa::private_key_from_pem_passphrase(key, b"mypass").unwrap();
619 }
620
621 #[test]
622 fn test_from_password_callback() {
623 let mut password_queried = false;
624 let key = include_bytes!("../test/rsa-encrypted.pem");
625 Rsa::private_key_from_pem_callback(key, |password| {
626 password_queried = true;
627 password[..6].copy_from_slice(b"mypass");
628 Ok(6)
629 })
630 .unwrap();
631
632 assert!(password_queried);
633 }
634
635 #[test]
636 fn test_to_password() {
637 let key = Rsa::generate(2048).unwrap();
638 let pem = key
639 .private_key_to_pem_passphrase(Cipher::aes_128_cbc(), b"foobar")
640 .unwrap();
641 Rsa::private_key_from_pem_passphrase(&pem, b"foobar").unwrap();
642 assert!(Rsa::private_key_from_pem_passphrase(&pem, b"fizzbuzz").is_err());
643 }
644
645 #[test]
646 fn test_public_encrypt_private_decrypt_with_padding() {
647 let key = include_bytes!("../test/rsa.pem.pub");
648 let public_key = Rsa::public_key_from_pem(key).unwrap();
649
650 let mut result = vec![0; public_key.size() as usize];
651 let original_data = b"This is test";
652 let len = public_key
653 .public_encrypt(original_data, &mut result, Padding::PKCS1)
654 .unwrap();
655 assert_eq!(len, 256);
656
657 let pkey = include_bytes!("../test/rsa.pem");
658 let private_key = Rsa::private_key_from_pem(pkey).unwrap();
659 let mut dec_result = vec![0; private_key.size() as usize];
660 let len = private_key
661 .private_decrypt(&result, &mut dec_result, Padding::PKCS1)
662 .unwrap();
663
664 assert_eq!(&dec_result[..len], original_data);
665 }
666
667 #[test]
668 fn test_private_encrypt() {
669 let k0 = super::Rsa::generate(512).unwrap();
670 let k0pkey = k0.public_key_to_pem().unwrap();
671 let k1 = super::Rsa::public_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.private_encrypt(&msg, &mut emesg, Padding::PKCS1)
677 .unwrap();
678 let mut dmesg = vec![0; k1.size() as usize];
679 let len = k1
680 .public_decrypt(&emesg, &mut dmesg, Padding::PKCS1)
681 .unwrap();
682 assert_eq!(msg, &dmesg[..len]);
683 }
684
685 #[test]
686 fn test_public_encrypt() {
687 let k0 = super::Rsa::generate(512).unwrap();
688 let k0pkey = k0.private_key_to_pem().unwrap();
689 let k1 = super::Rsa::private_key_from_pem(&k0pkey).unwrap();
690
691 let msg = vec![0xdeu8, 0xadu8, 0xd0u8, 0x0du8];
692
693 let mut emesg = vec![0; k0.size() as usize];
694 k0.public_encrypt(&msg, &mut emesg, Padding::PKCS1).unwrap();
695 let mut dmesg = vec![0; k1.size() as usize];
696 let len = k1
697 .private_decrypt(&emesg, &mut dmesg, Padding::PKCS1)
698 .unwrap();
699 assert_eq!(msg, &dmesg[..len]);
700 }
701
702 #[test]
703 fn test_public_key_from_pem_pkcs1() {
704 let key = include_bytes!("../test/pkcs1.pem.pub");
705 Rsa::public_key_from_pem_pkcs1(key).unwrap();
706 }
707
708 #[test]
709 #[should_panic]
710 fn test_public_key_from_pem_pkcs1_file_panic() {
711 let key = include_bytes!("../test/key.pem.pub");
712 Rsa::public_key_from_pem_pkcs1(key).unwrap();
713 }
714
715 #[test]
716 fn test_public_key_to_pem_pkcs1() {
717 let keypair = super::Rsa::generate(512).unwrap();
718 let pubkey_pem = keypair.public_key_to_pem_pkcs1().unwrap();
719 super::Rsa::public_key_from_pem_pkcs1(&pubkey_pem).unwrap();
720 }
721
722 #[test]
723 #[should_panic]
724 fn test_public_key_from_pem_pkcs1_generate_panic() {
725 let keypair = super::Rsa::generate(512).unwrap();
726 let pubkey_pem = keypair.public_key_to_pem().unwrap();
727 super::Rsa::public_key_from_pem_pkcs1(&pubkey_pem).unwrap();
728 }
729
730 #[test]
731 fn test_pem_pkcs1_encrypt() {
732 let keypair = super::Rsa::generate(2048).unwrap();
733 let pubkey_pem = keypair.public_key_to_pem_pkcs1().unwrap();
734 let pubkey = super::Rsa::public_key_from_pem_pkcs1(&pubkey_pem).unwrap();
735 let msg = b"Hello, world!";
736
737 let mut encrypted = vec![0; pubkey.size() as usize];
738 let len = pubkey
739 .public_encrypt(msg, &mut encrypted, Padding::PKCS1)
740 .unwrap();
741 assert!(len > msg.len());
742 let mut decrypted = vec![0; keypair.size() as usize];
743 let len = keypair
744 .private_decrypt(&encrypted, &mut decrypted, Padding::PKCS1)
745 .unwrap();
746 assert_eq!(len, msg.len());
747 assert_eq!(&decrypted[..len], msg);
748 }
749
750 #[test]
751 fn test_pem_pkcs1_padding() {
752 let keypair = super::Rsa::generate(2048).unwrap();
753 let pubkey_pem = keypair.public_key_to_pem_pkcs1().unwrap();
754 let pubkey = super::Rsa::public_key_from_pem_pkcs1(&pubkey_pem).unwrap();
755 let msg = b"foo";
756
757 let mut encrypted1 = vec![0; pubkey.size() as usize];
758 let mut encrypted2 = vec![0; pubkey.size() as usize];
759 let len1 = pubkey
760 .public_encrypt(msg, &mut encrypted1, Padding::PKCS1)
761 .unwrap();
762 let len2 = pubkey
763 .public_encrypt(msg, &mut encrypted2, Padding::PKCS1)
764 .unwrap();
765 assert!(len1 > (msg.len() + 1));
766 assert_eq!(len1, len2);
767 assert_ne!(encrypted1, encrypted2);
768 }
769
770 #[test]
771 #[allow(clippy::redundant_clone)]
772 fn clone() {
773 let key = Rsa::generate(2048).unwrap();
774 drop(key.clone());
775 }
776
777 #[test]
778 fn generate_with_e() {
779 let e = BigNum::from_u32(0x10001).unwrap();
780 Rsa::generate_with_e(2048, &e).unwrap();
781 }
782}