Commit 56e6da11 authored by Steven Fackler's avatar Steven Fackler
Browse files

Expose EVP_EC_gen

Closes #1538
parent cac01f8f
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
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,
    )
}
+7 −0
Original line number Diff line number Diff line
@@ -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;

+23 −0
Original line number Diff line number Diff line
@@ -602,6 +602,22 @@ impl PKey<Private> {
        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<PKey<Private>, 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());
    }
}