Merge pull request #613 from aosmond/add_evp_pkey_derive
Add new EC/PKEY methods to permit deriving shared secrets.
This commit is contained in:
commit
3439ec6f41
|
|
@ -1510,6 +1510,7 @@ extern {
|
|||
|
||||
pub fn EC_KEY_new() -> *mut EC_KEY;
|
||||
pub fn EC_KEY_new_by_curve_name(nid: c_int) -> *mut EC_KEY;
|
||||
pub fn EC_KEY_dup(key: *const EC_KEY) -> *mut EC_KEY;
|
||||
pub fn EC_KEY_set_group(key: *mut EC_KEY, group: *const EC_GROUP) -> c_int;
|
||||
pub fn EC_KEY_get0_group(key: *const EC_KEY) -> *const EC_GROUP;
|
||||
pub fn EC_KEY_set_public_key(key: *mut EC_KEY, key: *const EC_POINT) -> c_int;
|
||||
|
|
@ -1650,8 +1651,13 @@ extern {
|
|||
e: *mut ENGINE,
|
||||
key: *const c_uchar,
|
||||
keylen: c_int) -> *mut EVP_PKEY;
|
||||
pub fn EVP_PKEY_derive_init(ctx: *mut EVP_PKEY_CTX) -> c_int;
|
||||
pub fn EVP_PKEY_derive_set_peer(ctx: *mut EVP_PKEY_CTX, peer: *mut EVP_PKEY) -> c_int;
|
||||
pub fn EVP_PKEY_derive(ctx: *mut EVP_PKEY_CTX, key: *mut c_uchar, size: *mut size_t) -> c_int;
|
||||
pub fn d2i_PKCS8PrivateKey_bio(bp: *mut BIO, x: *mut *mut EVP_PKEY, cb: Option<PasswordCallback>, u: *mut c_void) -> *mut EVP_PKEY;
|
||||
|
||||
pub fn EVP_PKEY_CTX_new(k: *mut EVP_PKEY, e: *mut ENGINE) -> *mut EVP_PKEY_CTX;
|
||||
pub fn EVP_PKEY_CTX_free(ctx: *mut EVP_PKEY_CTX);
|
||||
pub fn EVP_PKEY_CTX_ctrl(ctx: *mut EVP_PKEY_CTX, keytype: c_int, optype: c_int, cmd: c_int, p1: c_int, p2: *mut c_void) -> c_int;
|
||||
|
||||
pub fn HMAC_CTX_copy(dst: *mut HMAC_CTX, src: *mut HMAC_CTX) -> c_int;
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
@ -440,6 +444,13 @@ mod test {
|
|||
key.private_key().unwrap();
|
||||
}
|
||||
|
||||
#[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();
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
|
||||
pub fn derive_init(&mut self) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
try!(cvt(ffi::EVP_PKEY_derive_init(self.as_ptr())));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl ForeignTypeRef for PKeyCtxRef {
|
||||
type CType = ffi::EVP_PKEY_CTX;
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue