PKey <-> DH conversions

Closes #498
This commit is contained in:
Steven Fackler 2016-11-11 19:04:54 +00:00
parent 609a09ebb9
commit 32cbed0782
2 changed files with 36 additions and 4 deletions

View File

@ -113,6 +113,7 @@ pub const EVP_MAX_MD_SIZE: c_uint = 64;
pub const EVP_PKEY_RSA: c_int = NID_rsaEncryption; pub const EVP_PKEY_RSA: c_int = NID_rsaEncryption;
pub const EVP_PKEY_HMAC: c_int = NID_hmac; pub const EVP_PKEY_HMAC: c_int = NID_hmac;
pub const EVP_PKEY_DSA: c_int = NID_dsa; pub const EVP_PKEY_DSA: c_int = NID_dsa;
pub const EVP_PKEY_DH: c_int = NID_dhKeyAgreement;
pub const EVP_CTRL_GCM_SET_IVLEN: c_int = 0x9; pub const EVP_CTRL_GCM_SET_IVLEN: c_int = 0x9;
pub const EVP_CTRL_GCM_GET_TAG: c_int = 0x10; pub const EVP_CTRL_GCM_GET_TAG: c_int = 0x10;
@ -1456,6 +1457,7 @@ extern {
pub fn EVP_PKEY_get1_RSA(k: *mut EVP_PKEY) -> *mut RSA; pub fn EVP_PKEY_get1_RSA(k: *mut EVP_PKEY) -> *mut RSA;
pub fn EVP_PKEY_set1_RSA(k: *mut EVP_PKEY, r: *mut RSA) -> c_int; pub fn EVP_PKEY_set1_RSA(k: *mut EVP_PKEY, r: *mut RSA) -> c_int;
pub fn EVP_PKEY_get1_DSA(k: *mut EVP_PKEY) -> *mut DSA; pub fn EVP_PKEY_get1_DSA(k: *mut EVP_PKEY) -> *mut DSA;
pub fn EVP_PKEY_get1_DH(k: *mut EVP_PKEY) -> *mut DH;
pub fn EVP_PKEY_cmp(a: *const EVP_PKEY, b: *const EVP_PKEY) -> c_int; pub fn EVP_PKEY_cmp(a: *const EVP_PKEY, b: *const EVP_PKEY) -> c_int;
pub fn EVP_PKEY_new_mac_key(type_: c_int, pub fn EVP_PKEY_new_mac_key(type_: c_int,
e: *mut ENGINE, e: *mut ENGINE,

View File

@ -5,6 +5,7 @@ use ffi;
use {cvt, cvt_p}; use {cvt, cvt_p};
use bio::{MemBio, MemBioSlice}; use bio::{MemBio, MemBioSlice};
use dh::Dh;
use dsa::Dsa; use dsa::Dsa;
use rsa::Rsa; use rsa::Rsa;
use error::ErrorStack; use error::ErrorStack;
@ -30,6 +31,14 @@ impl PKeyRef {
} }
} }
/// Returns a copy of the internal DH key.
pub fn dh(&self) -> Result<Dh, ErrorStack> {
unsafe {
let dh = try!(cvt_p(ffi::EVP_PKEY_get1_DH(self.as_ptr())));
Ok(Dh::from_ptr(dh))
}
}
/// Stores private key as a PEM /// Stores private key as a PEM
// FIXME: also add password and encryption // FIXME: also add password and encryption
pub fn private_key_to_pem(&self) -> Result<Vec<u8>, ErrorStack> { pub fn private_key_to_pem(&self) -> Result<Vec<u8>, ErrorStack> {
@ -74,7 +83,7 @@ unsafe impl Send for PKey {}
unsafe impl Sync for PKey {} unsafe impl Sync for PKey {}
impl PKey { impl PKey {
/// Create a new `PKey` containing an RSA key. /// Creates a new `PKey` containing an RSA key.
pub fn from_rsa(rsa: Rsa) -> Result<PKey, ErrorStack> { pub fn from_rsa(rsa: Rsa) -> Result<PKey, ErrorStack> {
unsafe { unsafe {
let evp = try!(cvt_p(ffi::EVP_PKEY_new())); let evp = try!(cvt_p(ffi::EVP_PKEY_new()));
@ -85,7 +94,7 @@ impl PKey {
} }
} }
/// Create a new `PKey` containing a DSA key. /// Creates a new `PKey` containing a DSA key.
pub fn from_dsa(dsa: Dsa) -> Result<PKey, ErrorStack> { pub fn from_dsa(dsa: Dsa) -> Result<PKey, ErrorStack> {
unsafe { unsafe {
let evp = try!(cvt_p(ffi::EVP_PKEY_new())); let evp = try!(cvt_p(ffi::EVP_PKEY_new()));
@ -96,7 +105,18 @@ impl PKey {
} }
} }
/// Create a new `PKey` containing an HMAC key. /// Creates a new `PKey` containing a DH key.
pub fn from_dh(dh: Dh) -> Result<PKey, ErrorStack> {
unsafe {
let evp = try!(cvt_p(ffi::EVP_PKEY_new()));
let pkey = PKey(evp);
try!(cvt(ffi::EVP_PKEY_assign(pkey.0, ffi::EVP_PKEY_DH, dh.as_ptr() as *mut _)));
mem::forget(dh);
Ok(pkey)
}
}
/// Creates a new `PKey` containing an HMAC key.
pub fn hmac(key: &[u8]) -> Result<PKey, ErrorStack> { pub fn hmac(key: &[u8]) -> Result<PKey, ErrorStack> {
unsafe { unsafe {
assert!(key.len() <= c_int::max_value() as usize); assert!(key.len() <= c_int::max_value() as usize);
@ -157,8 +177,9 @@ impl PKey {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use rsa::Rsa; use dh::Dh;
use dsa::Dsa; use dsa::Dsa;
use rsa::Rsa;
use super::*; use super::*;
@ -203,4 +224,13 @@ mod tests {
pkey.dsa().unwrap(); pkey.dsa().unwrap();
assert!(pkey.rsa().is_err()); assert!(pkey.rsa().is_err());
} }
#[test]
fn test_dh_accessor() {
let dh = include_bytes!("../test/dhparams.pem");
let dh = Dh::from_pem(dh).unwrap();
let pkey = PKey::from_dh(dh).unwrap();
pkey.dh().unwrap();
assert!(pkey.rsa().is_err());
}
} }