diff options
| author | Steven Fackler <[email protected]> | 2017-04-11 10:04:57 -0700 |
|---|---|---|
| committer | GitHub <[email protected]> | 2017-04-11 10:04:57 -0700 |
| commit | 3439ec6f41e9b6849f62e0eb6524020ec67d918b (patch) | |
| tree | c8da9a4fe516451a75e5ac30052b67d68c5c25d4 /openssl/src | |
| parent | Don't exclude test data from package (diff) | |
| parent | Add new EC/PKEY methods to permit deriving shared secrets. (diff) | |
| download | rust-openssl-3439ec6f41e9b6849f62e0eb6524020ec67d918b.tar.xz rust-openssl-3439ec6f41e9b6849f62e0eb6524020ec67d918b.zip | |
Merge pull request #613 from aosmond/add_evp_pkey_derive
Add new EC/PKEY methods to permit deriving shared secrets.
Diffstat (limited to 'openssl/src')
| -rw-r--r-- | openssl/src/ec.rs | 11 | ||||
| -rw-r--r-- | openssl/src/pkey.rs | 65 |
2 files changed, 69 insertions, 7 deletions
diff --git a/openssl/src/ec.rs b/openssl/src/ec.rs index 37815021..33c15569 100644 --- a/openssl/src/ec.rs +++ b/openssl/src/ec.rs @@ -314,6 +314,10 @@ impl EcKeyRef { pub fn check_key(&self) -> Result<(), ErrorStack> { unsafe { cvt(ffi::EC_KEY_check_key(self.as_ptr())).map(|_| ()) } } + + pub fn to_owned(&self) -> Result<EcKey, ErrorStack> { + unsafe { cvt_p(ffi::EC_KEY_dup(self.as_ptr())).map(EcKey) } + } } impl EcKey { @@ -441,6 +445,13 @@ mod test { } #[test] + fn dup() { + let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap(); + let key = EcKey::generate(&group).unwrap(); + key.to_owned().unwrap(); + } + + #[test] fn point_new() { let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap(); EcPoint::new(&group).unwrap(); diff --git a/openssl/src/pkey.rs b/openssl/src/pkey.rs index 6dbe8ec7..31dc9d82 100644 --- a/openssl/src/pkey.rs +++ b/openssl/src/pkey.rs @@ -1,9 +1,9 @@ -use libc::{c_void, c_char, c_int}; +use libc::{c_void, c_char, c_int, size_t}; use std::ptr; use std::mem; use std::ffi::CString; use ffi; -use foreign_types::{Opaque, ForeignType, ForeignTypeRef}; +use foreign_types::{ForeignType, ForeignTypeRef}; use {cvt, cvt_p}; use bio::MemBioSlice; @@ -199,7 +199,25 @@ impl PKey { } } -pub struct PKeyCtxRef(Opaque); +foreign_type! { + type CType = ffi::EVP_PKEY_CTX; + fn drop = ffi::EVP_PKEY_CTX_free; + + pub struct PKeyCtx; + pub struct PKeyCtxRef; +} + +unsafe impl Send for PKeyCtx {} +unsafe impl Sync for PKeyCtx {} + +impl PKeyCtx { + pub fn from_pkey(pkey: &PKeyRef) -> Result<PKeyCtx, ErrorStack> { + unsafe { + let evp = try!(cvt_p(ffi::EVP_PKEY_CTX_new(pkey.as_ptr(), ptr::null_mut()))); + Ok(PKeyCtx(evp)) + } + } +} impl PKeyCtxRef { pub fn set_rsa_padding(&mut self, pad: Padding) -> Result<(), ErrorStack> { @@ -216,10 +234,29 @@ impl PKeyCtxRef { }; Ok(Padding::from_raw(pad)) } -} -impl ForeignTypeRef for PKeyCtxRef { - type CType = ffi::EVP_PKEY_CTX; + pub fn derive_init(&mut self) -> Result<(), ErrorStack> { + unsafe { + try!(cvt(ffi::EVP_PKEY_derive_init(self.as_ptr()))); + } + Ok(()) + } + + pub fn derive_set_peer(&mut self, peer: &PKeyRef) -> Result<(), ErrorStack> { + unsafe { + try!(cvt(ffi::EVP_PKEY_derive_set_peer(self.as_ptr(), peer.as_ptr()))); + } + Ok(()) + } + + pub fn derive(&mut self) -> Result<Vec<u8>, ErrorStack> { + let mut len: size_t = 0; + unsafe { try!(cvt(ffi::EVP_PKEY_derive(self.as_ptr(), ptr::null_mut(), &mut len))); } + + let mut key = vec![0u8; len]; + unsafe { try!(cvt(ffi::EVP_PKEY_derive(self.as_ptr(), key.as_mut_ptr(), &mut len))); } + Ok(key) + } } #[cfg(test)] @@ -227,7 +264,7 @@ mod tests { use symm::Cipher; use dh::Dh; use dsa::Dsa; - use ec::EcKey; + use ec::{EcGroup, EcKey}; use rsa::Rsa; use nid; @@ -319,4 +356,18 @@ mod tests { pkey.ec_key().unwrap(); assert!(pkey.rsa().is_err()); } + + #[test] + fn test_ec_key_derive() { + let group = EcGroup::from_curve_name(nid::X9_62_PRIME256V1).unwrap(); + let ec_key = EcKey::generate(&group).unwrap(); + let ec_key2 = EcKey::generate(&group).unwrap(); + let pkey = PKey::from_ec_key(ec_key).unwrap(); + let pkey2 = PKey::from_ec_key(ec_key2).unwrap(); + let mut pkey_ctx = PKeyCtx::from_pkey(&pkey).unwrap(); + pkey_ctx.derive_init().unwrap(); + pkey_ctx.derive_set_peer(&pkey2).unwrap(); + let shared = pkey_ctx.derive().unwrap(); + assert!(!shared.is_empty()); + } } |