From 335b96beae6a2a3aea50c4da96257e9ed281ada3 Mon Sep 17 00:00:00 2001 From: Facundo Tuesca Date: Thu, 4 Jan 2024 14:08:33 +0100 Subject: [PATCH 1/7] Add support for setting the nonce type and digest on a PKEY_CTX --- openssl-sys/src/handwritten/evp.rs | 19 ++++ openssl-sys/src/handwritten/types.rs | 10 ++ openssl/CHANGELOG.md | 6 ++ openssl/src/pkey_ctx.rs | 154 +++++++++++++++++++++++++++ 4 files changed, 189 insertions(+) diff --git a/openssl-sys/src/handwritten/evp.rs b/openssl-sys/src/handwritten/evp.rs index fabb13383e..33c28accc1 100644 --- a/openssl-sys/src/handwritten/evp.rs +++ b/openssl-sys/src/handwritten/evp.rs @@ -538,6 +538,12 @@ extern "C" { #[cfg(ossl300)] pub fn EVP_PKEY_CTX_set_signature_md(ctx: *mut EVP_PKEY_CTX, md: *const EVP_MD) -> c_int; + #[cfg(ossl300)] + pub fn EVP_PKEY_CTX_set_params(ctx: *mut EVP_PKEY_CTX, params: *const OSSL_PARAM) -> c_int; + + #[cfg(ossl300)] + pub fn EVP_PKEY_CTX_get_params(ctx: *mut EVP_PKEY_CTX, params: *mut OSSL_PARAM) -> c_int; + pub fn EVP_PKEY_new_mac_key( type_: c_int, e: *mut ENGINE, @@ -646,3 +652,16 @@ extern "C" { pub fn EVP_EncodeBlock(dst: *mut c_uchar, src: *const c_uchar, src_len: c_int) -> c_int; pub fn EVP_DecodeBlock(dst: *mut c_uchar, src: *const c_uchar, src_len: c_int) -> c_int; } + +extern "C" { + #[cfg(ossl300)] + pub fn OSSL_PARAM_construct_uint(key: *const c_char, buf: *mut c_uint) -> OSSL_PARAM; + #[cfg(ossl300)] + pub fn OSSL_PARAM_construct_utf8_string( + key: *const c_char, + buf: *mut c_char, + bsize: size_t, + ) -> OSSL_PARAM; + #[cfg(ossl300)] + pub fn OSSL_PARAM_construct_end() -> OSSL_PARAM; +} diff --git a/openssl-sys/src/handwritten/types.rs b/openssl-sys/src/handwritten/types.rs index a03a878305..57c8113aa4 100644 --- a/openssl-sys/src/handwritten/types.rs +++ b/openssl-sys/src/handwritten/types.rs @@ -1093,3 +1093,13 @@ pub enum OSSL_PROVIDER {} #[cfg(ossl300)] pub enum OSSL_LIB_CTX {} + +#[cfg(ossl300)] +#[repr(C)] +pub struct OSSL_PARAM { + key: *const c_char, + data_type: c_uchar, + data: *mut c_void, + data_size: size_t, + return_size: size_t, +} diff --git a/openssl/CHANGELOG.md b/openssl/CHANGELOG.md index 8b34e48cab..f0a56e9c50 100644 --- a/openssl/CHANGELOG.md +++ b/openssl/CHANGELOG.md @@ -2,6 +2,12 @@ ## [Unreleased] +### Added + +* Added `PkeyCtxRef::{digest, set_digest, nonce_type, set_nonce_type}`. +* Added `OSSL_PARAM`, `OSSL_PARAM_construct_uint` , `OSSL_PARAM_construct_utf8_string`, `OSSL_PARAM_construct_end` to openssl-sys. +* Added `EVP_PKEY_CTX_set_params` and `EVP_PKEY_CTX_get_params` to openssl-sys. + ## [v0.10.63] - 2024-01-19 ### Added diff --git a/openssl/src/pkey_ctx.rs b/openssl/src/pkey_ctx.rs index 85778e2166..e039bab81e 100644 --- a/openssl/src/pkey_ctx.rs +++ b/openssl/src/pkey_ctx.rs @@ -67,6 +67,8 @@ let cmac_key = ctx.keygen().unwrap(); #[cfg(not(boringssl))] use crate::cipher::CipherRef; use crate::error::ErrorStack; +#[cfg(ossl300)] +use crate::hash::MessageDigest; use crate::md::MdRef; use crate::pkey::{HasPrivate, HasPublic, Id, PKey, PKeyRef, Private}; use crate::rsa::Padding; @@ -75,8 +77,12 @@ use crate::{cvt, cvt_p}; use foreign_types::{ForeignType, ForeignTypeRef}; #[cfg(not(boringssl))] use libc::c_int; +#[cfg(ossl320)] +use libc::c_uint; use openssl_macros::corresponds; use std::convert::TryFrom; +#[cfg(ossl300)] +use std::ffi::CString; use std::ptr; /// HKDF modes of operation. @@ -105,6 +111,21 @@ impl HkdfMode { pub const EXPAND_ONLY: Self = HkdfMode(ffi::EVP_PKEY_HKDEF_MODE_EXPAND_ONLY); } +/// Nonce type for ECDSA and DSA. +#[cfg(ossl320)] +#[derive(Debug, PartialEq)] +pub struct NonceType(c_uint); + +#[cfg(ossl320)] +impl NonceType { + /// This is the default mode. It uses a random value for the nonce k as defined in FIPS 186-4 Section 6.3 + /// “Secret Number Generation”. + pub const RANDOM_K: Self = NonceType(0); + + /// Uses a deterministic value for the nonce k as defined in RFC #6979 (See Section 3.2 “Generation of k”). + pub const DETERMINISTIC_K: Self = NonceType(1); +} + generic_foreign_type_and_impl_send_sync! { type CType = ffi::EVP_PKEY_CTX; fn drop = ffi::EVP_PKEY_CTX_free; @@ -714,6 +735,109 @@ impl PkeyCtxRef { Ok(PKey::from_ptr(key)) } } + + /// Sets the digest algorithm for a private key context. + /// + /// Requires OpenSSL 3.0.0 or newer. + #[cfg(ossl300)] + #[corresponds(EVP_PKEY_CTX_set_params)] + pub fn set_digest(&mut self, hash_algorithm: MessageDigest) -> Result<(), ErrorStack> { + let digest_name = hash_algorithm.type_().short_name()?; + let digest = CString::new(digest_name).unwrap().into_raw(); + let digest_field_name = CString::new("digest").unwrap(); + unsafe { + let param_digest = ffi::OSSL_PARAM_construct_utf8_string( + digest_field_name.as_ptr(), + digest, + digest_name.len(), + ); + let param_end = ffi::OSSL_PARAM_construct_end(); + + let params = [param_digest, param_end]; + cvt(ffi::EVP_PKEY_CTX_set_params(self.as_ptr(), params.as_ptr()))?; + + // retake pointer to free memory + let _ = CString::from_raw(digest); + } + Ok(()) + } + + /// Gets the digest algorithm for a private key context. + /// + /// Requires OpenSSL 3.0.0 or newer. + #[cfg(ossl300)] + #[corresponds(EVP_PKEY_CTX_get_params)] + pub fn digest(&mut self) -> Result, ErrorStack> { + use libc::c_char; + // From openssl/internal/sizes.h + let ossl_max_name_size = 50usize; + let digest_field_name = CString::new("digest").unwrap(); + let digest: *mut c_char = CString::new(vec![1; ossl_max_name_size]) + .unwrap() + .into_raw(); + unsafe { + let param_digest = ffi::OSSL_PARAM_construct_utf8_string( + digest_field_name.as_ptr(), + digest, + ossl_max_name_size, + ); + let param_end = ffi::OSSL_PARAM_construct_end(); + let mut params = [param_digest, param_end]; + cvt(ffi::EVP_PKEY_CTX_get_params( + self.as_ptr(), + params.as_mut_ptr(), + ))?; + let digest_str = CString::from_raw(digest); + Ok(MessageDigest::from_name(digest_str.to_str().unwrap())) + } + } + + /// Sets the nonce type for a private key context. + /// + /// The nonce for DSA and ECDSA can be either random (the default) or deterministic (as defined by RFC 6979). + /// + /// This is only useful for DSA and ECDSA. + /// Requires OpenSSL 3.2.0 or newer. + #[cfg(ossl320)] + #[corresponds(EVP_PKEY_CTX_set_params)] + pub fn set_nonce_type(&mut self, nonce_type: NonceType) -> Result<(), ErrorStack> { + let nonce_field_name = CString::new("nonce-type").unwrap(); + let mut nonce_type = nonce_type.0; + unsafe { + let param_nonce = + ffi::OSSL_PARAM_construct_uint(nonce_field_name.as_ptr(), &mut nonce_type); + let param_end = ffi::OSSL_PARAM_construct_end(); + + let params = [param_nonce, param_end]; + cvt(ffi::EVP_PKEY_CTX_set_params(self.as_ptr(), params.as_ptr()))?; + } + Ok(()) + } + + /// Gets the nonce type for a private key context. + /// + /// The nonce for DSA and ECDSA can be either random (the default) or deterministic (as defined by RFC 6979). + /// + /// This is only useful for DSA and ECDSA. + /// Requires OpenSSL 3.2.0 or newer. + #[cfg(ossl320)] + #[corresponds(EVP_PKEY_CTX_get_params)] + pub fn nonce_type(&mut self) -> Result { + let nonce_field_name = CString::new("nonce-type").unwrap(); + let mut nonce_type: c_uint = 0; + unsafe { + let param_nonce = + ffi::OSSL_PARAM_construct_uint(nonce_field_name.as_ptr(), &mut nonce_type); + let param_end = ffi::OSSL_PARAM_construct_end(); + + let mut params = [param_nonce, param_end]; + cvt(ffi::EVP_PKEY_CTX_get_params( + self.as_ptr(), + params.as_mut_ptr(), + ))?; + } + Ok(NonceType(nonce_type)) + } } #[cfg(test)] @@ -999,4 +1123,34 @@ mod test { // The digest is the end of the DigestInfo structure. assert_eq!(result_buf[length - digest.len()..length], digest); } + + #[test] + #[cfg(ossl300)] + fn set_digest() { + let key1 = + EcKey::generate(&EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap()).unwrap(); + let key1 = PKey::from_ec_key(key1).unwrap(); + + let mut ctx = PkeyCtx::new(&key1).unwrap(); + ctx.sign_init().unwrap(); + ctx.set_digest(MessageDigest::sha224()).unwrap(); + let digest_name = ctx.digest().unwrap().unwrap().type_(); + assert_eq!(digest_name, MessageDigest::sha224().type_()); + assert!(ErrorStack::get().errors().is_empty()); + } + + #[test] + #[cfg(ossl320)] + fn set_nonce_type() { + let key1 = + EcKey::generate(&EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap()).unwrap(); + let key1 = PKey::from_ec_key(key1).unwrap(); + + let mut ctx = PkeyCtx::new(&key1).unwrap(); + ctx.sign_init().unwrap(); + ctx.set_nonce_type(NonceType::DETERMINISTIC_K).unwrap(); + let nonce_type = ctx.nonce_type().unwrap(); + assert_eq!(nonce_type, NonceType::DETERMINISTIC_K); + assert!(ErrorStack::get().errors().is_empty()); + } } From e77c613db1bc5c46ae413fb4adc9f377549ab526 Mon Sep 17 00:00:00 2001 From: Facundo Tuesca Date: Mon, 5 Feb 2024 17:56:25 +0100 Subject: [PATCH 2/7] Remove unnecessary PkeyCtxRef::set_digest function --- openssl-sys/CHANGELOG.md | 5 +++++ openssl/CHANGELOG.md | 4 +--- openssl/src/pkey_ctx.rs | 34 ++++------------------------------ 3 files changed, 10 insertions(+), 33 deletions(-) diff --git a/openssl-sys/CHANGELOG.md b/openssl-sys/CHANGELOG.md index ba024b68e6..b1822b31c0 100644 --- a/openssl-sys/CHANGELOG.md +++ b/openssl-sys/CHANGELOG.md @@ -2,6 +2,11 @@ ## [Unreleased] +### Added + +* Added `OSSL_PARAM`, `OSSL_PARAM_construct_uint` , `OSSL_PARAM_construct_utf8_string`, `OSSL_PARAM_construct_end`. +* Added `EVP_PKEY_CTX_set_params` and `EVP_PKEY_CTX_get_params`. + ## [v0.9.99] - 2024-01-19 ### Added diff --git a/openssl/CHANGELOG.md b/openssl/CHANGELOG.md index f0a56e9c50..8392c1bdea 100644 --- a/openssl/CHANGELOG.md +++ b/openssl/CHANGELOG.md @@ -4,9 +4,7 @@ ### Added -* Added `PkeyCtxRef::{digest, set_digest, nonce_type, set_nonce_type}`. -* Added `OSSL_PARAM`, `OSSL_PARAM_construct_uint` , `OSSL_PARAM_construct_utf8_string`, `OSSL_PARAM_construct_end` to openssl-sys. -* Added `EVP_PKEY_CTX_set_params` and `EVP_PKEY_CTX_get_params` to openssl-sys. +* Added `PkeyCtxRef::{digest, nonce_type, set_nonce_type}`. ## [v0.10.63] - 2024-01-19 diff --git a/openssl/src/pkey_ctx.rs b/openssl/src/pkey_ctx.rs index e039bab81e..f4b46f8cef 100644 --- a/openssl/src/pkey_ctx.rs +++ b/openssl/src/pkey_ctx.rs @@ -736,32 +736,6 @@ impl PkeyCtxRef { } } - /// Sets the digest algorithm for a private key context. - /// - /// Requires OpenSSL 3.0.0 or newer. - #[cfg(ossl300)] - #[corresponds(EVP_PKEY_CTX_set_params)] - pub fn set_digest(&mut self, hash_algorithm: MessageDigest) -> Result<(), ErrorStack> { - let digest_name = hash_algorithm.type_().short_name()?; - let digest = CString::new(digest_name).unwrap().into_raw(); - let digest_field_name = CString::new("digest").unwrap(); - unsafe { - let param_digest = ffi::OSSL_PARAM_construct_utf8_string( - digest_field_name.as_ptr(), - digest, - digest_name.len(), - ); - let param_end = ffi::OSSL_PARAM_construct_end(); - - let params = [param_digest, param_end]; - cvt(ffi::EVP_PKEY_CTX_set_params(self.as_ptr(), params.as_ptr()))?; - - // retake pointer to free memory - let _ = CString::from_raw(digest); - } - Ok(()) - } - /// Gets the digest algorithm for a private key context. /// /// Requires OpenSSL 3.0.0 or newer. @@ -1126,16 +1100,16 @@ mod test { #[test] #[cfg(ossl300)] - fn set_digest() { + fn set_signature_md() { let key1 = EcKey::generate(&EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap()).unwrap(); let key1 = PKey::from_ec_key(key1).unwrap(); let mut ctx = PkeyCtx::new(&key1).unwrap(); ctx.sign_init().unwrap(); - ctx.set_digest(MessageDigest::sha224()).unwrap(); - let digest_name = ctx.digest().unwrap().unwrap().type_(); - assert_eq!(digest_name, MessageDigest::sha224().type_()); + ctx.set_signature_md(Md::sha224()).unwrap(); + let digest_nid = ctx.digest().unwrap().unwrap().type_(); + assert_eq!(digest_nid, Md::sha224().type_()); assert!(ErrorStack::get().errors().is_empty()); } From 76043a99817599377cbd8d1c83ae93f43ebb0e65 Mon Sep 17 00:00:00 2001 From: Facundo Tuesca Date: Mon, 5 Feb 2024 18:04:49 +0100 Subject: [PATCH 3/7] Move OSSL_PARAM definitions to new file --- openssl-sys/src/handwritten/evp.rs | 13 ------------- openssl-sys/src/handwritten/mod.rs | 2 ++ openssl-sys/src/handwritten/params.rs | 15 +++++++++++++++ 3 files changed, 17 insertions(+), 13 deletions(-) create mode 100644 openssl-sys/src/handwritten/params.rs diff --git a/openssl-sys/src/handwritten/evp.rs b/openssl-sys/src/handwritten/evp.rs index 33c28accc1..7da39e3bd8 100644 --- a/openssl-sys/src/handwritten/evp.rs +++ b/openssl-sys/src/handwritten/evp.rs @@ -652,16 +652,3 @@ extern "C" { pub fn EVP_EncodeBlock(dst: *mut c_uchar, src: *const c_uchar, src_len: c_int) -> c_int; pub fn EVP_DecodeBlock(dst: *mut c_uchar, src: *const c_uchar, src_len: c_int) -> c_int; } - -extern "C" { - #[cfg(ossl300)] - pub fn OSSL_PARAM_construct_uint(key: *const c_char, buf: *mut c_uint) -> OSSL_PARAM; - #[cfg(ossl300)] - pub fn OSSL_PARAM_construct_utf8_string( - key: *const c_char, - buf: *mut c_char, - bsize: size_t, - ) -> OSSL_PARAM; - #[cfg(ossl300)] - pub fn OSSL_PARAM_construct_end() -> OSSL_PARAM; -} diff --git a/openssl-sys/src/handwritten/mod.rs b/openssl-sys/src/handwritten/mod.rs index d3adfa5a13..f54ec9be5e 100644 --- a/openssl-sys/src/handwritten/mod.rs +++ b/openssl-sys/src/handwritten/mod.rs @@ -15,6 +15,7 @@ pub use self::hmac::*; pub use self::kdf::*; pub use self::object::*; pub use self::ocsp::*; +pub use self::params::*; pub use self::pem::*; pub use self::pkcs12::*; pub use self::pkcs7::*; @@ -51,6 +52,7 @@ mod hmac; mod kdf; mod object; mod ocsp; +mod params; mod pem; mod pkcs12; mod pkcs7; diff --git a/openssl-sys/src/handwritten/params.rs b/openssl-sys/src/handwritten/params.rs new file mode 100644 index 0000000000..5e1401c678 --- /dev/null +++ b/openssl-sys/src/handwritten/params.rs @@ -0,0 +1,15 @@ +use super::super::*; +use libc::*; + +extern "C" { + #[cfg(ossl300)] + pub fn OSSL_PARAM_construct_uint(key: *const c_char, buf: *mut c_uint) -> OSSL_PARAM; + #[cfg(ossl300)] + pub fn OSSL_PARAM_construct_utf8_string( + key: *const c_char, + buf: *mut c_char, + bsize: size_t, + ) -> OSSL_PARAM; + #[cfg(ossl300)] + pub fn OSSL_PARAM_construct_end() -> OSSL_PARAM; +} From 7a66dad2197e6f6762fd8ec3ce270f7b9cd2dd4d Mon Sep 17 00:00:00 2001 From: Facundo Tuesca Date: Mon, 5 Feb 2024 19:50:51 +0100 Subject: [PATCH 4/7] Add test vector for ECDSA with deterministic signature --- openssl/src/pkey_ctx.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/openssl/src/pkey_ctx.rs b/openssl/src/pkey_ctx.rs index f4b46f8cef..3056e4eeef 100644 --- a/openssl/src/pkey_ctx.rs +++ b/openssl/src/pkey_ctx.rs @@ -1127,4 +1127,31 @@ mod test { assert_eq!(nonce_type, NonceType::DETERMINISTIC_K); assert!(ErrorStack::get().errors().is_empty()); } + + // Test vector from + // https://github.com/openssl/openssl/blob/openssl-3.2.0/test/recipes/30-test_evp_data/evppkey_ecdsa_rfc6979.txt + #[test] + #[cfg(ossl320)] + fn ecdsa_deterministic_signature() { + let private_key_pem = "-----BEGIN PRIVATE KEY----- +MDkCAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQEEHzAdAgEBBBhvqwNJNOTA/Jrmf1tWWanX0f79GH7g +n9Q= +-----END PRIVATE KEY-----"; + + let key1 = EcKey::private_key_from_pem(private_key_pem.as_bytes()).unwrap(); + let key1 = PKey::from_ec_key(key1).unwrap(); + let input = "sample"; + let expected_output = hex::decode("303502190098C6BD12B23EAF5E2A2045132086BE3EB8EBD62ABF6698FF021857A22B07DEA9530F8DE9471B1DC6624472E8E2844BC25B64").unwrap(); + + let hashed_input = hash(MessageDigest::sha1(), input.as_bytes()).unwrap(); + let mut ctx = PkeyCtx::new(&key1).unwrap(); + ctx.sign_init().unwrap(); + ctx.set_signature_md(Md::sha1()).unwrap(); + ctx.set_nonce_type(NonceType::DETERMINISTIC_K).unwrap(); + + let mut output = vec![]; + ctx.sign_to_vec(&hashed_input, &mut output).unwrap(); + assert_eq!(output, expected_output); + assert!(ErrorStack::get().errors().is_empty()); + } } From ce5e9e4e6c48415ecd160fb530cecef4d5f3bc9a Mon Sep 17 00:00:00 2001 From: Facundo Tuesca Date: Tue, 6 Feb 2024 10:54:19 +0100 Subject: [PATCH 5/7] Remove PkeyCtxRef::digest() getter --- openssl-sys/CHANGELOG.md | 2 +- openssl-sys/src/handwritten/params.rs | 6 ---- openssl/CHANGELOG.md | 2 +- openssl/src/pkey_ctx.rs | 49 +-------------------------- 4 files changed, 3 insertions(+), 56 deletions(-) diff --git a/openssl-sys/CHANGELOG.md b/openssl-sys/CHANGELOG.md index b1822b31c0..ce85d14f88 100644 --- a/openssl-sys/CHANGELOG.md +++ b/openssl-sys/CHANGELOG.md @@ -4,7 +4,7 @@ ### Added -* Added `OSSL_PARAM`, `OSSL_PARAM_construct_uint` , `OSSL_PARAM_construct_utf8_string`, `OSSL_PARAM_construct_end`. +* Added `OSSL_PARAM`, `OSSL_PARAM_construct_uint` , `OSSL_PARAM_construct_end`. * Added `EVP_PKEY_CTX_set_params` and `EVP_PKEY_CTX_get_params`. ## [v0.9.99] - 2024-01-19 diff --git a/openssl-sys/src/handwritten/params.rs b/openssl-sys/src/handwritten/params.rs index 5e1401c678..3ed00c0488 100644 --- a/openssl-sys/src/handwritten/params.rs +++ b/openssl-sys/src/handwritten/params.rs @@ -5,11 +5,5 @@ extern "C" { #[cfg(ossl300)] pub fn OSSL_PARAM_construct_uint(key: *const c_char, buf: *mut c_uint) -> OSSL_PARAM; #[cfg(ossl300)] - pub fn OSSL_PARAM_construct_utf8_string( - key: *const c_char, - buf: *mut c_char, - bsize: size_t, - ) -> OSSL_PARAM; - #[cfg(ossl300)] pub fn OSSL_PARAM_construct_end() -> OSSL_PARAM; } diff --git a/openssl/CHANGELOG.md b/openssl/CHANGELOG.md index 8392c1bdea..b3a576bc98 100644 --- a/openssl/CHANGELOG.md +++ b/openssl/CHANGELOG.md @@ -4,7 +4,7 @@ ### Added -* Added `PkeyCtxRef::{digest, nonce_type, set_nonce_type}`. +* Added `PkeyCtxRef::{nonce_type, set_nonce_type}`. ## [v0.10.63] - 2024-01-19 diff --git a/openssl/src/pkey_ctx.rs b/openssl/src/pkey_ctx.rs index 3056e4eeef..7bb6696b3c 100644 --- a/openssl/src/pkey_ctx.rs +++ b/openssl/src/pkey_ctx.rs @@ -67,8 +67,6 @@ let cmac_key = ctx.keygen().unwrap(); #[cfg(not(boringssl))] use crate::cipher::CipherRef; use crate::error::ErrorStack; -#[cfg(ossl300)] -use crate::hash::MessageDigest; use crate::md::MdRef; use crate::pkey::{HasPrivate, HasPublic, Id, PKey, PKeyRef, Private}; use crate::rsa::Padding; @@ -81,7 +79,7 @@ use libc::c_int; use libc::c_uint; use openssl_macros::corresponds; use std::convert::TryFrom; -#[cfg(ossl300)] +#[cfg(ossl320)] use std::ffi::CString; use std::ptr; @@ -736,36 +734,6 @@ impl PkeyCtxRef { } } - /// Gets the digest algorithm for a private key context. - /// - /// Requires OpenSSL 3.0.0 or newer. - #[cfg(ossl300)] - #[corresponds(EVP_PKEY_CTX_get_params)] - pub fn digest(&mut self) -> Result, ErrorStack> { - use libc::c_char; - // From openssl/internal/sizes.h - let ossl_max_name_size = 50usize; - let digest_field_name = CString::new("digest").unwrap(); - let digest: *mut c_char = CString::new(vec![1; ossl_max_name_size]) - .unwrap() - .into_raw(); - unsafe { - let param_digest = ffi::OSSL_PARAM_construct_utf8_string( - digest_field_name.as_ptr(), - digest, - ossl_max_name_size, - ); - let param_end = ffi::OSSL_PARAM_construct_end(); - let mut params = [param_digest, param_end]; - cvt(ffi::EVP_PKEY_CTX_get_params( - self.as_ptr(), - params.as_mut_ptr(), - ))?; - let digest_str = CString::from_raw(digest); - Ok(MessageDigest::from_name(digest_str.to_str().unwrap())) - } - } - /// Sets the nonce type for a private key context. /// /// The nonce for DSA and ECDSA can be either random (the default) or deterministic (as defined by RFC 6979). @@ -1098,21 +1066,6 @@ mod test { assert_eq!(result_buf[length - digest.len()..length], digest); } - #[test] - #[cfg(ossl300)] - fn set_signature_md() { - let key1 = - EcKey::generate(&EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap()).unwrap(); - let key1 = PKey::from_ec_key(key1).unwrap(); - - let mut ctx = PkeyCtx::new(&key1).unwrap(); - ctx.sign_init().unwrap(); - ctx.set_signature_md(Md::sha224()).unwrap(); - let digest_nid = ctx.digest().unwrap().unwrap().type_(); - assert_eq!(digest_nid, Md::sha224().type_()); - assert!(ErrorStack::get().errors().is_empty()); - } - #[test] #[cfg(ossl320)] fn set_nonce_type() { From 870e290c1a6b2ab6acf0ad345cfe9b8c371afea9 Mon Sep 17 00:00:00 2001 From: Facundo Tuesca Date: Thu, 8 Feb 2024 14:48:16 +0100 Subject: [PATCH 6/7] Use CStr to avoid heap allocation --- openssl/src/pkey_ctx.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openssl/src/pkey_ctx.rs b/openssl/src/pkey_ctx.rs index 7bb6696b3c..69dfb7431e 100644 --- a/openssl/src/pkey_ctx.rs +++ b/openssl/src/pkey_ctx.rs @@ -80,7 +80,7 @@ use libc::c_uint; use openssl_macros::corresponds; use std::convert::TryFrom; #[cfg(ossl320)] -use std::ffi::CString; +use std::ffi::CStr; use std::ptr; /// HKDF modes of operation. @@ -743,7 +743,7 @@ impl PkeyCtxRef { #[cfg(ossl320)] #[corresponds(EVP_PKEY_CTX_set_params)] pub fn set_nonce_type(&mut self, nonce_type: NonceType) -> Result<(), ErrorStack> { - let nonce_field_name = CString::new("nonce-type").unwrap(); + let nonce_field_name = CStr::from_bytes_with_nul("nonce-type\0".as_bytes()).unwrap(); let mut nonce_type = nonce_type.0; unsafe { let param_nonce = @@ -765,7 +765,7 @@ impl PkeyCtxRef { #[cfg(ossl320)] #[corresponds(EVP_PKEY_CTX_get_params)] pub fn nonce_type(&mut self) -> Result { - let nonce_field_name = CString::new("nonce-type").unwrap(); + let nonce_field_name = CStr::from_bytes_with_nul("nonce-type\0".as_bytes()).unwrap(); let mut nonce_type: c_uint = 0; unsafe { let param_nonce = From 14c82479cbddb791c09953dfa5551a9b07e73177 Mon Sep 17 00:00:00 2001 From: Facundo Tuesca Date: Thu, 8 Feb 2024 14:58:56 +0100 Subject: [PATCH 7/7] Readability improvement --- openssl/src/pkey_ctx.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openssl/src/pkey_ctx.rs b/openssl/src/pkey_ctx.rs index 69dfb7431e..add7830484 100644 --- a/openssl/src/pkey_ctx.rs +++ b/openssl/src/pkey_ctx.rs @@ -743,7 +743,7 @@ impl PkeyCtxRef { #[cfg(ossl320)] #[corresponds(EVP_PKEY_CTX_set_params)] pub fn set_nonce_type(&mut self, nonce_type: NonceType) -> Result<(), ErrorStack> { - let nonce_field_name = CStr::from_bytes_with_nul("nonce-type\0".as_bytes()).unwrap(); + let nonce_field_name = CStr::from_bytes_with_nul(b"nonce-type\0").unwrap(); let mut nonce_type = nonce_type.0; unsafe { let param_nonce = @@ -765,7 +765,7 @@ impl PkeyCtxRef { #[cfg(ossl320)] #[corresponds(EVP_PKEY_CTX_get_params)] pub fn nonce_type(&mut self) -> Result { - let nonce_field_name = CStr::from_bytes_with_nul("nonce-type\0".as_bytes()).unwrap(); + let nonce_field_name = CStr::from_bytes_with_nul(b"nonce-type\0").unwrap(); let mut nonce_type: c_uint = 0; unsafe { let param_nonce =