diff options
| author | Steven Fackler <[email protected]> | 2016-10-30 17:22:53 -0700 |
|---|---|---|
| committer | GitHub <[email protected]> | 2016-10-30 17:22:53 -0700 |
| commit | eea4e31a56420e6b16f63420b12e94b69deb9da4 (patch) | |
| tree | 5e4bc46e2027caf072b047af7bbdb1b1f9a97d2e | |
| parent | Rustfmt (diff) | |
| parent | Remove DsaParams (diff) | |
| download | rust-openssl-eea4e31a56420e6b16f63420b12e94b69deb9da4.tar.xz rust-openssl-eea4e31a56420e6b16f63420b12e94b69deb9da4.zip | |
Merge pull request #505 from sfackler/more-refs
More refs
| -rw-r--r-- | openssl/src/dsa.rs | 196 | ||||
| -rw-r--r-- | openssl/src/pkey.rs | 4 | ||||
| -rw-r--r-- | openssl/src/rsa.rs | 250 |
3 files changed, 229 insertions, 221 deletions
diff --git a/openssl/src/dsa.rs b/openssl/src/dsa.rs index 9351d852..e92b8ca3 100644 --- a/openssl/src/dsa.rs +++ b/openssl/src/dsa.rs @@ -1,49 +1,98 @@ +use error::ErrorStack; use ffi; +use libc::{c_int, c_char, c_void}; use std::fmt; -use error::ErrorStack; +use std::ops::Deref; use std::ptr; -use libc::{c_int, c_char, c_void}; use {cvt, cvt_p}; use bn::BigNumRef; use bio::{MemBio, MemBioSlice}; use util::{CallbackState, invoke_passwd_cb}; +use opaque::Opaque; + +pub struct DsaRef(Opaque); -/// Builder for upfront DSA parameter generation -pub struct DsaParams(*mut ffi::DSA); +impl DsaRef { + pub unsafe fn from_ptr<'a>(ptr: *mut ffi::DSA) -> &'a DsaRef { + &*(ptr as *mut _) + } + + pub fn as_ptr(&self) -> *mut ffi::DSA { + self as *const _ as *mut _ + } + + /// Writes an DSA private key as unencrypted PEM formatted data + pub fn private_key_to_pem(&self) -> Result<Vec<u8>, ErrorStack> { + assert!(self.has_private_key()); + let mem_bio = try!(MemBio::new()); -impl DsaParams { - pub fn with_size(size: u32) -> Result<DsaParams, ErrorStack> { unsafe { - let dsa = DsaParams(try!(cvt_p(ffi::DSA_new()))); - try!(cvt(ffi::DSA_generate_parameters_ex(dsa.0, - size as c_int, - ptr::null(), - 0, - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut()))); - Ok(dsa) + try!(cvt(ffi::PEM_write_bio_DSAPrivateKey(mem_bio.as_ptr(), self.as_ptr(), + ptr::null(), ptr::null_mut(), 0, + None, ptr::null_mut()))) + }; + + Ok(mem_bio.get_buf().to_owned()) + } + + /// Writes an DSA public key as PEM formatted data + pub fn public_key_to_pem(&self) -> Result<Vec<u8>, ErrorStack> { + let mem_bio = try!(MemBio::new()); + unsafe { + try!(cvt(ffi::PEM_write_bio_DSA_PUBKEY(mem_bio.as_ptr(), self.as_ptr()))); } + Ok(mem_bio.get_buf().to_owned()) } - /// Generate a key pair from the initialized parameters - pub fn generate(self) -> Result<Dsa, ErrorStack> { + pub fn size(&self) -> Option<u32> { + if self.q().is_some() { + unsafe { Some(ffi::DSA_size(self.as_ptr()) as u32) } + } else { + None + } + } + + pub fn p(&self) -> Option<&BigNumRef> { unsafe { - try!(cvt(ffi::DSA_generate_key(self.0))); - let dsa = Dsa(self.0); - ::std::mem::forget(self); - Ok(dsa) + let p = compat::pqg(self.as_ptr())[0]; + if p.is_null() { + None + } else { + Some(BigNumRef::from_ptr(p as *mut _)) + } } } -} -impl Drop for DsaParams { - fn drop(&mut self) { + pub fn q(&self) -> Option<&BigNumRef> { unsafe { - ffi::DSA_free(self.0); + let q = compat::pqg(self.as_ptr())[1]; + if q.is_null() { + None + } else { + Some(BigNumRef::from_ptr(q as *mut _)) + } + } + } + + pub fn g(&self) -> Option<&BigNumRef> { + unsafe { + let g = compat::pqg(self.as_ptr())[2]; + if g.is_null() { + None + } else { + Some(BigNumRef::from_ptr(g as *mut _)) + } } } + + pub fn has_public_key(&self) -> bool { + unsafe { !compat::keys(self.as_ptr())[0].is_null() } + } + + pub fn has_private_key(&self) -> bool { + unsafe { !compat::keys(self.as_ptr())[1].is_null() } + } } pub struct Dsa(*mut ffi::DSA); @@ -61,11 +110,20 @@ impl Dsa { Dsa(dsa) } - /// Generate a DSA key pair - /// For more complicated key generation scenarios see the `DSAParams` type - pub fn generate(size: u32) -> Result<Dsa, ErrorStack> { - let params = try!(DsaParams::with_size(size)); - params.generate() + /// Generate a DSA key pair. + pub fn generate(bits: u32) -> Result<Dsa, ErrorStack> { + unsafe { + let dsa = Dsa(try!(cvt_p(ffi::DSA_new()))); + try!(cvt(ffi::DSA_generate_parameters_ex(dsa.0, + bits as c_int, + ptr::null(), + 0, + ptr::null_mut(), + ptr::null_mut(), + ptr::null_mut()))); + try!(cvt(ffi::DSA_generate_key(dsa .0))); + Ok(dsa) + } } /// Reads a DSA private key from PEM formatted data. @@ -104,20 +162,6 @@ impl Dsa { } } - /// Writes an DSA private key as unencrypted PEM formatted data - pub fn private_key_to_pem(&self) -> Result<Vec<u8>, ErrorStack> { - assert!(self.has_private_key()); - let mem_bio = try!(MemBio::new()); - - unsafe { - try!(cvt(ffi::PEM_write_bio_DSAPrivateKey(mem_bio.as_ptr(), self.0, - ptr::null(), ptr::null_mut(), 0, - None, ptr::null_mut()))) - }; - - Ok(mem_bio.get_buf().to_owned()) - } - /// Reads an DSA public key from PEM formatted data. pub fn public_key_from_pem(buf: &[u8]) -> Result<Dsa, ErrorStack> { ffi::init(); @@ -131,67 +175,13 @@ impl Dsa { Ok(Dsa(dsa)) } } +} - /// Writes an DSA public key as PEM formatted data - pub fn public_key_to_pem(&self) -> Result<Vec<u8>, ErrorStack> { - let mem_bio = try!(MemBio::new()); - unsafe { - try!(cvt(ffi::PEM_write_bio_DSA_PUBKEY(mem_bio.as_ptr(), self.0))); - } - Ok(mem_bio.get_buf().to_owned()) - } - - pub fn size(&self) -> Option<u32> { - if self.q().is_some() { - unsafe { Some(ffi::DSA_size(self.0) as u32) } - } else { - None - } - } - - pub fn as_ptr(&self) -> *mut ffi::DSA { - self.0 - } - - pub fn p(&self) -> Option<&BigNumRef> { - unsafe { - let p = compat::pqg(self.0)[0]; - if p.is_null() { - None - } else { - Some(BigNumRef::from_ptr(p as *mut _)) - } - } - } - - pub fn q(&self) -> Option<&BigNumRef> { - unsafe { - let q = compat::pqg(self.0)[1]; - if q.is_null() { - None - } else { - Some(BigNumRef::from_ptr(q as *mut _)) - } - } - } - - pub fn g(&self) -> Option<&BigNumRef> { - unsafe { - let g = compat::pqg(self.0)[2]; - if g.is_null() { - None - } else { - Some(BigNumRef::from_ptr(g as *mut _)) - } - } - } - - pub fn has_public_key(&self) -> bool { - unsafe { !compat::keys(self.0)[0].is_null() } - } +impl Deref for Dsa { + type Target = DsaRef; - pub fn has_private_key(&self) -> bool { - unsafe { !compat::keys(self.0)[1].is_null() } + fn deref(&self) -> &DsaRef { + unsafe { DsaRef::from_ptr(self.0) } } } diff --git a/openssl/src/pkey.rs b/openssl/src/pkey.rs index fc48c8b4..8e4041b1 100644 --- a/openssl/src/pkey.rs +++ b/openssl/src/pkey.rs @@ -7,7 +7,7 @@ use ffi; use {cvt, cvt_p}; use bio::{MemBio, MemBioSlice}; use dsa::Dsa; -use rsa::Rsa; +use rsa::{Rsa, RsaRef}; use error::ErrorStack; use util::{CallbackState, invoke_passwd_cb}; use opaque::Opaque; @@ -156,7 +156,7 @@ impl PKey { } /// Assign an RSA key to this pkey. - pub fn set_rsa(&mut self, rsa: &Rsa) -> Result<(), ErrorStack> { + pub fn set_rsa(&mut self, rsa: &RsaRef) -> Result<(), ErrorStack> { unsafe { // this needs to be a reference as the set1_RSA ups the reference count let rsa_ptr = rsa.as_ptr(); 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) } } } |