From 56e6da112c4367af4860ee318c687153cc3ad0ae Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Wed, 27 Oct 2021 21:35:39 -0400 Subject: [PATCH] Expose EVP_EC_gen Closes #1538 --- openssl-sys/src/ec.rs | 11 +++++++++++ openssl-sys/src/evp.rs | 7 +++++++ openssl/src/pkey.rs | 23 +++++++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/openssl-sys/src/ec.rs b/openssl-sys/src/ec.rs index 22b7218a3..d74279186 100644 --- a/openssl-sys/src/ec.rs +++ b/openssl-sys/src/ec.rs @@ -1,4 +1,5 @@ use libc::*; +use std::ptr; use *; @@ -241,3 +242,13 @@ extern "C" { pub fn i2d_ECDSA_SIG(sig: *const ECDSA_SIG, out: *mut *mut c_uchar) -> c_int; } + +#[cfg(ossl300)] +pub unsafe fn EVP_EC_gen(curve: *const c_char) -> *mut EVP_PKEY { + EVP_PKEY_Q_keygen( + ptr::null_mut(), + ptr::null_mut(), + "EC\0".as_ptr().cast(), + curve, + ) +} diff --git a/openssl-sys/src/evp.rs b/openssl-sys/src/evp.rs index e5c2595d2..80146c316 100644 --- a/openssl-sys/src/evp.rs +++ b/openssl-sys/src/evp.rs @@ -525,6 +525,13 @@ extern "C" { 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; + #[cfg(ossl300)] + pub fn EVP_PKEY_Q_keygen( + libctx: *mut OSSL_LIB_CTX, + propq: *const c_char, + type_: *const c_char, + ... + ) -> *mut EVP_PKEY; pub fn EVP_PKEY_keygen_init(ctx: *mut EVP_PKEY_CTX) -> c_int; pub fn EVP_PKEY_keygen(ctx: *mut EVP_PKEY_CTX, key: *mut *mut EVP_PKEY) -> c_int; diff --git a/openssl/src/pkey.rs b/openssl/src/pkey.rs index 9d55e617c..2dbb6022a 100644 --- a/openssl/src/pkey.rs +++ b/openssl/src/pkey.rs @@ -602,6 +602,22 @@ impl PKey { PKey::generate_eddsa(ffi::EVP_PKEY_ED448) } + /// Generates a new EC key using the provided curve. + /// + /// This corresponds to [`EVP_EC_gen`]. + /// + /// Requires OpenSSL 3.0.0 or newer. + /// + /// [`EVP_EC_gen`]: https://www.openssl.org/docs/manmaster/man3/EVP_EC_gen.html + #[cfg(ossl300)] + pub fn ec_gen(curve: &str) -> Result, ErrorStack> { + let curve = CString::new(curve).unwrap(); + unsafe { + let ptr = cvt_p(ffi::EVP_EC_gen(curve.as_ptr()))?; + Ok(PKey::from_ptr(ptr)) + } + } + private_key_from_pem! { /// Deserializes a private key from a PEM-encoded key type specific format. /// @@ -1128,4 +1144,11 @@ mod tests { assert!(pkey.raw_private_key().is_err()); assert!(pkey.raw_public_key().is_err()); } + + #[cfg(ossl300)] + #[test] + fn test_ec_gen() { + let key = PKey::ec_gen("prime256v1").unwrap(); + assert!(key.ec_key().is_ok()); + } } -- GitLab