diff options
| author | Steven Fackler <[email protected]> | 2017-12-30 21:46:17 -0800 |
|---|---|---|
| committer | Steven Fackler <[email protected]> | 2017-12-30 21:53:39 -0800 |
| commit | d207897458f8fbd0b2ff6d879721b2f787a5d72b (patch) | |
| tree | f5646108131916584291141407696ef894f2ff1e /openssl/src/rsa.rs | |
| parent | Merge pull request #809 from sfackler/issuer-name (diff) | |
| download | rust-openssl-d207897458f8fbd0b2ff6d879721b2f787a5d72b.tar.xz rust-openssl-d207897458f8fbd0b2ff6d879721b2f787a5d72b.zip | |
Parameterize keys over what they contain
Closes #790
Diffstat (limited to 'openssl/src/rsa.rs')
| -rw-r--r-- | openssl/src/rsa.rs | 237 |
1 files changed, 115 insertions, 122 deletions
diff --git a/openssl/src/rsa.rs b/openssl/src/rsa.rs index 6899fb10..21dd318a 100644 --- a/openssl/src/rsa.rs +++ b/openssl/src/rsa.rs @@ -3,11 +3,12 @@ use std::fmt; use std::ptr; use std::mem; use libc::c_int; -use foreign_types::ForeignTypeRef; +use foreign_types::{ForeignType, ForeignTypeRef}; use {cvt, cvt_n, cvt_p}; use bn::{BigNum, BigNumRef}; use error::ErrorStack; +use pkey::{HasPrivate, HasPublic, Private, Public}; /// Type of encryption padding to use. #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -27,34 +28,21 @@ impl Padding { pub const PKCS1_OAEP: Padding = Padding(ffi::RSA_PKCS1_OAEP_PADDING); } -foreign_type_and_impl_send_sync! { +generic_foreign_type_and_impl_send_sync! { type CType = ffi::RSA; fn drop = ffi::RSA_free; - pub struct Rsa; - pub struct RsaRef; + pub struct Rsa<T>; + pub struct RsaRef<T>; } -impl RsaRef { +impl<T> RsaRef<T> +where + T: HasPrivate, +{ // FIXME these need to specify output format private_key_to_pem!(ffi::PEM_write_bio_RSAPrivateKey); - public_key_to_pem!(ffi::PEM_write_bio_RSA_PUBKEY); - private_key_to_der!(ffi::i2d_RSAPrivateKey); - public_key_to_der!(ffi::i2d_RSA_PUBKEY); - - to_der_inner!( - /// Serializes the public key to DER-encoded PKCS#1. - public_key_to_der_pkcs1, - ffi::i2d_RSAPublicKey - ); - - pub fn size(&self) -> u32 { - unsafe { - assert!(self.n().is_some()); - ffi::RSA_size(self.as_ptr()) as u32 - } - } /// Decrypts data using the private key, returning the number of decrypted bytes. /// @@ -68,7 +56,6 @@ impl RsaRef { to: &mut [u8], padding: Padding, ) -> Result<usize, ErrorStack> { - assert!(self.d().is_some(), "private components missing"); assert!(from.len() <= i32::max_value() as usize); assert!(to.len() >= self.size() as usize); @@ -96,7 +83,6 @@ impl RsaRef { to: &mut [u8], padding: Padding, ) -> Result<usize, ErrorStack> { - assert!(self.d().is_some(), "private components missing"); assert!(from.len() <= i32::max_value() as usize); assert!(to.len() >= self.size() as usize); @@ -112,6 +98,86 @@ impl RsaRef { } } + pub fn d(&self) -> &BigNumRef { + unsafe { + let d = compat::key(self.as_ptr())[2]; + BigNumRef::from_ptr(d as *mut _) + } + } + + pub fn p(&self) -> Option<&BigNumRef> { + unsafe { + let p = compat::factors(self.as_ptr())[0]; + if p.is_null() { + None + } else { + Some(BigNumRef::from_ptr(p as *mut _)) + } + } + } + + pub fn q(&self) -> Option<&BigNumRef> { + unsafe { + let q = compat::factors(self.as_ptr())[1]; + if q.is_null() { + None + } else { + Some(BigNumRef::from_ptr(q as *mut _)) + } + } + } + + pub fn dp(&self) -> Option<&BigNumRef> { + unsafe { + let dp = compat::crt_params(self.as_ptr())[0]; + if dp.is_null() { + None + } else { + Some(BigNumRef::from_ptr(dp as *mut _)) + } + } + } + + pub fn dq(&self) -> Option<&BigNumRef> { + unsafe { + let dq = compat::crt_params(self.as_ptr())[1]; + if dq.is_null() { + None + } else { + Some(BigNumRef::from_ptr(dq as *mut _)) + } + } + } + + pub fn qi(&self) -> Option<&BigNumRef> { + unsafe { + let qi = compat::crt_params(self.as_ptr())[2]; + if qi.is_null() { + None + } else { + Some(BigNumRef::from_ptr(qi as *mut _)) + } + } + } +} + +impl<T> RsaRef<T> +where + T: HasPublic, +{ + public_key_to_pem!(ffi::PEM_write_bio_RSA_PUBKEY); + public_key_to_der!(ffi::i2d_RSA_PUBKEY); + + to_der_inner!( + /// Serializes the public key to DER-encoded PKCS#1. + public_key_to_der_pkcs1, + ffi::i2d_RSAPublicKey + ); + + pub fn size(&self) -> u32 { + unsafe { ffi::RSA_size(self.as_ptr()) as u32 } + } + /// Decrypts data using the public key, returning the number of decrypted bytes. /// /// # Panics @@ -164,101 +230,25 @@ impl RsaRef { } } - pub fn n(&self) -> Option<&BigNumRef> { + pub fn n(&self) -> &BigNumRef { unsafe { let n = compat::key(self.as_ptr())[0]; - if n.is_null() { - None - } else { - Some(BigNumRef::from_ptr(n as *mut _)) - } - } - } - - pub fn d(&self) -> Option<&BigNumRef> { - unsafe { - let d = compat::key(self.as_ptr())[2]; - if d.is_null() { - None - } else { - Some(BigNumRef::from_ptr(d as *mut _)) - } + BigNumRef::from_ptr(n as *mut _) } } - pub fn e(&self) -> Option<&BigNumRef> { + pub fn e(&self) -> &BigNumRef { unsafe { let e = compat::key(self.as_ptr())[1]; - if e.is_null() { - None - } else { - Some(BigNumRef::from_ptr(e as *mut _)) - } - } - } - - pub fn p(&self) -> Option<&BigNumRef> { - unsafe { - let p = compat::factors(self.as_ptr())[0]; - if p.is_null() { - None - } else { - Some(BigNumRef::from_ptr(p as *mut _)) - } - } - } - - pub fn q(&self) -> Option<&BigNumRef> { - unsafe { - let q = compat::factors(self.as_ptr())[1]; - if q.is_null() { - None - } else { - Some(BigNumRef::from_ptr(q as *mut _)) - } - } - } - - pub fn dp(&self) -> Option<&BigNumRef> { - unsafe { - let dp = compat::crt_params(self.as_ptr())[0]; - if dp.is_null() { - None - } else { - Some(BigNumRef::from_ptr(dp as *mut _)) - } - } - } - - pub fn dq(&self) -> Option<&BigNumRef> { - unsafe { - let dq = compat::crt_params(self.as_ptr())[1]; - if dq.is_null() { - None - } else { - Some(BigNumRef::from_ptr(dq as *mut _)) - } - } - } - - pub fn qi(&self) -> Option<&BigNumRef> { - unsafe { - let qi = compat::crt_params(self.as_ptr())[2]; - if qi.is_null() { - None - } else { - Some(BigNumRef::from_ptr(qi as *mut _)) - } + BigNumRef::from_ptr(e as *mut _) } } } -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> { +impl Rsa<Public> { + pub fn from_public_components(n: BigNum, e: BigNum) -> Result<Rsa<Public>, ErrorStack> { unsafe { - let rsa = Rsa(cvt_p(ffi::RSA_new())?); + let rsa = Rsa::from_ptr(cvt_p(ffi::RSA_new())?); cvt(compat::set_key( rsa.0, n.as_ptr(), @@ -270,6 +260,18 @@ impl Rsa { } } + public_key_from_pem!(Rsa<Public>, ffi::PEM_read_bio_RSA_PUBKEY); + public_key_from_der!(Rsa<Public>, ffi::d2i_RSA_PUBKEY); + + from_der_inner!( + /// Deserializes a public key from DER-encoded PKCS#1 data. + public_key_from_der_pkcs1, + Rsa<Public>, + ffi::d2i_RSAPublicKey + ); +} + +impl Rsa<Private> { pub fn from_private_components( n: BigNum, e: BigNum, @@ -279,9 +281,9 @@ impl Rsa { dp: BigNum, dq: BigNum, qi: BigNum, - ) -> Result<Rsa, ErrorStack> { + ) -> Result<Rsa<Private>, ErrorStack> { unsafe { - let rsa = Rsa(cvt_p(ffi::RSA_new())?); + let rsa = Rsa::from_ptr(cvt_p(ffi::RSA_new())?); cvt(compat::set_key(rsa.0, n.as_ptr(), e.as_ptr(), d.as_ptr()))?; mem::forget((n, e, d)); cvt(compat::set_factors(rsa.0, p.as_ptr(), q.as_ptr()))?; @@ -300,10 +302,10 @@ impl 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> { + pub fn generate(bits: u32) -> Result<Rsa<Private>, ErrorStack> { ffi::init(); unsafe { - let rsa = Rsa(cvt_p(ffi::RSA_new())?); + let rsa = Rsa::from_ptr(cvt_p(ffi::RSA_new())?); let e = BigNum::from_u32(ffi::RSA_F4 as u32)?; cvt(ffi::RSA_generate_key_ex( rsa.0, @@ -316,20 +318,11 @@ impl Rsa { } // FIXME these need to identify input formats - private_key_from_pem!(Rsa, ffi::PEM_read_bio_RSAPrivateKey); - private_key_from_der!(Rsa, ffi::d2i_RSAPrivateKey); - public_key_from_pem!(Rsa, ffi::PEM_read_bio_RSA_PUBKEY); - public_key_from_der!(Rsa, ffi::d2i_RSA_PUBKEY); - - from_der_inner!( - /// Deserializes a public key from DER-encoded PKCS#1 data. - public_key_from_der_pkcs1, - Rsa, - ffi::d2i_RSAPublicKey - ); + private_key_from_pem!(Rsa<Private>, ffi::PEM_read_bio_RSAPrivateKey); + private_key_from_der!(Rsa<Private>, ffi::d2i_RSAPrivateKey); } -impl fmt::Debug for Rsa { +impl<T> fmt::Debug for Rsa<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Rsa") } |