Commit f783cbe1 authored by Paul Kehrer's avatar Paul Kehrer
Browse files

add support for EVP_PKEY_derive_set_peer_ex in OpenSSL 3

via Deriver::set_peer_ex
parent 1a5b1346
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -522,6 +522,12 @@ extern "C" {

    pub fn EVP_PKEY_derive_init(ctx: *mut EVP_PKEY_CTX) -> c_int;
    pub fn EVP_PKEY_derive_set_peer(ctx: *mut EVP_PKEY_CTX, peer: *mut EVP_PKEY) -> c_int;
    #[cfg(ossl300)]
    pub fn EVP_PKEY_derive_set_peer_ex(
        ctx: *mut EVP_PKEY_CTX,
        peer: *mut EVP_PKEY,
        validate_peer: c_int,
    ) -> c_int;
    pub fn EVP_PKEY_derive(ctx: *mut EVP_PKEY_CTX, key: *mut c_uchar, size: *mut size_t) -> c_int;

    #[cfg(ossl300)]
+38 −0
Original line number Diff line number Diff line
@@ -93,6 +93,30 @@ impl<'a> Deriver<'a> {
        unsafe { cvt(ffi::EVP_PKEY_derive_set_peer(self.0, key.as_ptr())).map(|_| ()) }
    }

    /// Sets the peer key used for secret derivation along with optionally validating the peer public key.
    ///
    /// This corresponds to [`EVP_PKEY_derive_set_peer_ex`]:
    ///
    /// [`EVP_PKEY_derive_set_peer_ex`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_derive_set_peer_ex.html
    #[cfg(ossl300)]
    pub fn set_peer_ex<T>(
        &mut self,
        key: &'a PKeyRef<T>,
        validate_peer: bool,
    ) -> Result<(), ErrorStack>
    where
        T: HasPublic,
    {
        unsafe {
            cvt(ffi::EVP_PKEY_derive_set_peer_ex(
                self.0,
                key.as_ptr(),
                validate_peer as i32,
            ))
            .map(|_| ())
        }
    }

    /// Returns the size of the shared secret.
    ///
    /// It can be used to size the buffer passed to [`Deriver::derive`].
@@ -179,4 +203,18 @@ mod test {
        let shared = deriver.derive_to_vec().unwrap();
        assert!(!shared.is_empty());
    }

    #[test]
    #[cfg(ossl300)]
    fn test_ec_key_derive_ex() {
        let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
        let ec_key = EcKey::generate(&group).unwrap();
        let ec_key2 = EcKey::generate(&group).unwrap();
        let pkey = PKey::from_ec_key(ec_key).unwrap();
        let pkey2 = PKey::from_ec_key(ec_key2).unwrap();
        let mut deriver = Deriver::new(&pkey).unwrap();
        deriver.set_peer_ex(&pkey2, true).unwrap();
        let shared = deriver.derive_to_vec().unwrap();
        assert!(!shared.is_empty());
    }
}