Add PKeyRef
This commit is contained in:
parent
4c7a5a418e
commit
57d10ebbc3
|
|
@ -1,6 +1,7 @@
|
||||||
use libc::{c_void, c_char, c_int};
|
use libc::{c_void, c_char, c_int};
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
use std::ops::Deref;
|
||||||
use ffi;
|
use ffi;
|
||||||
|
|
||||||
use {cvt, cvt_p};
|
use {cvt, cvt_p};
|
||||||
|
|
@ -9,13 +10,66 @@ use dsa::Dsa;
|
||||||
use rsa::Rsa;
|
use rsa::Rsa;
|
||||||
use error::ErrorStack;
|
use error::ErrorStack;
|
||||||
use util::{CallbackState, invoke_passwd_cb};
|
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);
|
pub struct PKey(*mut ffi::EVP_PKEY);
|
||||||
|
|
||||||
unsafe impl Send for PKey {}
|
unsafe impl Send for PKey {}
|
||||||
unsafe impl Sync for PKey {}
|
unsafe impl Sync for PKey {}
|
||||||
|
|
||||||
/// Represents a public key, optionally with a private key attached.
|
|
||||||
impl PKey {
|
impl PKey {
|
||||||
/// Create a new `PKey` containing an RSA key.
|
/// Create 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> {
|
||||||
|
|
@ -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> {
|
pub fn set_rsa(&mut self, rsa: &Rsa) -> Result<(), ErrorStack> {
|
||||||
unsafe {
|
unsafe {
|
||||||
// this needs to be a reference as the set1_RSA ups the reference count
|
// this needs to be a reference as the set1_RSA ups the reference count
|
||||||
|
|
@ -110,49 +164,6 @@ impl PKey {
|
||||||
Ok(())
|
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 {
|
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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use dh::Dh;
|
||||||
use error::ErrorStack;
|
use error::ErrorStack;
|
||||||
use ssl::{self, SslMethod, SslContextBuilder, SslContext, Ssl, SSL_VERIFY_PEER, SslStream,
|
use ssl::{self, SslMethod, SslContextBuilder, SslContext, Ssl, SSL_VERIFY_PEER, SslStream,
|
||||||
HandshakeError};
|
HandshakeError};
|
||||||
use pkey::PKey;
|
use pkey::PKeyRef;
|
||||||
use x509::X509Ref;
|
use x509::X509Ref;
|
||||||
|
|
||||||
// apps/dh2048.pem
|
// apps/dh2048.pem
|
||||||
|
|
@ -85,7 +85,7 @@ impl ClientConnector {
|
||||||
pub struct ServerConnectorBuilder(SslContextBuilder);
|
pub struct ServerConnectorBuilder(SslContextBuilder);
|
||||||
|
|
||||||
impl ServerConnectorBuilder {
|
impl ServerConnectorBuilder {
|
||||||
pub fn tls<I, T>(private_key: &PKey,
|
pub fn tls<I, T>(private_key: &PKeyRef,
|
||||||
certificate: &X509Ref,
|
certificate: &X509Ref,
|
||||||
chain: I)
|
chain: I)
|
||||||
-> Result<ServerConnectorBuilder, ErrorStack>
|
-> Result<ServerConnectorBuilder, ErrorStack>
|
||||||
|
|
@ -96,7 +96,7 @@ impl ServerConnectorBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new<I, T>(method: SslMethod,
|
fn new<I, T>(method: SslMethod,
|
||||||
private_key: &PKey,
|
private_key: &PKeyRef,
|
||||||
certificate: &X509Ref,
|
certificate: &X509Ref,
|
||||||
chain: I)
|
chain: I)
|
||||||
-> Result<ServerConnectorBuilder, ErrorStack>
|
-> Result<ServerConnectorBuilder, ErrorStack>
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ use dh::Dh;
|
||||||
use x509::{X509StoreContextRef, X509FileType, X509, X509Ref, X509VerifyError};
|
use x509::{X509StoreContextRef, X509FileType, X509, X509Ref, X509VerifyError};
|
||||||
#[cfg(any(ossl102, ossl110))]
|
#[cfg(any(ossl102, ossl110))]
|
||||||
use verify::X509VerifyParamRef;
|
use verify::X509VerifyParamRef;
|
||||||
use pkey::PKey;
|
use pkey::PKeyRef;
|
||||||
use error::ErrorStack;
|
use error::ErrorStack;
|
||||||
use opaque::Opaque;
|
use opaque::Opaque;
|
||||||
|
|
||||||
|
|
@ -532,7 +532,7 @@ impl SslContextBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Specifies the private key
|
/// 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 {
|
unsafe {
|
||||||
cvt(ffi::SSL_CTX_use_PrivateKey(self.as_ptr(), key.as_ptr())).map(|_| ())
|
cvt(ffi::SSL_CTX_use_PrivateKey(self.as_ptr(), key.as_ptr())).map(|_| ())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue