From 724dd6f830d64de6fc1e6f55b8b0a9f630d928f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 7 Mar 2018 20:43:28 +0100 Subject: Adds more functions to `Verifier`/`Signer` for RSA keys --- openssl/src/sign.rs | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) (limited to 'openssl/src/sign.rs') diff --git a/openssl/src/sign.rs b/openssl/src/sign.rs index a61d883b..9de9bcf7 100644 --- a/openssl/src/sign.rs +++ b/openssl/src/sign.rs @@ -66,6 +66,7 @@ use foreign_types::ForeignTypeRef; use std::io::{self, Write}; use std::marker::PhantomData; use std::ptr; +use libc::c_int; use {cvt, cvt_p}; use hash::MessageDigest; @@ -160,6 +161,38 @@ impl<'a> Signer<'a> { } } + /// Sets the RSA PSS salt length. + /// + /// This is only useful for RSA keys. + /// + /// This corresponds to [`EVP_PKEY_CTX_set_rsa_pss_saltlen`]. + /// + /// [`EVP_PKEY_CTX_set_rsa_pss_saltlen`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_CTX_set_rsa_pss_saltlen.html + pub fn set_rsa_pss_saltlen(&mut self, len: c_int) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen( + self.pctx, + len, + )).map(|_| ()) + } + } + + /// Sets the RSA MGF1 algorithm. + /// + /// This is only useful for RSA keys. + /// + /// This corresponds to [`EVP_PKEY_CTX_set_rsa_mgf1_md`]. + /// + /// [`EVP_PKEY_CTX_set_rsa_mgf1_md`]: https://www.openssl.org/docs/manmaster/man7/RSA-PSS.html + pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md( + self.pctx, + md.as_ptr() as *mut _, + )).map(|_| ()) + } + } + /// Feeds more data into the `Signer`. /// /// OpenSSL documentation at [`EVP_DigestUpdate`]. @@ -320,6 +353,38 @@ impl<'a> Verifier<'a> { } } + /// Sets the RSA PSS salt length. + /// + /// This is only useful for RSA keys. + /// + /// This corresponds to [`EVP_PKEY_CTX_set_rsa_pss_saltlen`]. + /// + /// [`EVP_PKEY_CTX_set_rsa_pss_saltlen`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_CTX_set_rsa_pss_saltlen.html + pub fn set_rsa_pss_saltlen(&mut self, len: c_int) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen( + self.pctx, + len, + )).map(|_| ()) + } + } + + /// Sets the RSA MGF1 algorithm. + /// + /// This is only useful for RSA keys. + /// + /// This corresponds to [`EVP_PKEY_CTX_set_rsa_mgf1_md`]. + /// + /// [`EVP_PKEY_CTX_set_rsa_mgf1_md`]: https://www.openssl.org/docs/manmaster/man7/RSA-PSS.html + pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md( + self.pctx, + md.as_ptr() as *mut _, + )).map(|_| ()) + } + } + /// Feeds more data into the `Verifier`. /// /// OpenSSL documentation at [`EVP_DigestUpdate`]. @@ -559,4 +624,26 @@ mod test { verifier.update(b"hello world").unwrap(); assert!(verifier.verify(&signature).unwrap()); } + + #[test] + fn rsa_sign_verify() { + let key = include_bytes!("../test/rsa.pem"); + let private_key = Rsa::private_key_from_pem(key).unwrap(); + let pkey = PKey::from_rsa(private_key).unwrap(); + + let mut signer = Signer::new(MessageDigest::sha256(), &pkey).unwrap(); + signer.set_rsa_padding(Padding::PKCS1_PSS).unwrap(); + assert_eq!(signer.rsa_padding().unwrap(), Padding::PKCS1_PSS); + signer.set_rsa_pss_saltlen(-1).unwrap(); + signer.set_rsa_mgf1_md(MessageDigest::sha256()).unwrap(); + signer.update(&Vec::from_hex(INPUT).unwrap()).unwrap(); + let signature = signer.sign_to_vec().unwrap(); + + let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap(); + verifier.set_rsa_padding(Padding::PKCS1_PSS).unwrap(); + verifier.set_rsa_pss_saltlen(-1).unwrap(); + verifier.set_rsa_mgf1_md(MessageDigest::sha256()).unwrap(); + verifier.update(&Vec::from_hex(INPUT).unwrap()).unwrap(); + assert!(verifier.verify(&signature).unwrap()); + } } -- cgit v1.2.3 From a5ba1a00077f1eb91db34ca6109a935661bd41a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 8 Mar 2018 16:17:32 +0100 Subject: Adds `RsaPssSaltlen` enum to encode the special values --- openssl/src/sign.rs | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) (limited to 'openssl/src/sign.rs') diff --git a/openssl/src/sign.rs b/openssl/src/sign.rs index 9de9bcf7..488e7291 100644 --- a/openssl/src/sign.rs +++ b/openssl/src/sign.rs @@ -79,6 +79,29 @@ use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new}; #[cfg(any(ossl101, ossl102))] use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free}; +/// Salt lengths that must be used with `set_rsa_pss_saltlen`. +pub enum RsaPssSaltlen { + /// The salt length is set to the digest length. + /// Corresponds to the special value `-1`. + DigestLength, + /// The salt length is set to the maximum permissible value. + /// Corresponds to the special value `-2`. + MaximumLength, + /// Sets the salt length to the given value. + Custom(u32) +} + +impl RsaPssSaltlen { + /// Returns the integer representation of `Oid`. + fn as_raw(&self) -> c_int { + match *self { + RsaPssSaltlen::DigestLength => -1, + RsaPssSaltlen::MaximumLength => -2, + RsaPssSaltlen::Custom(val) => val as c_int, + } + } +} + /// A type which computes cryptographic signatures of data. pub struct Signer<'a> { md_ctx: *mut ffi::EVP_MD_CTX, @@ -168,11 +191,11 @@ impl<'a> Signer<'a> { /// This corresponds to [`EVP_PKEY_CTX_set_rsa_pss_saltlen`]. /// /// [`EVP_PKEY_CTX_set_rsa_pss_saltlen`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_CTX_set_rsa_pss_saltlen.html - pub fn set_rsa_pss_saltlen(&mut self, len: c_int) -> Result<(), ErrorStack> { + pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> { unsafe { cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen( self.pctx, - len, + len.as_raw(), )).map(|_| ()) } } @@ -360,11 +383,11 @@ impl<'a> Verifier<'a> { /// This corresponds to [`EVP_PKEY_CTX_set_rsa_pss_saltlen`]. /// /// [`EVP_PKEY_CTX_set_rsa_pss_saltlen`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_CTX_set_rsa_pss_saltlen.html - pub fn set_rsa_pss_saltlen(&mut self, len: c_int) -> Result<(), ErrorStack> { + pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> { unsafe { cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen( self.pctx, - len, + len.as_raw(), )).map(|_| ()) } } @@ -451,7 +474,7 @@ mod test { use std::iter; use hash::MessageDigest; - use sign::{Signer, Verifier}; + use sign::{Signer, Verifier, RsaPssSaltlen}; use ec::{EcGroup, EcKey}; use nid::Nid; use rsa::{Padding, Rsa}; @@ -634,14 +657,14 @@ mod test { let mut signer = Signer::new(MessageDigest::sha256(), &pkey).unwrap(); signer.set_rsa_padding(Padding::PKCS1_PSS).unwrap(); assert_eq!(signer.rsa_padding().unwrap(), Padding::PKCS1_PSS); - signer.set_rsa_pss_saltlen(-1).unwrap(); + signer.set_rsa_pss_saltlen(RsaPssSaltlen::DigestLength).unwrap(); signer.set_rsa_mgf1_md(MessageDigest::sha256()).unwrap(); signer.update(&Vec::from_hex(INPUT).unwrap()).unwrap(); let signature = signer.sign_to_vec().unwrap(); let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap(); verifier.set_rsa_padding(Padding::PKCS1_PSS).unwrap(); - verifier.set_rsa_pss_saltlen(-1).unwrap(); + verifier.set_rsa_pss_saltlen(RsaPssSaltlen::DigestLength).unwrap(); verifier.set_rsa_mgf1_md(MessageDigest::sha256()).unwrap(); verifier.update(&Vec::from_hex(INPUT).unwrap()).unwrap(); assert!(verifier.verify(&signature).unwrap()); -- cgit v1.2.3 From 7fe3fabf245a1e65ad8441dc8c00f1b3ab28d70d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Sat, 10 Mar 2018 00:26:20 +0100 Subject: Switches to new type wrapper for RsaPssSaltlen --- openssl/src/sign.rs | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) (limited to 'openssl/src/sign.rs') diff --git a/openssl/src/sign.rs b/openssl/src/sign.rs index 488e7291..d4c36cad 100644 --- a/openssl/src/sign.rs +++ b/openssl/src/sign.rs @@ -80,26 +80,25 @@ use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new}; use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free}; /// Salt lengths that must be used with `set_rsa_pss_saltlen`. -pub enum RsaPssSaltlen { - /// The salt length is set to the digest length. - /// Corresponds to the special value `-1`. - DigestLength, - /// The salt length is set to the maximum permissible value. - /// Corresponds to the special value `-2`. - MaximumLength, - /// Sets the salt length to the given value. - Custom(u32) -} +pub struct RsaPssSaltlen(c_int); impl RsaPssSaltlen { - /// Returns the integer representation of `Oid`. + /// Returns the integer representation of `RsaPssSaltlen`. fn as_raw(&self) -> c_int { - match *self { - RsaPssSaltlen::DigestLength => -1, - RsaPssSaltlen::MaximumLength => -2, - RsaPssSaltlen::Custom(val) => val as c_int, - } + self.0 } + + /// Sets the salt length to the given value. + pub fn custom(val: c_int) -> RsaPssSaltlen { + RsaPssSaltlen(val) + } + + /// The salt length is set to the digest length. + /// Corresponds to the special value `-1`. + pub const DIGEST_LENGTH: RsaPssSaltlen = RsaPssSaltlen(-1); + /// The salt length is set to the maximum permissible value. + /// Corresponds to the special value `-2`. + pub const MAXIMUM_LENGTH: RsaPssSaltlen = RsaPssSaltlen(-2); } /// A type which computes cryptographic signatures of data. @@ -657,14 +656,14 @@ mod test { let mut signer = Signer::new(MessageDigest::sha256(), &pkey).unwrap(); signer.set_rsa_padding(Padding::PKCS1_PSS).unwrap(); assert_eq!(signer.rsa_padding().unwrap(), Padding::PKCS1_PSS); - signer.set_rsa_pss_saltlen(RsaPssSaltlen::DigestLength).unwrap(); + signer.set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH).unwrap(); signer.set_rsa_mgf1_md(MessageDigest::sha256()).unwrap(); signer.update(&Vec::from_hex(INPUT).unwrap()).unwrap(); let signature = signer.sign_to_vec().unwrap(); let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap(); verifier.set_rsa_padding(Padding::PKCS1_PSS).unwrap(); - verifier.set_rsa_pss_saltlen(RsaPssSaltlen::DigestLength).unwrap(); + verifier.set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH).unwrap(); verifier.set_rsa_mgf1_md(MessageDigest::sha256()).unwrap(); verifier.update(&Vec::from_hex(INPUT).unwrap()).unwrap(); assert!(verifier.verify(&signature).unwrap()); -- cgit v1.2.3