From 7ce0835b7463016623af8cb98654607512f9680f Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Tue, 1 Oct 2019 18:45:10 -0700 Subject: [PATCH] Implement Clone for PKey --- openssl-sys/src/crypto.rs | 2 ++ openssl-sys/src/evp.rs | 2 ++ openssl/src/pkey.rs | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/openssl-sys/src/crypto.rs b/openssl-sys/src/crypto.rs index 24e495cd..6d8096f7 100644 --- a/openssl-sys/src/crypto.rs +++ b/openssl-sys/src/crypto.rs @@ -5,6 +5,8 @@ use *; #[cfg(not(ossl110))] pub const CRYPTO_LOCK_X509: c_int = 3; #[cfg(not(ossl110))] +pub const CRYPTO_LOCK_EVP_PKEY: c_int = 10; +#[cfg(not(ossl110))] pub const CRYPTO_LOCK_SSL_CTX: c_int = 12; #[cfg(not(ossl110))] pub const CRYPTO_LOCK_SSL_SESSION: c_int = 14; diff --git a/openssl-sys/src/evp.rs b/openssl-sys/src/evp.rs index 140e6a36..b248f7f9 100644 --- a/openssl-sys/src/evp.rs +++ b/openssl-sys/src/evp.rs @@ -304,6 +304,8 @@ extern "C" { pub fn EVP_PKEY_new() -> *mut EVP_PKEY; pub fn EVP_PKEY_free(k: *mut EVP_PKEY); + #[cfg(any(ossl110, libressl270))] + pub fn EVP_PKEY_up_ref(pkey: *mut EVP_PKEY) -> c_int; pub fn d2i_AutoPrivateKey( a: *mut *mut EVP_PKEY, diff --git a/openssl/src/pkey.rs b/openssl/src/pkey.rs index f05f5f15..f1ab1e2e 100644 --- a/openssl/src/pkey.rs +++ b/openssl/src/pkey.rs @@ -126,6 +126,17 @@ generic_foreign_type_and_impl_send_sync! { pub struct PKeyRef; } +impl ToOwned for PKeyRef { + type Owned = PKey; + + fn to_owned(&self) -> PKey { + unsafe { + EVP_PKEY_up_ref(self.as_ptr()); + PKey::from_ptr(self.as_ptr()) + } + } +} + impl PKeyRef { /// Returns a copy of the internal RSA key. /// @@ -272,6 +283,12 @@ where } } +impl Clone for PKey { + fn clone(&self) -> PKey { + PKeyRef::to_owned(self) + } +} + impl PKey { /// Creates a new `PKey` containing an RSA key. /// @@ -584,6 +601,22 @@ impl PKey { } } +cfg_if! { + if #[cfg(any(ossl110, libressl270))] { + use ffi::EVP_PKEY_up_ref; + } else { + unsafe extern "C" fn EVP_PKEY_up_ref(pkey: *mut ffi::EVP_PKEY) { + ffi::CRYPTO_add_lock( + &mut (*pkey).references, + 1, + ffi::CRYPTO_LOCK_EVP_PKEY, + "pkey.rs\0".as_ptr() as *const _, + line!() as c_int, + ); + } + } +} + #[cfg(test)] mod tests { use dh::Dh;