Add PKeyRef
This commit is contained in:
parent
4c7a5a418e
commit
57d10ebbc3
|
|
@ -1,6 +1,7 @@
|
|||
use libc::{c_void, c_char, c_int};
|
||||
use std::ptr;
|
||||
use std::mem;
|
||||
use std::ops::Deref;
|
||||
use ffi;
|
||||
|
||||
use {cvt, cvt_p};
|
||||
|
|
@ -9,13 +10,66 @@ use dsa::Dsa;
|
|||
use rsa::Rsa;
|
||||
use error::ErrorStack;
|
||||
use util::{CallbackState, invoke_passwd_cb};
|
||||
use opaque::Opaque;
|
||||
|
||||
/// A borrowed `PKey`.
|
||||
pub struct PKeyRef(Opaque);
|
||||
|
||||
impl PKeyRef {
|
||||
pub unsafe fn from_ptr<'a>(ptr: *mut ffi::EVP_PKEY) -> &'a PKeyRef {
|
||||
&*(ptr as *mut _)
|
||||
}
|
||||
|
||||
pub fn as_ptr(&self) -> *mut ffi::EVP_PKEY {
|
||||
self as *const _ as *mut _
|
||||
}
|
||||
|
||||
/// Get a reference to the interal RSA key for direct access to the key components
|
||||
pub fn rsa(&self) -> Result<Rsa, ErrorStack> {
|
||||
unsafe {
|
||||
let rsa = try!(cvt_p(ffi::EVP_PKEY_get1_RSA(self.as_ptr())));
|
||||
// this is safe as the ffi increments a reference counter to the internal key
|
||||
Ok(Rsa::from_ptr(rsa))
|
||||
}
|
||||
}
|
||||
|
||||
/// Stores private key as a PEM
|
||||
// FIXME: also add password and encryption
|
||||
pub fn private_key_to_pem(&self) -> Result<Vec<u8>, ErrorStack> {
|
||||
let mem_bio = try!(MemBio::new());
|
||||
unsafe {
|
||||
try!(cvt(ffi::PEM_write_bio_PrivateKey(mem_bio.as_ptr(),
|
||||
self.as_ptr(),
|
||||
ptr::null(),
|
||||
ptr::null_mut(),
|
||||
-1,
|
||||
None,
|
||||
ptr::null_mut())));
|
||||
|
||||
}
|
||||
Ok(mem_bio.get_buf().to_owned())
|
||||
}
|
||||
|
||||
/// Stores public key as a PEM
|
||||
pub fn public_key_to_pem(&self) -> Result<Vec<u8>, ErrorStack> {
|
||||
let mem_bio = try!(MemBio::new());
|
||||
unsafe {
|
||||
try!(cvt(ffi::PEM_write_bio_PUBKEY(mem_bio.as_ptr(), self.as_ptr())));
|
||||
}
|
||||
Ok(mem_bio.get_buf().to_owned())
|
||||
}
|
||||
|
||||
pub fn public_eq(&self, other: &PKeyRef) -> bool {
|
||||
unsafe { ffi::EVP_PKEY_cmp(self.as_ptr(), other.as_ptr()) == 1 }
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a public key, optionally with a private key attached.
|
||||
pub struct PKey(*mut ffi::EVP_PKEY);
|
||||
|
||||
unsafe impl Send for PKey {}
|
||||
unsafe impl Sync for PKey {}
|
||||
|
||||
/// Represents a public key, optionally with a private key attached.
|
||||
impl PKey {
|
||||
/// Create a new `PKey` containing an RSA key.
|
||||
pub fn from_rsa(rsa: Rsa) -> Result<PKey, ErrorStack> {
|
||||
|
|
@ -101,7 +155,7 @@ impl PKey {
|
|||
}
|
||||
}
|
||||
|
||||
/// assign RSA key to this pkey
|
||||
/// Assign an RSA key to this pkey.
|
||||
pub fn set_rsa(&mut self, rsa: &Rsa) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
// this needs to be a reference as the set1_RSA ups the reference count
|
||||
|
|
@ -110,49 +164,6 @@ impl PKey {
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a reference to the interal RSA key for direct access to the key components
|
||||
pub fn rsa(&self) -> Result<Rsa, ErrorStack> {
|
||||
unsafe {
|
||||
let rsa = try!(cvt_p(ffi::EVP_PKEY_get1_RSA(self.0)));
|
||||
// this is safe as the ffi increments a reference counter to the internal key
|
||||
Ok(Rsa::from_ptr(rsa))
|
||||
}
|
||||
}
|
||||
|
||||
/// Stores private key as a PEM
|
||||
// FIXME: also add password and encryption
|
||||
pub fn private_key_to_pem(&self) -> Result<Vec<u8>, ErrorStack> {
|
||||
let mem_bio = try!(MemBio::new());
|
||||
unsafe {
|
||||
try!(cvt(ffi::PEM_write_bio_PrivateKey(mem_bio.as_ptr(),
|
||||
self.0,
|
||||
ptr::null(),
|
||||
ptr::null_mut(),
|
||||
-1,
|
||||
None,
|
||||
ptr::null_mut())));
|
||||
|
||||
}
|
||||
Ok(mem_bio.get_buf().to_owned())
|
||||
}
|
||||
|
||||
/// Stores public key as a PEM
|
||||
pub fn public_key_to_pem(&self) -> Result<Vec<u8>, ErrorStack> {
|
||||
let mem_bio = try!(MemBio::new());
|
||||
unsafe {
|
||||
try!(cvt(ffi::PEM_write_bio_PUBKEY(mem_bio.as_ptr(), self.0)));
|
||||
}
|
||||
Ok(mem_bio.get_buf().to_owned())
|
||||
}
|
||||
|
||||
pub fn as_ptr(&self) -> *mut ffi::EVP_PKEY {
|
||||
return self.0;
|
||||
}
|
||||
|
||||
pub fn public_eq(&self, other: &PKey) -> bool {
|
||||
unsafe { ffi::EVP_PKEY_cmp(self.0, other.0) == 1 }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for PKey {
|
||||
|
|
@ -163,6 +174,16 @@ impl Drop for PKey {
|
|||
}
|
||||
}
|
||||
|
||||
impl Deref for PKey {
|
||||
type Target = PKeyRef;
|
||||
|
||||
fn deref(&self) -> &PKeyRef {
|
||||
unsafe {
|
||||
PKeyRef::from_ptr(self.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use dh::Dh;
|
|||
use error::ErrorStack;
|
||||
use ssl::{self, SslMethod, SslContextBuilder, SslContext, Ssl, SSL_VERIFY_PEER, SslStream,
|
||||
HandshakeError};
|
||||
use pkey::PKey;
|
||||
use pkey::PKeyRef;
|
||||
use x509::X509Ref;
|
||||
|
||||
// apps/dh2048.pem
|
||||
|
|
@ -85,7 +85,7 @@ impl ClientConnector {
|
|||
pub struct ServerConnectorBuilder(SslContextBuilder);
|
||||
|
||||
impl ServerConnectorBuilder {
|
||||
pub fn tls<I, T>(private_key: &PKey,
|
||||
pub fn tls<I, T>(private_key: &PKeyRef,
|
||||
certificate: &X509Ref,
|
||||
chain: I)
|
||||
-> Result<ServerConnectorBuilder, ErrorStack>
|
||||
|
|
@ -96,7 +96,7 @@ impl ServerConnectorBuilder {
|
|||
}
|
||||
|
||||
fn new<I, T>(method: SslMethod,
|
||||
private_key: &PKey,
|
||||
private_key: &PKeyRef,
|
||||
certificate: &X509Ref,
|
||||
chain: I)
|
||||
-> Result<ServerConnectorBuilder, ErrorStack>
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ use dh::Dh;
|
|||
use x509::{X509StoreContextRef, X509FileType, X509, X509Ref, X509VerifyError};
|
||||
#[cfg(any(ossl102, ossl110))]
|
||||
use verify::X509VerifyParamRef;
|
||||
use pkey::PKey;
|
||||
use pkey::PKeyRef;
|
||||
use error::ErrorStack;
|
||||
use opaque::Opaque;
|
||||
|
||||
|
|
@ -532,7 +532,7 @@ impl SslContextBuilder {
|
|||
}
|
||||
|
||||
/// Specifies the private key
|
||||
pub fn set_private_key(&mut self, key: &PKey) -> Result<(), ErrorStack> {
|
||||
pub fn set_private_key(&mut self, key: &PKeyRef) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
cvt(ffi::SSL_CTX_use_PrivateKey(self.as_ptr(), key.as_ptr())).map(|_| ())
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue