diff --git a/openssl/src/pkey_ctx.rs b/openssl/src/pkey_ctx.rs index 8f7a10515d7a6dcfb1cdafff5ff9ac13c02ec679..3c6c7430c5fd43e5d9cadac5ab088de9beeb23f3 100644 --- a/openssl/src/pkey_ctx.rs +++ b/openssl/src/pkey_ctx.rs @@ -70,6 +70,7 @@ use crate::error::ErrorStack; use crate::md::MdRef; use crate::pkey::{HasPrivate, HasPublic, Id, PKey, PKeyRef, Private}; use crate::rsa::Padding; +use crate::sign::RsaPssSaltlen; use crate::{cvt, cvt_n, cvt_p}; use foreign_types::{ForeignType, ForeignTypeRef}; #[cfg(not(boringssl))] @@ -397,6 +398,21 @@ impl PkeyCtxRef { Ok(()) } + /// Sets the RSA PSS salt length. + /// + /// This is only useful for RSA keys. + #[corresponds(EVP_PKEY_CTX_set_rsa_pss_saltlen)] + #[inline] + pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen( + self.as_ptr(), + len.as_raw(), + )) + .map(|_| ()) + } + } + /// Sets the RSA MGF1 algorithm. /// /// This is only useful for RSA keys. @@ -736,6 +752,32 @@ mod test { assert!(matches!(verifier.verify(&signature), Ok(true))); } + #[test] + fn rsa_sign_pss() { + 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_PSS).unwrap(); + ctx.set_signature_md(Md::sha384()).unwrap(); + ctx.set_rsa_pss_saltlen(RsaPssSaltlen::custom(14)).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.set_rsa_padding(Padding::PKCS1_PSS).unwrap(); + verifier + .set_rsa_pss_saltlen(RsaPssSaltlen::custom(14)) + .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(); diff --git a/openssl/src/sign.rs b/openssl/src/sign.rs index a32f5c9144ece4cc31d3f87dea1b0e48ea35e5d7..1c770d18b79d2a4dd240d91a212c77a8f0e0273a 100644 --- a/openssl/src/sign.rs +++ b/openssl/src/sign.rs @@ -93,7 +93,7 @@ pub struct RsaPssSaltlen(c_int); impl RsaPssSaltlen { /// Returns the integer representation of `RsaPssSaltlen`. - fn as_raw(&self) -> c_int { + pub(crate) fn as_raw(&self) -> c_int { self.0 }