Loading openssl/src/dsa.rs +93 −103 Original line number Diff line number Diff line 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); 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 _ } /// Builder for upfront DSA parameter generation pub struct DsaParams(*mut ffi::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()); 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); impl Drop for Dsa { Loading @@ -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. Loading Loading @@ -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(); Loading @@ -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 } } impl Deref for Dsa { type Target = DsaRef; 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() } } 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) } } } Loading openssl/src/pkey.rs +2 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); Loading openssl/src/rsa.rs +134 −116 Original line number Diff line number Diff line Loading @@ -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}; Loading @@ -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)] Loading @@ -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 Loading @@ -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, Loading @@ -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()) Loading @@ -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 } } Loading @@ -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) } Loading @@ -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) } Loading @@ -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) } Loading @@ -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 { Loading @@ -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 { Loading @@ -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 { Loading @@ -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 { Loading @@ -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 { Loading @@ -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) } } } Loading Loading
openssl/src/dsa.rs +93 −103 Original line number Diff line number Diff line 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); 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 _ } /// Builder for upfront DSA parameter generation pub struct DsaParams(*mut ffi::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()); 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); impl Drop for Dsa { Loading @@ -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. Loading Loading @@ -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(); Loading @@ -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 } } impl Deref for Dsa { type Target = DsaRef; 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() } } 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) } } } Loading
openssl/src/pkey.rs +2 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); Loading
openssl/src/rsa.rs +134 −116 Original line number Diff line number Diff line Loading @@ -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}; Loading @@ -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)] Loading @@ -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 Loading @@ -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, Loading @@ -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()) Loading @@ -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 } } Loading @@ -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) } Loading @@ -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) } Loading @@ -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) } Loading @@ -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 { Loading @@ -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 { Loading @@ -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 { Loading @@ -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 { Loading @@ -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 { Loading @@ -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) } } } Loading