diff options
Diffstat (limited to 'openssl/src/rsa.rs')
| -rw-r--r-- | openssl/src/rsa.rs | 250 |
1 files changed, 134 insertions, 116 deletions
diff --git a/openssl/src/rsa.rs b/openssl/src/rsa.rs index 666b99dd..c6c96223 100644 --- a/openssl/src/rsa.rs +++ b/openssl/src/rsa.rs @@ -2,6 +2,7 @@ use ffi; use std::fmt; use std::ptr; use std::mem; +use std::ops::Deref; use libc::{c_int, c_void, c_char}; use {cvt, cvt_p, cvt_n}; @@ -9,6 +10,7 @@ use bn::{BigNum, BigNumRef}; use bio::{MemBio, MemBioSlice}; use error::ErrorStack; use util::{CallbackState, invoke_passwd_cb}; +use opaque::Opaque; /// Type of encryption padding to use. #[derive(Copy, Clone)] @@ -18,108 +20,15 @@ pub const NO_PADDING: Padding = Padding(ffi::RSA_NO_PADDING); pub const PKCS1_PADDING: Padding = Padding(ffi::RSA_PKCS1_PADDING); pub const PKCS1_OAEP_PADDING: Padding = Padding(ffi::RSA_PKCS1_OAEP_PADDING); -pub struct Rsa(*mut ffi::RSA); - -impl Drop for Rsa { - fn drop(&mut self) { - unsafe { - ffi::RSA_free(self.0); - } - } -} - -impl Rsa { - /// only useful for associating the key material directly with the key, it's safer to use - /// the supplied load and save methods for DER formatted keys. - pub fn from_public_components(n: BigNum, e: BigNum) -> Result<Rsa, ErrorStack> { - unsafe { - let rsa = Rsa(try!(cvt_p(ffi::RSA_new()))); - try!(cvt(compat::set_key(rsa.0, - n.as_ptr(), - e.as_ptr(), - ptr::null_mut()))); - mem::forget((n, e)); - Ok(rsa) - } - } - - pub fn from_private_components(n: BigNum, - e: BigNum, - d: BigNum, - p: BigNum, - q: BigNum, - dp: BigNum, - dq: BigNum, - qi: BigNum) - -> Result<Rsa, ErrorStack> { - unsafe { - let rsa = Rsa(try!(cvt_p(ffi::RSA_new()))); - try!(cvt(compat::set_key(rsa.0, n.as_ptr(), e.as_ptr(), d.as_ptr()))); - mem::forget((n, e, d)); - try!(cvt(compat::set_factors(rsa.0, p.as_ptr(), q.as_ptr()))); - mem::forget((p, q)); - try!(cvt(compat::set_crt_params(rsa.0, dp.as_ptr(), dq.as_ptr(), - qi.as_ptr()))); - mem::forget((dp, dq, qi)); - Ok(rsa) - } - } - - pub unsafe fn from_ptr(rsa: *mut ffi::RSA) -> Rsa { - Rsa(rsa) - } - - /// Generates a public/private key pair with the specified size. - /// - /// The public exponent will be 65537. - pub fn generate(bits: u32) -> Result<Rsa, ErrorStack> { - unsafe { - let rsa = Rsa(try!(cvt_p(ffi::RSA_new()))); - let e = try!(BigNum::from_u32(ffi::RSA_F4 as u32)); - try!(cvt(ffi::RSA_generate_key_ex(rsa.0, bits as c_int, e.as_ptr(), ptr::null_mut()))); - Ok(rsa) - } - } +pub struct RsaRef(Opaque); - /// Reads an RSA private key from PEM formatted data. - pub fn private_key_from_pem(buf: &[u8]) -> Result<Rsa, ErrorStack> { - let mem_bio = try!(MemBioSlice::new(buf)); - unsafe { - let rsa = try!(cvt_p(ffi::PEM_read_bio_RSAPrivateKey(mem_bio.as_ptr(), - ptr::null_mut(), - None, - ptr::null_mut()))); - Ok(Rsa(rsa)) - } +impl RsaRef { + pub unsafe fn from_ptr<'a>(ptr: *mut ffi::RSA) -> &'a RsaRef { + &*(ptr as *mut _) } - /// Reads an RSA private key from PEM formatted data and supplies a password callback. - pub fn private_key_from_pem_cb<F>(buf: &[u8], pass_cb: F) -> Result<Rsa, ErrorStack> - where F: FnOnce(&mut [c_char]) -> usize - { - let mut cb = CallbackState::new(pass_cb); - let mem_bio = try!(MemBioSlice::new(buf)); - - unsafe { - let cb_ptr = &mut cb as *mut _ as *mut c_void; - let rsa = try!(cvt_p(ffi::PEM_read_bio_RSAPrivateKey(mem_bio.as_ptr(), - ptr::null_mut(), - Some(invoke_passwd_cb::<F>), - cb_ptr))); - Ok(Rsa(rsa)) - } - } - - /// Reads an RSA public key from PEM formatted data. - pub fn public_key_from_pem(buf: &[u8]) -> Result<Rsa, ErrorStack> { - let mem_bio = try!(MemBioSlice::new(buf)); - unsafe { - let rsa = try!(cvt_p(ffi::PEM_read_bio_RSA_PUBKEY(mem_bio.as_ptr(), - ptr::null_mut(), - None, - ptr::null_mut()))); - Ok(Rsa(rsa)) - } + pub fn as_ptr(&self) -> *mut ffi::RSA { + self as *const _ as *mut _ } /// Writes an RSA private key as unencrypted PEM formatted data @@ -128,7 +37,7 @@ impl Rsa { unsafe { try!(cvt(ffi::PEM_write_bio_RSAPrivateKey(mem_bio.as_ptr(), - self.0, + self.as_ptr(), ptr::null(), ptr::null_mut(), 0, @@ -143,7 +52,7 @@ impl Rsa { let mem_bio = try!(MemBio::new()); unsafe { - try!(cvt(ffi::PEM_write_bio_RSA_PUBKEY(mem_bio.as_ptr(), self.0))); + try!(cvt(ffi::PEM_write_bio_RSA_PUBKEY(mem_bio.as_ptr(), self.as_ptr()))); } Ok(mem_bio.get_buf().to_owned()) @@ -153,7 +62,7 @@ impl Rsa { unsafe { assert!(self.n().is_some()); - ffi::RSA_size(self.0) as usize + ffi::RSA_size(self.as_ptr()) as usize } } @@ -176,7 +85,7 @@ impl Rsa { let len = try!(cvt_n(ffi::RSA_private_decrypt(from.len() as c_int, from.as_ptr(), to.as_mut_ptr(), - self.0, + self.as_ptr(), padding.0))); Ok(len as usize) } @@ -201,7 +110,7 @@ impl Rsa { let len = try!(cvt_n(ffi::RSA_private_encrypt(from.len() as c_int, from.as_ptr(), to.as_mut_ptr(), - self.0, + self.as_ptr(), padding.0))); Ok(len as usize) } @@ -224,7 +133,7 @@ impl Rsa { let len = try!(cvt_n(ffi::RSA_public_decrypt(from.len() as c_int, from.as_ptr(), to.as_mut_ptr(), - self.0, + self.as_ptr(), padding.0))); Ok(len as usize) } @@ -247,19 +156,15 @@ impl Rsa { let len = try!(cvt_n(ffi::RSA_public_encrypt(from.len() as c_int, from.as_ptr(), to.as_mut_ptr(), - self.0, + self.as_ptr(), padding.0))); Ok(len as usize) } } - pub fn as_ptr(&self) -> *mut ffi::RSA { - self.0 - } - pub fn n(&self) -> Option<&BigNumRef> { unsafe { - let n = compat::key(self.0)[0]; + let n = compat::key(self.as_ptr())[0]; if n.is_null() { None } else { @@ -270,7 +175,7 @@ impl Rsa { pub fn d(&self) -> Option<&BigNumRef> { unsafe { - let d = compat::key(self.0)[2]; + let d = compat::key(self.as_ptr())[2]; if d.is_null() { None } else { @@ -281,7 +186,7 @@ impl Rsa { pub fn e(&self) -> Option<&BigNumRef> { unsafe { - let e = compat::key(self.0)[1]; + let e = compat::key(self.as_ptr())[1]; if e.is_null() { None } else { @@ -292,7 +197,7 @@ impl Rsa { pub fn p(&self) -> Option<&BigNumRef> { unsafe { - let p = compat::factors(self.0)[0]; + let p = compat::factors(self.as_ptr())[0]; if p.is_null() { None } else { @@ -303,7 +208,7 @@ impl Rsa { pub fn q(&self) -> Option<&BigNumRef> { unsafe { - let q = compat::factors(self.0)[1]; + let q = compat::factors(self.as_ptr())[1]; if q.is_null() { None } else { @@ -313,9 +218,122 @@ impl Rsa { } } +pub struct Rsa(*mut ffi::RSA); + +impl Drop for Rsa { + fn drop(&mut self) { + unsafe { + ffi::RSA_free(self.0); + } + } +} + +impl Rsa { + /// only useful for associating the key material directly with the key, it's safer to use + /// the supplied load and save methods for DER formatted keys. + pub fn from_public_components(n: BigNum, e: BigNum) -> Result<Rsa, ErrorStack> { + unsafe { + let rsa = Rsa(try!(cvt_p(ffi::RSA_new()))); + try!(cvt(compat::set_key(rsa.0, + n.as_ptr(), + e.as_ptr(), + ptr::null_mut()))); + mem::forget((n, e)); + Ok(rsa) + } + } + + pub fn from_private_components(n: BigNum, + e: BigNum, + d: BigNum, + p: BigNum, + q: BigNum, + dp: BigNum, + dq: BigNum, + qi: BigNum) + -> Result<Rsa, ErrorStack> { + unsafe { + let rsa = Rsa(try!(cvt_p(ffi::RSA_new()))); + try!(cvt(compat::set_key(rsa.0, n.as_ptr(), e.as_ptr(), d.as_ptr()))); + mem::forget((n, e, d)); + try!(cvt(compat::set_factors(rsa.0, p.as_ptr(), q.as_ptr()))); + mem::forget((p, q)); + try!(cvt(compat::set_crt_params(rsa.0, dp.as_ptr(), dq.as_ptr(), + qi.as_ptr()))); + mem::forget((dp, dq, qi)); + Ok(rsa) + } + } + + pub unsafe fn from_ptr(rsa: *mut ffi::RSA) -> Rsa { + Rsa(rsa) + } + + /// Generates a public/private key pair with the specified size. + /// + /// The public exponent will be 65537. + pub fn generate(bits: u32) -> Result<Rsa, ErrorStack> { + unsafe { + let rsa = Rsa(try!(cvt_p(ffi::RSA_new()))); + let e = try!(BigNum::from_u32(ffi::RSA_F4 as u32)); + try!(cvt(ffi::RSA_generate_key_ex(rsa.0, bits as c_int, e.as_ptr(), ptr::null_mut()))); + Ok(rsa) + } + } + + /// Reads an RSA private key from PEM formatted data. + pub fn private_key_from_pem(buf: &[u8]) -> Result<Rsa, ErrorStack> { + let mem_bio = try!(MemBioSlice::new(buf)); + unsafe { + let rsa = try!(cvt_p(ffi::PEM_read_bio_RSAPrivateKey(mem_bio.as_ptr(), + ptr::null_mut(), + None, + ptr::null_mut()))); + Ok(Rsa(rsa)) + } + } + + /// Reads an RSA private key from PEM formatted data and supplies a password callback. + pub fn private_key_from_pem_cb<F>(buf: &[u8], pass_cb: F) -> Result<Rsa, ErrorStack> + where F: FnOnce(&mut [c_char]) -> usize + { + let mut cb = CallbackState::new(pass_cb); + let mem_bio = try!(MemBioSlice::new(buf)); + + unsafe { + let cb_ptr = &mut cb as *mut _ as *mut c_void; + let rsa = try!(cvt_p(ffi::PEM_read_bio_RSAPrivateKey(mem_bio.as_ptr(), + ptr::null_mut(), + Some(invoke_passwd_cb::<F>), + cb_ptr))); + Ok(Rsa(rsa)) + } + } + + /// Reads an RSA public key from PEM formatted data. + pub fn public_key_from_pem(buf: &[u8]) -> Result<Rsa, ErrorStack> { + let mem_bio = try!(MemBioSlice::new(buf)); + unsafe { + let rsa = try!(cvt_p(ffi::PEM_read_bio_RSA_PUBKEY(mem_bio.as_ptr(), + ptr::null_mut(), + None, + ptr::null_mut()))); + Ok(Rsa(rsa)) + } + } +} + impl fmt::Debug for Rsa { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "RSA") + write!(f, "Rsa") + } +} + +impl Deref for Rsa { + type Target = RsaRef; + + fn deref(&self) -> &RsaRef { + unsafe { RsaRef::from_ptr(self.0) } } } |