5 use libc
::{c_int, c_void, c_char}
;
6 use foreign_types
::ForeignTypeRef
;
8 use {cvt, cvt_p, cvt_n}
;
9 use bn
::{BigNum, BigNumRef}
;
11 use error
::ErrorStack
;
12 use util
::{CallbackState, invoke_passwd_cb_old}
;
14 /// Type of encryption padding to use.
15 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
16 pub struct Padding(c_int
);
19 pub fn from_raw(value
: c_int
) -> Padding
{
23 pub fn as_raw(&self) -> c_int
{
28 pub const NO_PADDING
: Padding
= Padding(ffi
::RSA_NO_PADDING
);
29 pub const PKCS1_PADDING
: Padding
= Padding(ffi
::RSA_PKCS1_PADDING
);
30 pub const PKCS1_OAEP_PADDING
: Padding
= Padding(ffi
::RSA_PKCS1_OAEP_PADDING
);
33 type CType
= ffi
::RSA
;
34 fn drop
= ffi
::RSA_free
;
41 // FIXME these need to specify output format
42 private_key_to_pem
!(ffi
::PEM_write_bio_RSAPrivateKey
);
43 public_key_to_pem
!(ffi
::PEM_write_bio_RSA_PUBKEY
);
45 private_key_to_der
!(ffi
::i2d_RSAPrivateKey
);
46 public_key_to_der
!(ffi
::i2d_RSA_PUBKEY
);
49 /// Serializes the public key to DER-encoded PKCS#1.
50 public_key_to_der_pkcs1
,
54 // FIXME should return u32
55 pub fn size(&self) -> usize {
57 assert
!(self.n().is_some());
59 ffi
::RSA_size(self.as_ptr()) as usize
63 /// Decrypts data using the private key, returning the number of decrypted bytes.
67 /// Panics if `self` has no private components, or if `to` is smaller
68 /// than `self.size()`.
69 pub fn private_decrypt(
74 ) -> Result
<usize, ErrorStack
> {
75 assert
!(self.d().is_some(), "private components missing");
76 assert
!(from
.len() <= i32::max_value() as usize);
77 assert
!(to
.len() >= self.size());
80 let len
= try
!(cvt_n(ffi
::RSA_private_decrypt(
91 /// Encrypts data using the private key, returning the number of encrypted bytes.
95 /// Panics if `self` has no private components, or if `to` is smaller
96 /// than `self.size()`.
97 pub fn private_encrypt(
102 ) -> Result
<usize, ErrorStack
> {
103 assert
!(self.d().is_some(), "private components missing");
104 assert
!(from
.len() <= i32::max_value() as usize);
105 assert
!(to
.len() >= self.size());
108 let len
= try
!(cvt_n(ffi
::RSA_private_encrypt(
119 /// Decrypts data using the public key, returning the number of decrypted bytes.
123 /// Panics if `to` is smaller than `self.size()`.
124 pub fn public_decrypt(
129 ) -> Result
<usize, ErrorStack
> {
130 assert
!(from
.len() <= i32::max_value() as usize);
131 assert
!(to
.len() >= self.size());
134 let len
= try
!(cvt_n(ffi
::RSA_public_decrypt(
145 /// Encrypts data using the public key, returning the number of encrypted bytes.
149 /// Panics if `to` is smaller than `self.size()`.
150 pub fn public_encrypt(
155 ) -> Result
<usize, ErrorStack
> {
156 assert
!(from
.len() <= i32::max_value() as usize);
157 assert
!(to
.len() >= self.size());
160 let len
= try
!(cvt_n(ffi
::RSA_public_encrypt(
171 pub fn n(&self) -> Option
<&BigNumRef
> {
173 let n
= compat
::key(self.as_ptr())[0];
177 Some(BigNumRef
::from_ptr(n
as *mut _
))
182 pub fn d(&self) -> Option
<&BigNumRef
> {
184 let d
= compat
::key(self.as_ptr())[2];
188 Some(BigNumRef
::from_ptr(d
as *mut _
))
193 pub fn e(&self) -> Option
<&BigNumRef
> {
195 let e
= compat
::key(self.as_ptr())[1];
199 Some(BigNumRef
::from_ptr(e
as *mut _
))
204 pub fn p(&self) -> Option
<&BigNumRef
> {
206 let p
= compat
::factors(self.as_ptr())[0];
210 Some(BigNumRef
::from_ptr(p
as *mut _
))
215 pub fn q(&self) -> Option
<&BigNumRef
> {
217 let q
= compat
::factors(self.as_ptr())[1];
221 Some(BigNumRef
::from_ptr(q
as *mut _
))
228 /// only useful for associating the key material directly with the key, it's safer to use
229 /// the supplied load and save methods for DER formatted keys.
230 pub fn from_public_components(n
: BigNum
, e
: BigNum
) -> Result
<Rsa
, ErrorStack
> {
232 let rsa
= Rsa(try
!(cvt_p(ffi
::RSA_new())));
233 try
!(cvt(compat
::set_key(
244 pub fn from_private_components(
253 ) -> Result
<Rsa
, ErrorStack
> {
255 let rsa
= Rsa(try
!(cvt_p(ffi
::RSA_new())));
257 compat
::set_key(rsa
.0, n
.as_ptr(), e
.as_ptr(), d
.as_ptr()),
259 mem
::forget((n
, e
, d
));
260 try
!(cvt(compat
::set_factors(rsa
.0, p
.as_ptr(), q
.as_ptr())));
262 try
!(cvt(compat
::set_crt_params(
268 mem
::forget((dp
, dq
, qi
));
273 /// Generates a public/private key pair with the specified size.
275 /// The public exponent will be 65537.
276 pub fn generate(bits
: u32) -> Result
<Rsa
, ErrorStack
> {
279 let rsa
= Rsa(try
!(cvt_p(ffi
::RSA_new())));
280 let e
= try
!(BigNum
::from_u32(ffi
::RSA_F4
as u32));
281 try
!(cvt(ffi
::RSA_generate_key_ex(
291 // FIXME these need to identify input formats
292 private_key_from_pem
!(Rsa
, ffi
::PEM_read_bio_RSAPrivateKey
);
293 private_key_from_der
!(Rsa
, ffi
::d2i_RSAPrivateKey
);
294 public_key_from_pem
!(Rsa
, ffi
::PEM_read_bio_RSA_PUBKEY
);
295 public_key_from_der
!(Rsa
, ffi
::d2i_RSA_PUBKEY
);
298 /// Deserializes a public key from DER-encoded PKCS#1 data.
299 public_key_from_der_pkcs1
,
301 ffi
::d2i_RSAPublicKey
304 #[deprecated(since = "0.9.2", note = "use private_key_from_pem_callback")]
305 pub fn private_key_from_pem_cb
<F
>(buf
: &[u8], pass_cb
: F
) -> Result
<Rsa
, ErrorStack
>
307 F
: FnOnce(&mut [c_char
]) -> usize,
310 let mut cb
= CallbackState
::new(pass_cb
);
311 let mem_bio
= try
!(MemBioSlice
::new(buf
));
314 let cb_ptr
= &mut cb
as *mut _
as *mut c_void
;
315 let rsa
= try
!(cvt_p(ffi
::PEM_read_bio_RSAPrivateKey(
318 Some(invoke_passwd_cb_old
::<F
>),
326 impl fmt
::Debug
for Rsa
{
327 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
336 use ffi
::{self, BIGNUM, RSA}
;
339 pub unsafe fn key(r
: *const RSA
) -> [*const BIGNUM
; 3] {
340 let (mut n
, mut e
, mut d
) = (ptr
::null(), ptr
::null(), ptr
::null());
341 ffi
::RSA_get0_key(r
, &mut n
, &mut e
, &mut d
);
345 pub unsafe fn factors(r
: *const RSA
) -> [*const BIGNUM
; 2] {
346 let (mut p
, mut q
) = (ptr
::null(), ptr
::null());
347 ffi
::RSA_get0_factors(r
, &mut p
, &mut q
);
351 pub unsafe fn set_key(r
: *mut RSA
, n
: *mut BIGNUM
, e
: *mut BIGNUM
, d
: *mut BIGNUM
) -> c_int
{
352 ffi
::RSA_set0_key(r
, n
, e
, d
)
355 pub unsafe fn set_factors(r
: *mut RSA
, p
: *mut BIGNUM
, q
: *mut BIGNUM
) -> c_int
{
356 ffi
::RSA_set0_factors(r
, p
, q
)
359 pub unsafe fn set_crt_params(
365 ffi
::RSA_set0_crt_params(r
, dmp1
, dmq1
, iqmp
)
372 use ffi
::{BIGNUM, RSA}
;
374 pub unsafe fn key(r
: *const RSA
) -> [*const BIGNUM
; 3] {
375 [(*r
).n
, (*r
).e
, (*r
).d
]
378 pub unsafe fn factors(r
: *const RSA
) -> [*const BIGNUM
; 2] {
382 pub unsafe fn set_key(r
: *mut RSA
, n
: *mut BIGNUM
, e
: *mut BIGNUM
, d
: *mut BIGNUM
) -> c_int
{
386 1 // TODO: is this right? should it be 0? what's success?
389 pub unsafe fn set_factors(r
: *mut RSA
, p
: *mut BIGNUM
, q
: *mut BIGNUM
) -> c_int
{
392 1 // TODO: is this right? should it be 0? what's success?
395 pub unsafe fn set_crt_params(
404 1 // TODO: is this right? should it be 0? what's success?
415 fn test_from_password() {
416 let key
= include_bytes
!("../test/rsa-encrypted.pem");
417 Rsa
::private_key_from_pem_passphrase(key
, b
"mypass").unwrap();
421 fn test_from_password_callback() {
422 let mut password_queried
= false;
423 let key
= include_bytes
!("../test/rsa-encrypted.pem");
424 Rsa
::private_key_from_pem_callback(key
, |password
| {
425 password_queried
= true;
426 password
[..6].copy_from_slice(b
"mypass");
430 assert
!(password_queried
);
434 fn test_to_password() {
435 let key
= Rsa
::generate(2048).unwrap();
436 let pem
= key
.private_key_to_pem_passphrase(Cipher
::aes_128_cbc(), b
"foobar")
438 Rsa
::private_key_from_pem_passphrase(&pem
, b
"foobar").unwrap();
439 assert
!(Rsa
::private_key_from_pem_passphrase(&pem
, b
"fizzbuzz").is_err());
443 fn test_public_encrypt_private_decrypt_with_padding() {
444 let key
= include_bytes
!("../test/rsa.pem.pub");
445 let public_key
= Rsa
::public_key_from_pem(key
).unwrap();
447 let mut result
= vec
![0; public_key
.size()];
448 let original_data
= b
"This is test";
450 .public_encrypt(original_data
, &mut result
, PKCS1_PADDING
)
452 assert_eq
!(len
, 256);
454 let pkey
= include_bytes
!("../test/rsa.pem");
455 let private_key
= Rsa
::private_key_from_pem(pkey
).unwrap();
456 let mut dec_result
= vec
![0; private_key
.size()];
457 let len
= private_key
458 .private_decrypt(&result
, &mut dec_result
, PKCS1_PADDING
)
461 assert_eq
!(&dec_result
[..len
], original_data
);
465 fn test_private_encrypt() {
466 let k0
= super::Rsa
::generate(512).unwrap();
467 let k0pkey
= k0
.public_key_to_pem().unwrap();
468 let k1
= super::Rsa
::public_key_from_pem(&k0pkey
).unwrap();
470 let msg
= vec
![0xdeu8, 0xadu8, 0xd0u8, 0x0du8];
472 let mut emesg
= vec
![0; k0
.size()];
473 k0
.private_encrypt(&msg
, &mut emesg
, PKCS1_PADDING
).unwrap();
474 let mut dmesg
= vec
![0; k1
.size()];
475 let len
= k1
.public_decrypt(&emesg
, &mut dmesg
, PKCS1_PADDING
)
477 assert_eq
!(msg
, &dmesg
[..len
]);
481 fn test_public_encrypt() {
482 let k0
= super::Rsa
::generate(512).unwrap();
483 let k0pkey
= k0
.private_key_to_pem().unwrap();
484 let k1
= super::Rsa
::private_key_from_pem(&k0pkey
).unwrap();
486 let msg
= vec
![0xdeu8, 0xadu8, 0xd0u8, 0x0du8];
488 let mut emesg
= vec
![0; k0
.size()];
489 k0
.public_encrypt(&msg
, &mut emesg
, PKCS1_PADDING
).unwrap();
490 let mut dmesg
= vec
![0; k1
.size()];
491 let len
= k1
.private_decrypt(&emesg
, &mut dmesg
, PKCS1_PADDING
)
493 assert_eq
!(msg
, &dmesg
[..len
]);