Skip to content

Commit a71f492

Browse files
authored
Merge pull request #1956 from reaperhulk/ex-tend-those-peers
add support for EVP_PKEY_derive_set_peer_ex in OpenSSL 3
2 parents 1a5b134 + 2604033 commit a71f492

File tree

2 files changed

+45
-4
lines changed

2 files changed

+45
-4
lines changed

openssl-sys/src/handwritten/evp.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,12 @@ extern "C" {
522522

523523
pub fn EVP_PKEY_derive_init(ctx: *mut EVP_PKEY_CTX) -> c_int;
524524
pub fn EVP_PKEY_derive_set_peer(ctx: *mut EVP_PKEY_CTX, peer: *mut EVP_PKEY) -> c_int;
525+
#[cfg(ossl300)]
526+
pub fn EVP_PKEY_derive_set_peer_ex(
527+
ctx: *mut EVP_PKEY_CTX,
528+
peer: *mut EVP_PKEY,
529+
validate_peer: c_int,
530+
) -> c_int;
525531
pub fn EVP_PKEY_derive(ctx: *mut EVP_PKEY_CTX, key: *mut c_uchar, size: *mut size_t) -> c_int;
526532

527533
#[cfg(ossl300)]

openssl/src/derive.rs

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ use std::ptr;
5656
use crate::error::ErrorStack;
5757
use crate::pkey::{HasPrivate, HasPublic, PKeyRef};
5858
use crate::{cvt, cvt_p};
59+
use openssl_macros::corresponds;
5960

6061
/// A type used to derive a shared secret between two keys.
6162
pub struct Deriver<'a>(*mut ffi::EVP_PKEY_CTX, PhantomData<&'a ()>);
@@ -82,17 +83,37 @@ impl<'a> Deriver<'a> {
8283
}
8384

8485
/// Sets the peer key used for secret derivation.
85-
///
86-
/// This corresponds to [`EVP_PKEY_derive_set_peer`]:
87-
///
88-
/// [`EVP_PKEY_derive_set_peer`]: https://www.openssl.org/docs/manmaster/crypto/EVP_PKEY_derive_init.html
86+
#[corresponds(EVP_PKEY_derive_set_peer)]
8987
pub fn set_peer<T>(&mut self, key: &'a PKeyRef<T>) -> Result<(), ErrorStack>
9088
where
9189
T: HasPublic,
9290
{
9391
unsafe { cvt(ffi::EVP_PKEY_derive_set_peer(self.0, key.as_ptr())).map(|_| ()) }
9492
}
9593

94+
/// Sets the peer key used for secret derivation along with optionally validating the peer public key.
95+
///
96+
/// Requires OpenSSL 3.0.0 or newer.
97+
#[corresponds(EVP_PKEY_derive_set_peer_ex)]
98+
#[cfg(ossl300)]
99+
pub fn set_peer_ex<T>(
100+
&mut self,
101+
key: &'a PKeyRef<T>,
102+
validate_peer: bool,
103+
) -> Result<(), ErrorStack>
104+
where
105+
T: HasPublic,
106+
{
107+
unsafe {
108+
cvt(ffi::EVP_PKEY_derive_set_peer_ex(
109+
self.0,
110+
key.as_ptr(),
111+
validate_peer as i32,
112+
))
113+
.map(|_| ())
114+
}
115+
}
116+
96117
/// Returns the size of the shared secret.
97118
///
98119
/// It can be used to size the buffer passed to [`Deriver::derive`].
@@ -179,4 +200,18 @@ mod test {
179200
let shared = deriver.derive_to_vec().unwrap();
180201
assert!(!shared.is_empty());
181202
}
203+
204+
#[test]
205+
#[cfg(ossl300)]
206+
fn test_ec_key_derive_ex() {
207+
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
208+
let ec_key = EcKey::generate(&group).unwrap();
209+
let ec_key2 = EcKey::generate(&group).unwrap();
210+
let pkey = PKey::from_ec_key(ec_key).unwrap();
211+
let pkey2 = PKey::from_ec_key(ec_key2).unwrap();
212+
let mut deriver = Deriver::new(&pkey).unwrap();
213+
deriver.set_peer_ex(&pkey2, true).unwrap();
214+
let shared = deriver.derive_to_vec().unwrap();
215+
assert!(!shared.is_empty());
216+
}
182217
}

0 commit comments

Comments
 (0)