Unverified Commit 4c19f4b6 authored by Alex Gaynor's avatar Alex Gaynor
Browse files

Allow setting the MD on signature PkeyCtx

parent ee44daf4
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -186,6 +186,8 @@ pub const EVP_PKEY_OP_TYPE_SIG: c_int = EVP_PKEY_OP_SIGN

pub const EVP_PKEY_OP_TYPE_CRYPT: c_int = EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT;

pub const EVP_PKEY_CTRL_MD: c_int = 1;

pub const EVP_PKEY_CTRL_SET_MAC_KEY: c_int = 6;

pub const EVP_PKEY_CTRL_CIPHER: c_int = 12;
@@ -288,6 +290,18 @@ pub unsafe fn EVP_PKEY_CTX_add1_hkdf_info(
    )
}

#[cfg(all(not(ossl300), not(boringssl)))]
pub unsafe fn EVP_PKEY_CTX_set_signature_md(cxt: *mut EVP_PKEY_CTX, md: *mut EVP_MD) -> c_int {
    EVP_PKEY_CTX_ctrl(
        cxt,
        -1,
        EVP_PKEY_OP_TYPE_SIG,
        EVP_PKEY_CTRL_MD,
        0,
        md as *mut c_void,
    )
}

pub unsafe fn EVP_PKEY_assign_RSA(pkey: *mut EVP_PKEY, rsa: *mut RSA) -> c_int {
    EVP_PKEY_assign(pkey, EVP_PKEY_RSA, rsa as *mut c_void)
}
+3 −0
Original line number Diff line number Diff line
@@ -497,6 +497,9 @@ extern "C" {
        p2: *mut c_void,
    ) -> c_int;

    #[cfg(ossl300)]
    pub fn EVP_PKEY_CTX_set_signature_md(ctx: *mut EVP_PKEY_CTX, md: *const EVP_MD) -> c_int;

    pub fn EVP_PKEY_new_mac_key(
        type_: c_int,
        e: *mut ENGINE,
+39 −1
Original line number Diff line number Diff line
@@ -351,6 +351,22 @@ impl<T> PkeyCtxRef<T> {
        Ok(())
    }

    /// Sets which algorithm was used to compute the digest used in a
    /// signature. With RSA signatures this causes the signature to be wrapped
    /// in a `DigestInfo` structure. This is almost always what you want with
    /// RSA signatures.
    #[corresponds(EVP_PKEY_CTX_set_signature_md)]
    #[inline]
    pub fn set_signature_md(&self, md: &MdRef) -> Result<(), ErrorStack> {
        unsafe {
            cvt(ffi::EVP_PKEY_CTX_set_signature_md(
                self.as_ptr(),
                md.as_ptr(),
            ))?;
        }
        Ok(())
    }

    /// Returns the RSA padding mode in use.
    ///
    /// This is only useful for RSA keys.
@@ -641,11 +657,12 @@ mod test {
    #[cfg(not(boringssl))]
    use crate::cipher::Cipher;
    use crate::ec::{EcGroup, EcKey};
    #[cfg(any(ossl102, libressl310, boringssl))]
    use crate::hash::{hash, MessageDigest};
    use crate::md::Md;
    use crate::nid::Nid;
    use crate::pkey::PKey;
    use crate::rsa::Rsa;
    use crate::sign::Verifier;

    #[test]
    fn rsa() {
@@ -698,6 +715,27 @@ mod test {
        assert_eq!(pt, out);
    }

    #[test]
    fn rsa_sign() {
        let key = include_bytes!("../test/rsa.pem");
        let rsa = Rsa::private_key_from_pem(key).unwrap();
        let pkey = PKey::from_rsa(rsa).unwrap();

        let mut ctx = PkeyCtx::new(&pkey).unwrap();
        ctx.sign_init().unwrap();
        ctx.set_rsa_padding(Padding::PKCS1).unwrap();
        ctx.set_signature_md(Md::sha384()).unwrap();

        let msg = b"hello world";
        let digest = hash(MessageDigest::sha384(), msg).unwrap();
        let mut signature = vec![];
        ctx.sign_to_vec(&digest, &mut signature).unwrap();

        let mut verifier = Verifier::new(MessageDigest::sha384(), &pkey).unwrap();
        verifier.update(msg).unwrap();
        assert!(matches!(verifier.verify(&signature), Ok(true)));
    }

    #[test]
    fn derive() {
        let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();