192f3ab15Sopenharmony_ci//! Message signatures. 292f3ab15Sopenharmony_ci//! 392f3ab15Sopenharmony_ci//! The `Signer` allows for the computation of cryptographic signatures of 492f3ab15Sopenharmony_ci//! data given a private key. The `Verifier` can then be used with the 592f3ab15Sopenharmony_ci//! corresponding public key to verify the integrity and authenticity of that 692f3ab15Sopenharmony_ci//! data given the signature. 792f3ab15Sopenharmony_ci//! 892f3ab15Sopenharmony_ci//! # Examples 992f3ab15Sopenharmony_ci//! 1092f3ab15Sopenharmony_ci//! Sign and verify data given an RSA keypair: 1192f3ab15Sopenharmony_ci//! 1292f3ab15Sopenharmony_ci//! ```rust 1392f3ab15Sopenharmony_ci//! use openssl::sign::{Signer, Verifier}; 1492f3ab15Sopenharmony_ci//! use openssl::rsa::Rsa; 1592f3ab15Sopenharmony_ci//! use openssl::pkey::PKey; 1692f3ab15Sopenharmony_ci//! use openssl::hash::MessageDigest; 1792f3ab15Sopenharmony_ci//! 1892f3ab15Sopenharmony_ci//! // Generate a keypair 1992f3ab15Sopenharmony_ci//! let keypair = Rsa::generate(2048).unwrap(); 2092f3ab15Sopenharmony_ci//! let keypair = PKey::from_rsa(keypair).unwrap(); 2192f3ab15Sopenharmony_ci//! 2292f3ab15Sopenharmony_ci//! let data = b"hello, world!"; 2392f3ab15Sopenharmony_ci//! let data2 = b"hola, mundo!"; 2492f3ab15Sopenharmony_ci//! 2592f3ab15Sopenharmony_ci//! // Sign the data 2692f3ab15Sopenharmony_ci//! let mut signer = Signer::new(MessageDigest::sha256(), &keypair).unwrap(); 2792f3ab15Sopenharmony_ci//! signer.update(data).unwrap(); 2892f3ab15Sopenharmony_ci//! signer.update(data2).unwrap(); 2992f3ab15Sopenharmony_ci//! let signature = signer.sign_to_vec().unwrap(); 3092f3ab15Sopenharmony_ci//! 3192f3ab15Sopenharmony_ci//! // Verify the data 3292f3ab15Sopenharmony_ci//! let mut verifier = Verifier::new(MessageDigest::sha256(), &keypair).unwrap(); 3392f3ab15Sopenharmony_ci//! verifier.update(data).unwrap(); 3492f3ab15Sopenharmony_ci//! verifier.update(data2).unwrap(); 3592f3ab15Sopenharmony_ci//! assert!(verifier.verify(&signature).unwrap()); 3692f3ab15Sopenharmony_ci//! ``` 3792f3ab15Sopenharmony_ci 3892f3ab15Sopenharmony_ci#![cfg_attr( 3992f3ab15Sopenharmony_ci not(boringssl), 4092f3ab15Sopenharmony_ci doc = r#"\ 4192f3ab15Sopenharmony_ci 4292f3ab15Sopenharmony_ciCompute an HMAC: 4392f3ab15Sopenharmony_ci 4492f3ab15Sopenharmony_ci```rust 4592f3ab15Sopenharmony_ciuse openssl::hash::MessageDigest; 4692f3ab15Sopenharmony_ciuse openssl::memcmp; 4792f3ab15Sopenharmony_ciuse openssl::pkey::PKey; 4892f3ab15Sopenharmony_ciuse openssl::sign::Signer; 4992f3ab15Sopenharmony_ci 5092f3ab15Sopenharmony_ci// Create a PKey 5192f3ab15Sopenharmony_cilet key = PKey::hmac(b"my secret").unwrap(); 5292f3ab15Sopenharmony_ci 5392f3ab15Sopenharmony_cilet data = b"hello, world!"; 5492f3ab15Sopenharmony_cilet data2 = b"hola, mundo!"; 5592f3ab15Sopenharmony_ci 5692f3ab15Sopenharmony_ci// Compute the HMAC 5792f3ab15Sopenharmony_cilet mut signer = Signer::new(MessageDigest::sha256(), &key).unwrap(); 5892f3ab15Sopenharmony_cisigner.update(data).unwrap(); 5992f3ab15Sopenharmony_cisigner.update(data2).unwrap(); 6092f3ab15Sopenharmony_cilet hmac = signer.sign_to_vec().unwrap(); 6192f3ab15Sopenharmony_ci 6292f3ab15Sopenharmony_ci// `Verifier` cannot be used with HMACs; use the `memcmp::eq` function instead 6392f3ab15Sopenharmony_ci// 6492f3ab15Sopenharmony_ci// Do not simply check for equality with `==`! 6592f3ab15Sopenharmony_ci# let target = hmac.clone(); 6692f3ab15Sopenharmony_ciassert!(memcmp::eq(&hmac, &target)); 6792f3ab15Sopenharmony_ci```"# 6892f3ab15Sopenharmony_ci)] 6992f3ab15Sopenharmony_ci 7092f3ab15Sopenharmony_ciuse cfg_if::cfg_if; 7192f3ab15Sopenharmony_ciuse foreign_types::ForeignTypeRef; 7292f3ab15Sopenharmony_ciuse libc::c_int; 7392f3ab15Sopenharmony_ciuse std::io::{self, Write}; 7492f3ab15Sopenharmony_ciuse std::marker::PhantomData; 7592f3ab15Sopenharmony_ciuse std::ptr; 7692f3ab15Sopenharmony_ci 7792f3ab15Sopenharmony_ciuse crate::error::ErrorStack; 7892f3ab15Sopenharmony_ciuse crate::hash::MessageDigest; 7992f3ab15Sopenharmony_ciuse crate::pkey::{HasPrivate, HasPublic, PKeyRef}; 8092f3ab15Sopenharmony_ciuse crate::rsa::Padding; 8192f3ab15Sopenharmony_ciuse crate::{cvt, cvt_p}; 8292f3ab15Sopenharmony_ci 8392f3ab15Sopenharmony_cicfg_if! { 8492f3ab15Sopenharmony_ci if #[cfg(ossl110)] { 8592f3ab15Sopenharmony_ci use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new}; 8692f3ab15Sopenharmony_ci } else { 8792f3ab15Sopenharmony_ci use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free}; 8892f3ab15Sopenharmony_ci } 8992f3ab15Sopenharmony_ci} 9092f3ab15Sopenharmony_ci 9192f3ab15Sopenharmony_ci/// Salt lengths that must be used with `set_rsa_pss_saltlen`. 9292f3ab15Sopenharmony_cipub struct RsaPssSaltlen(c_int); 9392f3ab15Sopenharmony_ci 9492f3ab15Sopenharmony_ciimpl RsaPssSaltlen { 9592f3ab15Sopenharmony_ci /// Returns the integer representation of `RsaPssSaltlen`. 9692f3ab15Sopenharmony_ci pub(crate) fn as_raw(&self) -> c_int { 9792f3ab15Sopenharmony_ci self.0 9892f3ab15Sopenharmony_ci } 9992f3ab15Sopenharmony_ci 10092f3ab15Sopenharmony_ci /// Sets the salt length to the given value. 10192f3ab15Sopenharmony_ci pub fn custom(val: c_int) -> RsaPssSaltlen { 10292f3ab15Sopenharmony_ci RsaPssSaltlen(val) 10392f3ab15Sopenharmony_ci } 10492f3ab15Sopenharmony_ci 10592f3ab15Sopenharmony_ci /// The salt length is set to the digest length. 10692f3ab15Sopenharmony_ci /// Corresponds to the special value `-1`. 10792f3ab15Sopenharmony_ci pub const DIGEST_LENGTH: RsaPssSaltlen = RsaPssSaltlen(-1); 10892f3ab15Sopenharmony_ci /// The salt length is set to the maximum permissible value. 10992f3ab15Sopenharmony_ci /// Corresponds to the special value `-2`. 11092f3ab15Sopenharmony_ci pub const MAXIMUM_LENGTH: RsaPssSaltlen = RsaPssSaltlen(-2); 11192f3ab15Sopenharmony_ci} 11292f3ab15Sopenharmony_ci 11392f3ab15Sopenharmony_ci/// A type which computes cryptographic signatures of data. 11492f3ab15Sopenharmony_cipub struct Signer<'a> { 11592f3ab15Sopenharmony_ci md_ctx: *mut ffi::EVP_MD_CTX, 11692f3ab15Sopenharmony_ci pctx: *mut ffi::EVP_PKEY_CTX, 11792f3ab15Sopenharmony_ci _p: PhantomData<&'a ()>, 11892f3ab15Sopenharmony_ci} 11992f3ab15Sopenharmony_ci 12092f3ab15Sopenharmony_ciunsafe impl Sync for Signer<'_> {} 12192f3ab15Sopenharmony_ciunsafe impl Send for Signer<'_> {} 12292f3ab15Sopenharmony_ci 12392f3ab15Sopenharmony_ciimpl Drop for Signer<'_> { 12492f3ab15Sopenharmony_ci fn drop(&mut self) { 12592f3ab15Sopenharmony_ci // pkey_ctx is owned by the md_ctx, so no need to explicitly free it. 12692f3ab15Sopenharmony_ci unsafe { 12792f3ab15Sopenharmony_ci EVP_MD_CTX_free(self.md_ctx); 12892f3ab15Sopenharmony_ci } 12992f3ab15Sopenharmony_ci } 13092f3ab15Sopenharmony_ci} 13192f3ab15Sopenharmony_ci 13292f3ab15Sopenharmony_ci#[allow(clippy::len_without_is_empty)] 13392f3ab15Sopenharmony_ciimpl Signer<'_> { 13492f3ab15Sopenharmony_ci /// Creates a new `Signer`. 13592f3ab15Sopenharmony_ci /// 13692f3ab15Sopenharmony_ci /// This cannot be used with Ed25519 or Ed448 keys. Please refer to 13792f3ab15Sopenharmony_ci /// `new_without_digest`. 13892f3ab15Sopenharmony_ci /// 13992f3ab15Sopenharmony_ci /// OpenSSL documentation at [`EVP_DigestSignInit`]. 14092f3ab15Sopenharmony_ci /// 14192f3ab15Sopenharmony_ci /// [`EVP_DigestSignInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestSignInit.html 14292f3ab15Sopenharmony_ci pub fn new<'a, T>(type_: MessageDigest, pkey: &PKeyRef<T>) -> Result<Signer<'a>, ErrorStack> 14392f3ab15Sopenharmony_ci where 14492f3ab15Sopenharmony_ci T: HasPrivate, 14592f3ab15Sopenharmony_ci { 14692f3ab15Sopenharmony_ci Self::new_intern(Some(type_), pkey) 14792f3ab15Sopenharmony_ci } 14892f3ab15Sopenharmony_ci 14992f3ab15Sopenharmony_ci /// Creates a new `Signer` without a digest. 15092f3ab15Sopenharmony_ci /// 15192f3ab15Sopenharmony_ci /// This is the only way to create a `Verifier` for Ed25519 or Ed448 keys. 15292f3ab15Sopenharmony_ci /// It can also be used to create a CMAC. 15392f3ab15Sopenharmony_ci /// 15492f3ab15Sopenharmony_ci /// OpenSSL documentation at [`EVP_DigestSignInit`]. 15592f3ab15Sopenharmony_ci /// 15692f3ab15Sopenharmony_ci /// [`EVP_DigestSignInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestSignInit.html 15792f3ab15Sopenharmony_ci pub fn new_without_digest<'a, T>(pkey: &PKeyRef<T>) -> Result<Signer<'a>, ErrorStack> 15892f3ab15Sopenharmony_ci where 15992f3ab15Sopenharmony_ci T: HasPrivate, 16092f3ab15Sopenharmony_ci { 16192f3ab15Sopenharmony_ci Self::new_intern(None, pkey) 16292f3ab15Sopenharmony_ci } 16392f3ab15Sopenharmony_ci 16492f3ab15Sopenharmony_ci fn new_intern<'a, T>( 16592f3ab15Sopenharmony_ci type_: Option<MessageDigest>, 16692f3ab15Sopenharmony_ci pkey: &PKeyRef<T>, 16792f3ab15Sopenharmony_ci ) -> Result<Signer<'a>, ErrorStack> 16892f3ab15Sopenharmony_ci where 16992f3ab15Sopenharmony_ci T: HasPrivate, 17092f3ab15Sopenharmony_ci { 17192f3ab15Sopenharmony_ci unsafe { 17292f3ab15Sopenharmony_ci ffi::init(); 17392f3ab15Sopenharmony_ci 17492f3ab15Sopenharmony_ci let ctx = cvt_p(EVP_MD_CTX_new())?; 17592f3ab15Sopenharmony_ci let mut pctx: *mut ffi::EVP_PKEY_CTX = ptr::null_mut(); 17692f3ab15Sopenharmony_ci let r = ffi::EVP_DigestSignInit( 17792f3ab15Sopenharmony_ci ctx, 17892f3ab15Sopenharmony_ci &mut pctx, 17992f3ab15Sopenharmony_ci type_.map(|t| t.as_ptr()).unwrap_or(ptr::null()), 18092f3ab15Sopenharmony_ci ptr::null_mut(), 18192f3ab15Sopenharmony_ci pkey.as_ptr(), 18292f3ab15Sopenharmony_ci ); 18392f3ab15Sopenharmony_ci if r != 1 { 18492f3ab15Sopenharmony_ci EVP_MD_CTX_free(ctx); 18592f3ab15Sopenharmony_ci return Err(ErrorStack::get()); 18692f3ab15Sopenharmony_ci } 18792f3ab15Sopenharmony_ci 18892f3ab15Sopenharmony_ci assert!(!pctx.is_null()); 18992f3ab15Sopenharmony_ci 19092f3ab15Sopenharmony_ci Ok(Signer { 19192f3ab15Sopenharmony_ci md_ctx: ctx, 19292f3ab15Sopenharmony_ci pctx, 19392f3ab15Sopenharmony_ci _p: PhantomData, 19492f3ab15Sopenharmony_ci }) 19592f3ab15Sopenharmony_ci } 19692f3ab15Sopenharmony_ci } 19792f3ab15Sopenharmony_ci 19892f3ab15Sopenharmony_ci /// Returns the RSA padding mode in use. 19992f3ab15Sopenharmony_ci /// 20092f3ab15Sopenharmony_ci /// This is only useful for RSA keys. 20192f3ab15Sopenharmony_ci /// 20292f3ab15Sopenharmony_ci /// This corresponds to `EVP_PKEY_CTX_get_rsa_padding`. 20392f3ab15Sopenharmony_ci pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> { 20492f3ab15Sopenharmony_ci unsafe { 20592f3ab15Sopenharmony_ci let mut pad = 0; 20692f3ab15Sopenharmony_ci cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.pctx, &mut pad)) 20792f3ab15Sopenharmony_ci .map(|_| Padding::from_raw(pad)) 20892f3ab15Sopenharmony_ci } 20992f3ab15Sopenharmony_ci } 21092f3ab15Sopenharmony_ci 21192f3ab15Sopenharmony_ci /// Sets the RSA padding mode. 21292f3ab15Sopenharmony_ci /// 21392f3ab15Sopenharmony_ci /// This is only useful for RSA keys. 21492f3ab15Sopenharmony_ci /// 21592f3ab15Sopenharmony_ci /// This corresponds to [`EVP_PKEY_CTX_set_rsa_padding`]. 21692f3ab15Sopenharmony_ci /// 21792f3ab15Sopenharmony_ci /// [`EVP_PKEY_CTX_set_rsa_padding`]: https://www.openssl.org/docs/manmaster/crypto/EVP_PKEY_CTX_set_rsa_padding.html 21892f3ab15Sopenharmony_ci pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> { 21992f3ab15Sopenharmony_ci unsafe { 22092f3ab15Sopenharmony_ci cvt(ffi::EVP_PKEY_CTX_set_rsa_padding( 22192f3ab15Sopenharmony_ci self.pctx, 22292f3ab15Sopenharmony_ci padding.as_raw(), 22392f3ab15Sopenharmony_ci )) 22492f3ab15Sopenharmony_ci .map(|_| ()) 22592f3ab15Sopenharmony_ci } 22692f3ab15Sopenharmony_ci } 22792f3ab15Sopenharmony_ci 22892f3ab15Sopenharmony_ci /// Sets the RSA PSS salt length. 22992f3ab15Sopenharmony_ci /// 23092f3ab15Sopenharmony_ci /// This is only useful for RSA keys. 23192f3ab15Sopenharmony_ci /// 23292f3ab15Sopenharmony_ci /// This corresponds to [`EVP_PKEY_CTX_set_rsa_pss_saltlen`]. 23392f3ab15Sopenharmony_ci /// 23492f3ab15Sopenharmony_ci /// [`EVP_PKEY_CTX_set_rsa_pss_saltlen`]: https://www.openssl.org/docs/manmaster/crypto/EVP_PKEY_CTX_set_rsa_pss_saltlen.html 23592f3ab15Sopenharmony_ci pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> { 23692f3ab15Sopenharmony_ci unsafe { 23792f3ab15Sopenharmony_ci cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen( 23892f3ab15Sopenharmony_ci self.pctx, 23992f3ab15Sopenharmony_ci len.as_raw(), 24092f3ab15Sopenharmony_ci )) 24192f3ab15Sopenharmony_ci .map(|_| ()) 24292f3ab15Sopenharmony_ci } 24392f3ab15Sopenharmony_ci } 24492f3ab15Sopenharmony_ci 24592f3ab15Sopenharmony_ci /// Sets the RSA MGF1 algorithm. 24692f3ab15Sopenharmony_ci /// 24792f3ab15Sopenharmony_ci /// This is only useful for RSA keys. 24892f3ab15Sopenharmony_ci /// 24992f3ab15Sopenharmony_ci /// This corresponds to [`EVP_PKEY_CTX_set_rsa_mgf1_md`]. 25092f3ab15Sopenharmony_ci /// 25192f3ab15Sopenharmony_ci /// [`EVP_PKEY_CTX_set_rsa_mgf1_md`]: https://www.openssl.org/docs/manmaster/man7/RSA-PSS.html 25292f3ab15Sopenharmony_ci pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> { 25392f3ab15Sopenharmony_ci unsafe { 25492f3ab15Sopenharmony_ci cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md( 25592f3ab15Sopenharmony_ci self.pctx, 25692f3ab15Sopenharmony_ci md.as_ptr() as *mut _, 25792f3ab15Sopenharmony_ci )) 25892f3ab15Sopenharmony_ci .map(|_| ()) 25992f3ab15Sopenharmony_ci } 26092f3ab15Sopenharmony_ci } 26192f3ab15Sopenharmony_ci 26292f3ab15Sopenharmony_ci /// Feeds more data into the `Signer`. 26392f3ab15Sopenharmony_ci /// 26492f3ab15Sopenharmony_ci /// Please note that PureEdDSA (Ed25519 and Ed448 keys) do not support streaming. 26592f3ab15Sopenharmony_ci /// Use `sign_oneshot` instead. 26692f3ab15Sopenharmony_ci /// 26792f3ab15Sopenharmony_ci /// OpenSSL documentation at [`EVP_DigestUpdate`]. 26892f3ab15Sopenharmony_ci /// 26992f3ab15Sopenharmony_ci /// [`EVP_DigestUpdate`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestInit.html 27092f3ab15Sopenharmony_ci pub fn update(&mut self, buf: &[u8]) -> Result<(), ErrorStack> { 27192f3ab15Sopenharmony_ci unsafe { 27292f3ab15Sopenharmony_ci cvt(ffi::EVP_DigestUpdate( 27392f3ab15Sopenharmony_ci self.md_ctx, 27492f3ab15Sopenharmony_ci buf.as_ptr() as *const _, 27592f3ab15Sopenharmony_ci buf.len(), 27692f3ab15Sopenharmony_ci )) 27792f3ab15Sopenharmony_ci .map(|_| ()) 27892f3ab15Sopenharmony_ci } 27992f3ab15Sopenharmony_ci } 28092f3ab15Sopenharmony_ci 28192f3ab15Sopenharmony_ci /// Computes an upper bound on the signature length. 28292f3ab15Sopenharmony_ci /// 28392f3ab15Sopenharmony_ci /// The actual signature may be shorter than this value. Check the return value of 28492f3ab15Sopenharmony_ci /// `sign` to get the exact length. 28592f3ab15Sopenharmony_ci /// 28692f3ab15Sopenharmony_ci /// OpenSSL documentation at [`EVP_DigestSignFinal`]. 28792f3ab15Sopenharmony_ci /// 28892f3ab15Sopenharmony_ci /// [`EVP_DigestSignFinal`]: https://www.openssl.org/docs/manmaster/crypto/EVP_DigestSignFinal.html 28992f3ab15Sopenharmony_ci pub fn len(&self) -> Result<usize, ErrorStack> { 29092f3ab15Sopenharmony_ci self.len_intern() 29192f3ab15Sopenharmony_ci } 29292f3ab15Sopenharmony_ci 29392f3ab15Sopenharmony_ci #[cfg(all(not(ossl111), not(boringssl), not(libressl370)))] 29492f3ab15Sopenharmony_ci fn len_intern(&self) -> Result<usize, ErrorStack> { 29592f3ab15Sopenharmony_ci unsafe { 29692f3ab15Sopenharmony_ci let mut len = 0; 29792f3ab15Sopenharmony_ci cvt(ffi::EVP_DigestSignFinal( 29892f3ab15Sopenharmony_ci self.md_ctx, 29992f3ab15Sopenharmony_ci ptr::null_mut(), 30092f3ab15Sopenharmony_ci &mut len, 30192f3ab15Sopenharmony_ci ))?; 30292f3ab15Sopenharmony_ci Ok(len) 30392f3ab15Sopenharmony_ci } 30492f3ab15Sopenharmony_ci } 30592f3ab15Sopenharmony_ci 30692f3ab15Sopenharmony_ci #[cfg(any(ossl111, boringssl, libressl370))] 30792f3ab15Sopenharmony_ci fn len_intern(&self) -> Result<usize, ErrorStack> { 30892f3ab15Sopenharmony_ci unsafe { 30992f3ab15Sopenharmony_ci let mut len = 0; 31092f3ab15Sopenharmony_ci cvt(ffi::EVP_DigestSign( 31192f3ab15Sopenharmony_ci self.md_ctx, 31292f3ab15Sopenharmony_ci ptr::null_mut(), 31392f3ab15Sopenharmony_ci &mut len, 31492f3ab15Sopenharmony_ci ptr::null(), 31592f3ab15Sopenharmony_ci 0, 31692f3ab15Sopenharmony_ci ))?; 31792f3ab15Sopenharmony_ci Ok(len) 31892f3ab15Sopenharmony_ci } 31992f3ab15Sopenharmony_ci } 32092f3ab15Sopenharmony_ci 32192f3ab15Sopenharmony_ci /// Writes the signature into the provided buffer, returning the number of bytes written. 32292f3ab15Sopenharmony_ci /// 32392f3ab15Sopenharmony_ci /// This method will fail if the buffer is not large enough for the signature. Use the `len` 32492f3ab15Sopenharmony_ci /// method to get an upper bound on the required size. 32592f3ab15Sopenharmony_ci /// 32692f3ab15Sopenharmony_ci /// OpenSSL documentation at [`EVP_DigestSignFinal`]. 32792f3ab15Sopenharmony_ci /// 32892f3ab15Sopenharmony_ci /// [`EVP_DigestSignFinal`]: https://www.openssl.org/docs/manmaster/crypto/EVP_DigestSignFinal.html 32992f3ab15Sopenharmony_ci pub fn sign(&self, buf: &mut [u8]) -> Result<usize, ErrorStack> { 33092f3ab15Sopenharmony_ci unsafe { 33192f3ab15Sopenharmony_ci let mut len = buf.len(); 33292f3ab15Sopenharmony_ci cvt(ffi::EVP_DigestSignFinal( 33392f3ab15Sopenharmony_ci self.md_ctx, 33492f3ab15Sopenharmony_ci buf.as_mut_ptr() as *mut _, 33592f3ab15Sopenharmony_ci &mut len, 33692f3ab15Sopenharmony_ci ))?; 33792f3ab15Sopenharmony_ci Ok(len) 33892f3ab15Sopenharmony_ci } 33992f3ab15Sopenharmony_ci } 34092f3ab15Sopenharmony_ci 34192f3ab15Sopenharmony_ci /// Returns the signature. 34292f3ab15Sopenharmony_ci /// 34392f3ab15Sopenharmony_ci /// This is a simple convenience wrapper over `len` and `sign`. 34492f3ab15Sopenharmony_ci pub fn sign_to_vec(&self) -> Result<Vec<u8>, ErrorStack> { 34592f3ab15Sopenharmony_ci let mut buf = vec![0; self.len()?]; 34692f3ab15Sopenharmony_ci let len = self.sign(&mut buf)?; 34792f3ab15Sopenharmony_ci // The advertised length is not always equal to the real length for things like DSA 34892f3ab15Sopenharmony_ci buf.truncate(len); 34992f3ab15Sopenharmony_ci Ok(buf) 35092f3ab15Sopenharmony_ci } 35192f3ab15Sopenharmony_ci 35292f3ab15Sopenharmony_ci /// Signs the data in `data_buf` and writes the signature into the buffer `sig_buf`, returning the 35392f3ab15Sopenharmony_ci /// number of bytes written. 35492f3ab15Sopenharmony_ci /// 35592f3ab15Sopenharmony_ci /// For PureEdDSA (Ed25519 and Ed448 keys), this is the only way to sign data. 35692f3ab15Sopenharmony_ci /// 35792f3ab15Sopenharmony_ci /// This method will fail if the buffer is not large enough for the signature. Use the `len` 35892f3ab15Sopenharmony_ci /// method to get an upper bound on the required size. 35992f3ab15Sopenharmony_ci /// 36092f3ab15Sopenharmony_ci /// OpenSSL documentation at [`EVP_DigestSign`]. 36192f3ab15Sopenharmony_ci /// 36292f3ab15Sopenharmony_ci /// [`EVP_DigestSign`]: https://www.openssl.org/docs/man1.1.1/man3/EVP_DigestSign.html 36392f3ab15Sopenharmony_ci #[cfg(any(ossl111, boringssl, libressl370))] 36492f3ab15Sopenharmony_ci pub fn sign_oneshot( 36592f3ab15Sopenharmony_ci &mut self, 36692f3ab15Sopenharmony_ci sig_buf: &mut [u8], 36792f3ab15Sopenharmony_ci data_buf: &[u8], 36892f3ab15Sopenharmony_ci ) -> Result<usize, ErrorStack> { 36992f3ab15Sopenharmony_ci unsafe { 37092f3ab15Sopenharmony_ci let mut sig_len = sig_buf.len(); 37192f3ab15Sopenharmony_ci cvt(ffi::EVP_DigestSign( 37292f3ab15Sopenharmony_ci self.md_ctx, 37392f3ab15Sopenharmony_ci sig_buf.as_mut_ptr() as *mut _, 37492f3ab15Sopenharmony_ci &mut sig_len, 37592f3ab15Sopenharmony_ci data_buf.as_ptr() as *const _, 37692f3ab15Sopenharmony_ci data_buf.len(), 37792f3ab15Sopenharmony_ci ))?; 37892f3ab15Sopenharmony_ci Ok(sig_len) 37992f3ab15Sopenharmony_ci } 38092f3ab15Sopenharmony_ci } 38192f3ab15Sopenharmony_ci 38292f3ab15Sopenharmony_ci /// Returns the signature. 38392f3ab15Sopenharmony_ci /// 38492f3ab15Sopenharmony_ci /// This is a simple convenience wrapper over `len` and `sign_oneshot`. 38592f3ab15Sopenharmony_ci #[cfg(any(ossl111, boringssl, libressl370))] 38692f3ab15Sopenharmony_ci pub fn sign_oneshot_to_vec(&mut self, data_buf: &[u8]) -> Result<Vec<u8>, ErrorStack> { 38792f3ab15Sopenharmony_ci let mut sig_buf = vec![0; self.len()?]; 38892f3ab15Sopenharmony_ci let len = self.sign_oneshot(&mut sig_buf, data_buf)?; 38992f3ab15Sopenharmony_ci // The advertised length is not always equal to the real length for things like DSA 39092f3ab15Sopenharmony_ci sig_buf.truncate(len); 39192f3ab15Sopenharmony_ci Ok(sig_buf) 39292f3ab15Sopenharmony_ci } 39392f3ab15Sopenharmony_ci} 39492f3ab15Sopenharmony_ci 39592f3ab15Sopenharmony_ciimpl<'a> Write for Signer<'a> { 39692f3ab15Sopenharmony_ci fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 39792f3ab15Sopenharmony_ci self.update(buf)?; 39892f3ab15Sopenharmony_ci Ok(buf.len()) 39992f3ab15Sopenharmony_ci } 40092f3ab15Sopenharmony_ci 40192f3ab15Sopenharmony_ci fn flush(&mut self) -> io::Result<()> { 40292f3ab15Sopenharmony_ci Ok(()) 40392f3ab15Sopenharmony_ci } 40492f3ab15Sopenharmony_ci} 40592f3ab15Sopenharmony_ci 40692f3ab15Sopenharmony_ci/// A type which can be used to verify the integrity and authenticity 40792f3ab15Sopenharmony_ci/// of data given the signature. 40892f3ab15Sopenharmony_cipub struct Verifier<'a> { 40992f3ab15Sopenharmony_ci md_ctx: *mut ffi::EVP_MD_CTX, 41092f3ab15Sopenharmony_ci pctx: *mut ffi::EVP_PKEY_CTX, 41192f3ab15Sopenharmony_ci pkey_pd: PhantomData<&'a ()>, 41292f3ab15Sopenharmony_ci} 41392f3ab15Sopenharmony_ci 41492f3ab15Sopenharmony_ciunsafe impl<'a> Sync for Verifier<'a> {} 41592f3ab15Sopenharmony_ciunsafe impl<'a> Send for Verifier<'a> {} 41692f3ab15Sopenharmony_ci 41792f3ab15Sopenharmony_ciimpl<'a> Drop for Verifier<'a> { 41892f3ab15Sopenharmony_ci fn drop(&mut self) { 41992f3ab15Sopenharmony_ci // pkey_ctx is owned by the md_ctx, so no need to explicitly free it. 42092f3ab15Sopenharmony_ci unsafe { 42192f3ab15Sopenharmony_ci EVP_MD_CTX_free(self.md_ctx); 42292f3ab15Sopenharmony_ci } 42392f3ab15Sopenharmony_ci } 42492f3ab15Sopenharmony_ci} 42592f3ab15Sopenharmony_ci 42692f3ab15Sopenharmony_ci/// A type which verifies cryptographic signatures of data. 42792f3ab15Sopenharmony_ciimpl<'a> Verifier<'a> { 42892f3ab15Sopenharmony_ci /// Creates a new `Verifier`. 42992f3ab15Sopenharmony_ci /// 43092f3ab15Sopenharmony_ci /// This cannot be used with Ed25519 or Ed448 keys. Please refer to 43192f3ab15Sopenharmony_ci /// [`Verifier::new_without_digest`]. 43292f3ab15Sopenharmony_ci /// 43392f3ab15Sopenharmony_ci /// OpenSSL documentation at [`EVP_DigestVerifyInit`]. 43492f3ab15Sopenharmony_ci /// 43592f3ab15Sopenharmony_ci /// [`EVP_DigestVerifyInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestVerifyInit.html 43692f3ab15Sopenharmony_ci pub fn new<T>(type_: MessageDigest, pkey: &'a PKeyRef<T>) -> Result<Verifier<'a>, ErrorStack> 43792f3ab15Sopenharmony_ci where 43892f3ab15Sopenharmony_ci T: HasPublic, 43992f3ab15Sopenharmony_ci { 44092f3ab15Sopenharmony_ci Verifier::new_intern(Some(type_), pkey) 44192f3ab15Sopenharmony_ci } 44292f3ab15Sopenharmony_ci 44392f3ab15Sopenharmony_ci /// Creates a new `Verifier` without a digest. 44492f3ab15Sopenharmony_ci /// 44592f3ab15Sopenharmony_ci /// This is the only way to create a `Verifier` for Ed25519 or Ed448 keys. 44692f3ab15Sopenharmony_ci /// 44792f3ab15Sopenharmony_ci /// OpenSSL documentation at [`EVP_DigestVerifyInit`]. 44892f3ab15Sopenharmony_ci /// 44992f3ab15Sopenharmony_ci /// [`EVP_DigestVerifyInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestVerifyInit.html 45092f3ab15Sopenharmony_ci pub fn new_without_digest<T>(pkey: &'a PKeyRef<T>) -> Result<Verifier<'a>, ErrorStack> 45192f3ab15Sopenharmony_ci where 45292f3ab15Sopenharmony_ci T: HasPublic, 45392f3ab15Sopenharmony_ci { 45492f3ab15Sopenharmony_ci Verifier::new_intern(None, pkey) 45592f3ab15Sopenharmony_ci } 45692f3ab15Sopenharmony_ci 45792f3ab15Sopenharmony_ci fn new_intern<T>( 45892f3ab15Sopenharmony_ci type_: Option<MessageDigest>, 45992f3ab15Sopenharmony_ci pkey: &'a PKeyRef<T>, 46092f3ab15Sopenharmony_ci ) -> Result<Verifier<'a>, ErrorStack> 46192f3ab15Sopenharmony_ci where 46292f3ab15Sopenharmony_ci T: HasPublic, 46392f3ab15Sopenharmony_ci { 46492f3ab15Sopenharmony_ci unsafe { 46592f3ab15Sopenharmony_ci ffi::init(); 46692f3ab15Sopenharmony_ci 46792f3ab15Sopenharmony_ci let ctx = cvt_p(EVP_MD_CTX_new())?; 46892f3ab15Sopenharmony_ci let mut pctx: *mut ffi::EVP_PKEY_CTX = ptr::null_mut(); 46992f3ab15Sopenharmony_ci let r = ffi::EVP_DigestVerifyInit( 47092f3ab15Sopenharmony_ci ctx, 47192f3ab15Sopenharmony_ci &mut pctx, 47292f3ab15Sopenharmony_ci type_.map(|t| t.as_ptr()).unwrap_or(ptr::null()), 47392f3ab15Sopenharmony_ci ptr::null_mut(), 47492f3ab15Sopenharmony_ci pkey.as_ptr(), 47592f3ab15Sopenharmony_ci ); 47692f3ab15Sopenharmony_ci if r != 1 { 47792f3ab15Sopenharmony_ci EVP_MD_CTX_free(ctx); 47892f3ab15Sopenharmony_ci return Err(ErrorStack::get()); 47992f3ab15Sopenharmony_ci } 48092f3ab15Sopenharmony_ci 48192f3ab15Sopenharmony_ci assert!(!pctx.is_null()); 48292f3ab15Sopenharmony_ci 48392f3ab15Sopenharmony_ci Ok(Verifier { 48492f3ab15Sopenharmony_ci md_ctx: ctx, 48592f3ab15Sopenharmony_ci pctx, 48692f3ab15Sopenharmony_ci pkey_pd: PhantomData, 48792f3ab15Sopenharmony_ci }) 48892f3ab15Sopenharmony_ci } 48992f3ab15Sopenharmony_ci } 49092f3ab15Sopenharmony_ci 49192f3ab15Sopenharmony_ci /// Returns the RSA padding mode in use. 49292f3ab15Sopenharmony_ci /// 49392f3ab15Sopenharmony_ci /// This is only useful for RSA keys. 49492f3ab15Sopenharmony_ci /// 49592f3ab15Sopenharmony_ci /// This corresponds to `EVP_PKEY_CTX_get_rsa_padding`. 49692f3ab15Sopenharmony_ci pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> { 49792f3ab15Sopenharmony_ci unsafe { 49892f3ab15Sopenharmony_ci let mut pad = 0; 49992f3ab15Sopenharmony_ci cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.pctx, &mut pad)) 50092f3ab15Sopenharmony_ci .map(|_| Padding::from_raw(pad)) 50192f3ab15Sopenharmony_ci } 50292f3ab15Sopenharmony_ci } 50392f3ab15Sopenharmony_ci 50492f3ab15Sopenharmony_ci /// Sets the RSA padding mode. 50592f3ab15Sopenharmony_ci /// 50692f3ab15Sopenharmony_ci /// This is only useful for RSA keys. 50792f3ab15Sopenharmony_ci /// 50892f3ab15Sopenharmony_ci /// This corresponds to [`EVP_PKEY_CTX_set_rsa_padding`]. 50992f3ab15Sopenharmony_ci /// 51092f3ab15Sopenharmony_ci /// [`EVP_PKEY_CTX_set_rsa_padding`]: https://www.openssl.org/docs/manmaster/crypto/EVP_PKEY_CTX_set_rsa_padding.html 51192f3ab15Sopenharmony_ci pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> { 51292f3ab15Sopenharmony_ci unsafe { 51392f3ab15Sopenharmony_ci cvt(ffi::EVP_PKEY_CTX_set_rsa_padding( 51492f3ab15Sopenharmony_ci self.pctx, 51592f3ab15Sopenharmony_ci padding.as_raw(), 51692f3ab15Sopenharmony_ci )) 51792f3ab15Sopenharmony_ci .map(|_| ()) 51892f3ab15Sopenharmony_ci } 51992f3ab15Sopenharmony_ci } 52092f3ab15Sopenharmony_ci 52192f3ab15Sopenharmony_ci /// Sets the RSA PSS salt length. 52292f3ab15Sopenharmony_ci /// 52392f3ab15Sopenharmony_ci /// This is only useful for RSA keys. 52492f3ab15Sopenharmony_ci /// 52592f3ab15Sopenharmony_ci /// This corresponds to [`EVP_PKEY_CTX_set_rsa_pss_saltlen`]. 52692f3ab15Sopenharmony_ci /// 52792f3ab15Sopenharmony_ci /// [`EVP_PKEY_CTX_set_rsa_pss_saltlen`]: https://www.openssl.org/docs/manmaster/crypto/EVP_PKEY_CTX_set_rsa_pss_saltlen.html 52892f3ab15Sopenharmony_ci pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> { 52992f3ab15Sopenharmony_ci unsafe { 53092f3ab15Sopenharmony_ci cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen( 53192f3ab15Sopenharmony_ci self.pctx, 53292f3ab15Sopenharmony_ci len.as_raw(), 53392f3ab15Sopenharmony_ci )) 53492f3ab15Sopenharmony_ci .map(|_| ()) 53592f3ab15Sopenharmony_ci } 53692f3ab15Sopenharmony_ci } 53792f3ab15Sopenharmony_ci 53892f3ab15Sopenharmony_ci /// Sets the RSA MGF1 algorithm. 53992f3ab15Sopenharmony_ci /// 54092f3ab15Sopenharmony_ci /// This is only useful for RSA keys. 54192f3ab15Sopenharmony_ci /// 54292f3ab15Sopenharmony_ci /// This corresponds to [`EVP_PKEY_CTX_set_rsa_mgf1_md`]. 54392f3ab15Sopenharmony_ci /// 54492f3ab15Sopenharmony_ci /// [`EVP_PKEY_CTX_set_rsa_mgf1_md`]: https://www.openssl.org/docs/manmaster/man7/RSA-PSS.html 54592f3ab15Sopenharmony_ci pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> { 54692f3ab15Sopenharmony_ci unsafe { 54792f3ab15Sopenharmony_ci cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md( 54892f3ab15Sopenharmony_ci self.pctx, 54992f3ab15Sopenharmony_ci md.as_ptr() as *mut _, 55092f3ab15Sopenharmony_ci )) 55192f3ab15Sopenharmony_ci .map(|_| ()) 55292f3ab15Sopenharmony_ci } 55392f3ab15Sopenharmony_ci } 55492f3ab15Sopenharmony_ci 55592f3ab15Sopenharmony_ci /// Feeds more data into the `Verifier`. 55692f3ab15Sopenharmony_ci /// 55792f3ab15Sopenharmony_ci /// Please note that PureEdDSA (Ed25519 and Ed448 keys) do not support streaming. 55892f3ab15Sopenharmony_ci /// Use [`Verifier::verify_oneshot`] instead. 55992f3ab15Sopenharmony_ci /// 56092f3ab15Sopenharmony_ci /// OpenSSL documentation at [`EVP_DigestUpdate`]. 56192f3ab15Sopenharmony_ci /// 56292f3ab15Sopenharmony_ci /// [`EVP_DigestUpdate`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestInit.html 56392f3ab15Sopenharmony_ci pub fn update(&mut self, buf: &[u8]) -> Result<(), ErrorStack> { 56492f3ab15Sopenharmony_ci unsafe { 56592f3ab15Sopenharmony_ci cvt(ffi::EVP_DigestUpdate( 56692f3ab15Sopenharmony_ci self.md_ctx, 56792f3ab15Sopenharmony_ci buf.as_ptr() as *const _, 56892f3ab15Sopenharmony_ci buf.len(), 56992f3ab15Sopenharmony_ci )) 57092f3ab15Sopenharmony_ci .map(|_| ()) 57192f3ab15Sopenharmony_ci } 57292f3ab15Sopenharmony_ci } 57392f3ab15Sopenharmony_ci 57492f3ab15Sopenharmony_ci /// Determines if the data fed into the `Verifier` matches the provided signature. 57592f3ab15Sopenharmony_ci /// 57692f3ab15Sopenharmony_ci /// OpenSSL documentation at [`EVP_DigestVerifyFinal`]. 57792f3ab15Sopenharmony_ci /// 57892f3ab15Sopenharmony_ci /// [`EVP_DigestVerifyFinal`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestVerifyFinal.html 57992f3ab15Sopenharmony_ci pub fn verify(&self, signature: &[u8]) -> Result<bool, ErrorStack> { 58092f3ab15Sopenharmony_ci unsafe { 58192f3ab15Sopenharmony_ci let r = 58292f3ab15Sopenharmony_ci EVP_DigestVerifyFinal(self.md_ctx, signature.as_ptr() as *mut _, signature.len()); 58392f3ab15Sopenharmony_ci match r { 58492f3ab15Sopenharmony_ci 1 => Ok(true), 58592f3ab15Sopenharmony_ci 0 => { 58692f3ab15Sopenharmony_ci ErrorStack::get(); // discard error stack 58792f3ab15Sopenharmony_ci Ok(false) 58892f3ab15Sopenharmony_ci } 58992f3ab15Sopenharmony_ci _ => Err(ErrorStack::get()), 59092f3ab15Sopenharmony_ci } 59192f3ab15Sopenharmony_ci } 59292f3ab15Sopenharmony_ci } 59392f3ab15Sopenharmony_ci 59492f3ab15Sopenharmony_ci /// Determines if the data given in `buf` matches the provided signature. 59592f3ab15Sopenharmony_ci /// 59692f3ab15Sopenharmony_ci /// OpenSSL documentation at [`EVP_DigestVerify`]. 59792f3ab15Sopenharmony_ci /// 59892f3ab15Sopenharmony_ci /// [`EVP_DigestVerify`]: https://www.openssl.org/docs/man1.1.1/man3/EVP_DigestVerify.html 59992f3ab15Sopenharmony_ci #[cfg(any(ossl111, boringssl, libressl370))] 60092f3ab15Sopenharmony_ci pub fn verify_oneshot(&mut self, signature: &[u8], buf: &[u8]) -> Result<bool, ErrorStack> { 60192f3ab15Sopenharmony_ci unsafe { 60292f3ab15Sopenharmony_ci let r = ffi::EVP_DigestVerify( 60392f3ab15Sopenharmony_ci self.md_ctx, 60492f3ab15Sopenharmony_ci signature.as_ptr() as *const _, 60592f3ab15Sopenharmony_ci signature.len(), 60692f3ab15Sopenharmony_ci buf.as_ptr() as *const _, 60792f3ab15Sopenharmony_ci buf.len(), 60892f3ab15Sopenharmony_ci ); 60992f3ab15Sopenharmony_ci match r { 61092f3ab15Sopenharmony_ci 1 => Ok(true), 61192f3ab15Sopenharmony_ci 0 => { 61292f3ab15Sopenharmony_ci ErrorStack::get(); 61392f3ab15Sopenharmony_ci Ok(false) 61492f3ab15Sopenharmony_ci } 61592f3ab15Sopenharmony_ci _ => Err(ErrorStack::get()), 61692f3ab15Sopenharmony_ci } 61792f3ab15Sopenharmony_ci } 61892f3ab15Sopenharmony_ci } 61992f3ab15Sopenharmony_ci} 62092f3ab15Sopenharmony_ci 62192f3ab15Sopenharmony_ciimpl<'a> Write for Verifier<'a> { 62292f3ab15Sopenharmony_ci fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 62392f3ab15Sopenharmony_ci self.update(buf)?; 62492f3ab15Sopenharmony_ci Ok(buf.len()) 62592f3ab15Sopenharmony_ci } 62692f3ab15Sopenharmony_ci 62792f3ab15Sopenharmony_ci fn flush(&mut self) -> io::Result<()> { 62892f3ab15Sopenharmony_ci Ok(()) 62992f3ab15Sopenharmony_ci } 63092f3ab15Sopenharmony_ci} 63192f3ab15Sopenharmony_ci 63292f3ab15Sopenharmony_ci#[cfg(not(ossl101))] 63392f3ab15Sopenharmony_ciuse ffi::EVP_DigestVerifyFinal; 63492f3ab15Sopenharmony_ci 63592f3ab15Sopenharmony_ci#[cfg(ossl101)] 63692f3ab15Sopenharmony_ci#[allow(bad_style)] 63792f3ab15Sopenharmony_ciunsafe fn EVP_DigestVerifyFinal( 63892f3ab15Sopenharmony_ci ctx: *mut ffi::EVP_MD_CTX, 63992f3ab15Sopenharmony_ci sigret: *const ::libc::c_uchar, 64092f3ab15Sopenharmony_ci siglen: ::libc::size_t, 64192f3ab15Sopenharmony_ci) -> ::libc::c_int { 64292f3ab15Sopenharmony_ci ffi::EVP_DigestVerifyFinal(ctx, sigret as *mut _, siglen) 64392f3ab15Sopenharmony_ci} 64492f3ab15Sopenharmony_ci 64592f3ab15Sopenharmony_ci#[cfg(test)] 64692f3ab15Sopenharmony_cimod test { 64792f3ab15Sopenharmony_ci use hex::{self, FromHex}; 64892f3ab15Sopenharmony_ci #[cfg(not(boringssl))] 64992f3ab15Sopenharmony_ci use std::iter; 65092f3ab15Sopenharmony_ci 65192f3ab15Sopenharmony_ci use crate::ec::{EcGroup, EcKey}; 65292f3ab15Sopenharmony_ci use crate::hash::MessageDigest; 65392f3ab15Sopenharmony_ci use crate::nid::Nid; 65492f3ab15Sopenharmony_ci use crate::pkey::PKey; 65592f3ab15Sopenharmony_ci use crate::rsa::{Padding, Rsa}; 65692f3ab15Sopenharmony_ci #[cfg(ossl111)] 65792f3ab15Sopenharmony_ci use crate::sign::RsaPssSaltlen; 65892f3ab15Sopenharmony_ci use crate::sign::{Signer, Verifier}; 65992f3ab15Sopenharmony_ci 66092f3ab15Sopenharmony_ci const INPUT: &str = 66192f3ab15Sopenharmony_ci "65794a68624763694f694a53557a49314e694a392e65794a7063334d694f694a71623255694c41304b49434a6c\ 66292f3ab15Sopenharmony_ci 654841694f6a457a4d4441344d546b7a4f44417344516f67496d6830644841364c79396c654746746347786c4c\ 66392f3ab15Sopenharmony_ci 6d4e76625339706331397962323930496a7030636e566c6651"; 66492f3ab15Sopenharmony_ci 66592f3ab15Sopenharmony_ci const SIGNATURE: &str = 66692f3ab15Sopenharmony_ci "702e218943e88fd11eb5d82dbf7845f34106ae1b81fff7731116add1717d83656d420afd3c96eedd73a2663e51\ 66792f3ab15Sopenharmony_ci 66687b000b87226e0187ed1073f945e582adfcef16d85a798ee8c66ddb3db8975b17d09402beedd5d9d9700710\ 66892f3ab15Sopenharmony_ci 8db28160d5f8040ca7445762b81fbe7ff9d92e0ae76f24f25b33bbe6f44ae61eb1040acb20044d3ef9128ed401\ 66992f3ab15Sopenharmony_ci 30795bd4bd3b41eecad066ab651981fde48df77f372dc38b9fafdd3befb18b5da3cc3c2eb02f9e3a41d612caad\ 67092f3ab15Sopenharmony_ci 15911273a05f23b9e838faaf849d698429ef5a1e88798236c3d40e604522a544c8f27a7a2db80663d16cf7caea\ 67192f3ab15Sopenharmony_ci 56de405cb2215a45b2c25566b55ac1a748a070dfc8a32a469543d019eefb47"; 67292f3ab15Sopenharmony_ci 67392f3ab15Sopenharmony_ci #[test] 67492f3ab15Sopenharmony_ci fn rsa_sign() { 67592f3ab15Sopenharmony_ci let key = include_bytes!("../test/rsa.pem"); 67692f3ab15Sopenharmony_ci let private_key = Rsa::private_key_from_pem(key).unwrap(); 67792f3ab15Sopenharmony_ci let pkey = PKey::from_rsa(private_key).unwrap(); 67892f3ab15Sopenharmony_ci 67992f3ab15Sopenharmony_ci let mut signer = Signer::new(MessageDigest::sha256(), &pkey).unwrap(); 68092f3ab15Sopenharmony_ci assert_eq!(signer.rsa_padding().unwrap(), Padding::PKCS1); 68192f3ab15Sopenharmony_ci signer.set_rsa_padding(Padding::PKCS1).unwrap(); 68292f3ab15Sopenharmony_ci signer.update(&Vec::from_hex(INPUT).unwrap()).unwrap(); 68392f3ab15Sopenharmony_ci let result = signer.sign_to_vec().unwrap(); 68492f3ab15Sopenharmony_ci 68592f3ab15Sopenharmony_ci assert_eq!(hex::encode(result), SIGNATURE); 68692f3ab15Sopenharmony_ci } 68792f3ab15Sopenharmony_ci 68892f3ab15Sopenharmony_ci #[test] 68992f3ab15Sopenharmony_ci fn rsa_verify_ok() { 69092f3ab15Sopenharmony_ci let key = include_bytes!("../test/rsa.pem"); 69192f3ab15Sopenharmony_ci let private_key = Rsa::private_key_from_pem(key).unwrap(); 69292f3ab15Sopenharmony_ci let pkey = PKey::from_rsa(private_key).unwrap(); 69392f3ab15Sopenharmony_ci 69492f3ab15Sopenharmony_ci let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap(); 69592f3ab15Sopenharmony_ci assert_eq!(verifier.rsa_padding().unwrap(), Padding::PKCS1); 69692f3ab15Sopenharmony_ci verifier.update(&Vec::from_hex(INPUT).unwrap()).unwrap(); 69792f3ab15Sopenharmony_ci assert!(verifier.verify(&Vec::from_hex(SIGNATURE).unwrap()).unwrap()); 69892f3ab15Sopenharmony_ci } 69992f3ab15Sopenharmony_ci 70092f3ab15Sopenharmony_ci #[test] 70192f3ab15Sopenharmony_ci fn rsa_verify_invalid() { 70292f3ab15Sopenharmony_ci let key = include_bytes!("../test/rsa.pem"); 70392f3ab15Sopenharmony_ci let private_key = Rsa::private_key_from_pem(key).unwrap(); 70492f3ab15Sopenharmony_ci let pkey = PKey::from_rsa(private_key).unwrap(); 70592f3ab15Sopenharmony_ci 70692f3ab15Sopenharmony_ci let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap(); 70792f3ab15Sopenharmony_ci verifier.update(&Vec::from_hex(INPUT).unwrap()).unwrap(); 70892f3ab15Sopenharmony_ci verifier.update(b"foobar").unwrap(); 70992f3ab15Sopenharmony_ci assert!(!verifier.verify(&Vec::from_hex(SIGNATURE).unwrap()).unwrap()); 71092f3ab15Sopenharmony_ci } 71192f3ab15Sopenharmony_ci 71292f3ab15Sopenharmony_ci #[cfg(not(boringssl))] 71392f3ab15Sopenharmony_ci fn test_hmac(ty: MessageDigest, tests: &[(Vec<u8>, Vec<u8>, Vec<u8>)]) { 71492f3ab15Sopenharmony_ci for (key, data, res) in tests.iter() { 71592f3ab15Sopenharmony_ci let pkey = PKey::hmac(key).unwrap(); 71692f3ab15Sopenharmony_ci let mut signer = Signer::new(ty, &pkey).unwrap(); 71792f3ab15Sopenharmony_ci signer.update(data).unwrap(); 71892f3ab15Sopenharmony_ci assert_eq!(signer.sign_to_vec().unwrap(), *res); 71992f3ab15Sopenharmony_ci } 72092f3ab15Sopenharmony_ci } 72192f3ab15Sopenharmony_ci 72292f3ab15Sopenharmony_ci #[test] 72392f3ab15Sopenharmony_ci #[cfg(not(boringssl))] 72492f3ab15Sopenharmony_ci fn hmac_md5() { 72592f3ab15Sopenharmony_ci // test vectors from RFC 2202 72692f3ab15Sopenharmony_ci let tests: [(Vec<u8>, Vec<u8>, Vec<u8>); 7] = [ 72792f3ab15Sopenharmony_ci ( 72892f3ab15Sopenharmony_ci iter::repeat(0x0b_u8).take(16).collect(), 72992f3ab15Sopenharmony_ci b"Hi There".to_vec(), 73092f3ab15Sopenharmony_ci Vec::from_hex("9294727a3638bb1c13f48ef8158bfc9d").unwrap(), 73192f3ab15Sopenharmony_ci ), 73292f3ab15Sopenharmony_ci ( 73392f3ab15Sopenharmony_ci b"Jefe".to_vec(), 73492f3ab15Sopenharmony_ci b"what do ya want for nothing?".to_vec(), 73592f3ab15Sopenharmony_ci Vec::from_hex("750c783e6ab0b503eaa86e310a5db738").unwrap(), 73692f3ab15Sopenharmony_ci ), 73792f3ab15Sopenharmony_ci ( 73892f3ab15Sopenharmony_ci iter::repeat(0xaa_u8).take(16).collect(), 73992f3ab15Sopenharmony_ci iter::repeat(0xdd_u8).take(50).collect(), 74092f3ab15Sopenharmony_ci Vec::from_hex("56be34521d144c88dbb8c733f0e8b3f6").unwrap(), 74192f3ab15Sopenharmony_ci ), 74292f3ab15Sopenharmony_ci ( 74392f3ab15Sopenharmony_ci Vec::from_hex("0102030405060708090a0b0c0d0e0f10111213141516171819").unwrap(), 74492f3ab15Sopenharmony_ci iter::repeat(0xcd_u8).take(50).collect(), 74592f3ab15Sopenharmony_ci Vec::from_hex("697eaf0aca3a3aea3a75164746ffaa79").unwrap(), 74692f3ab15Sopenharmony_ci ), 74792f3ab15Sopenharmony_ci ( 74892f3ab15Sopenharmony_ci iter::repeat(0x0c_u8).take(16).collect(), 74992f3ab15Sopenharmony_ci b"Test With Truncation".to_vec(), 75092f3ab15Sopenharmony_ci Vec::from_hex("56461ef2342edc00f9bab995690efd4c").unwrap(), 75192f3ab15Sopenharmony_ci ), 75292f3ab15Sopenharmony_ci ( 75392f3ab15Sopenharmony_ci iter::repeat(0xaa_u8).take(80).collect(), 75492f3ab15Sopenharmony_ci b"Test Using Larger Than Block-Size Key - Hash Key First".to_vec(), 75592f3ab15Sopenharmony_ci Vec::from_hex("6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd").unwrap(), 75692f3ab15Sopenharmony_ci ), 75792f3ab15Sopenharmony_ci ( 75892f3ab15Sopenharmony_ci iter::repeat(0xaa_u8).take(80).collect(), 75992f3ab15Sopenharmony_ci b"Test Using Larger Than Block-Size Key \ 76092f3ab15Sopenharmony_ci and Larger Than One Block-Size Data" 76192f3ab15Sopenharmony_ci .to_vec(), 76292f3ab15Sopenharmony_ci Vec::from_hex("6f630fad67cda0ee1fb1f562db3aa53e").unwrap(), 76392f3ab15Sopenharmony_ci ), 76492f3ab15Sopenharmony_ci ]; 76592f3ab15Sopenharmony_ci 76692f3ab15Sopenharmony_ci test_hmac(MessageDigest::md5(), &tests); 76792f3ab15Sopenharmony_ci } 76892f3ab15Sopenharmony_ci 76992f3ab15Sopenharmony_ci #[test] 77092f3ab15Sopenharmony_ci #[cfg(not(boringssl))] 77192f3ab15Sopenharmony_ci fn hmac_sha1() { 77292f3ab15Sopenharmony_ci // test vectors from RFC 2202 77392f3ab15Sopenharmony_ci let tests: [(Vec<u8>, Vec<u8>, Vec<u8>); 7] = [ 77492f3ab15Sopenharmony_ci ( 77592f3ab15Sopenharmony_ci iter::repeat(0x0b_u8).take(20).collect(), 77692f3ab15Sopenharmony_ci b"Hi There".to_vec(), 77792f3ab15Sopenharmony_ci Vec::from_hex("b617318655057264e28bc0b6fb378c8ef146be00").unwrap(), 77892f3ab15Sopenharmony_ci ), 77992f3ab15Sopenharmony_ci ( 78092f3ab15Sopenharmony_ci b"Jefe".to_vec(), 78192f3ab15Sopenharmony_ci b"what do ya want for nothing?".to_vec(), 78292f3ab15Sopenharmony_ci Vec::from_hex("effcdf6ae5eb2fa2d27416d5f184df9c259a7c79").unwrap(), 78392f3ab15Sopenharmony_ci ), 78492f3ab15Sopenharmony_ci ( 78592f3ab15Sopenharmony_ci iter::repeat(0xaa_u8).take(20).collect(), 78692f3ab15Sopenharmony_ci iter::repeat(0xdd_u8).take(50).collect(), 78792f3ab15Sopenharmony_ci Vec::from_hex("125d7342b9ac11cd91a39af48aa17b4f63f175d3").unwrap(), 78892f3ab15Sopenharmony_ci ), 78992f3ab15Sopenharmony_ci ( 79092f3ab15Sopenharmony_ci Vec::from_hex("0102030405060708090a0b0c0d0e0f10111213141516171819").unwrap(), 79192f3ab15Sopenharmony_ci iter::repeat(0xcd_u8).take(50).collect(), 79292f3ab15Sopenharmony_ci Vec::from_hex("4c9007f4026250c6bc8414f9bf50c86c2d7235da").unwrap(), 79392f3ab15Sopenharmony_ci ), 79492f3ab15Sopenharmony_ci ( 79592f3ab15Sopenharmony_ci iter::repeat(0x0c_u8).take(20).collect(), 79692f3ab15Sopenharmony_ci b"Test With Truncation".to_vec(), 79792f3ab15Sopenharmony_ci Vec::from_hex("4c1a03424b55e07fe7f27be1d58bb9324a9a5a04").unwrap(), 79892f3ab15Sopenharmony_ci ), 79992f3ab15Sopenharmony_ci ( 80092f3ab15Sopenharmony_ci iter::repeat(0xaa_u8).take(80).collect(), 80192f3ab15Sopenharmony_ci b"Test Using Larger Than Block-Size Key - Hash Key First".to_vec(), 80292f3ab15Sopenharmony_ci Vec::from_hex("aa4ae5e15272d00e95705637ce8a3b55ed402112").unwrap(), 80392f3ab15Sopenharmony_ci ), 80492f3ab15Sopenharmony_ci ( 80592f3ab15Sopenharmony_ci iter::repeat(0xaa_u8).take(80).collect(), 80692f3ab15Sopenharmony_ci b"Test Using Larger Than Block-Size Key \ 80792f3ab15Sopenharmony_ci and Larger Than One Block-Size Data" 80892f3ab15Sopenharmony_ci .to_vec(), 80992f3ab15Sopenharmony_ci Vec::from_hex("e8e99d0f45237d786d6bbaa7965c7808bbff1a91").unwrap(), 81092f3ab15Sopenharmony_ci ), 81192f3ab15Sopenharmony_ci ]; 81292f3ab15Sopenharmony_ci 81392f3ab15Sopenharmony_ci test_hmac(MessageDigest::sha1(), &tests); 81492f3ab15Sopenharmony_ci } 81592f3ab15Sopenharmony_ci 81692f3ab15Sopenharmony_ci #[test] 81792f3ab15Sopenharmony_ci #[cfg(ossl110)] 81892f3ab15Sopenharmony_ci fn test_cmac() { 81992f3ab15Sopenharmony_ci let cipher = crate::symm::Cipher::aes_128_cbc(); 82092f3ab15Sopenharmony_ci let key = Vec::from_hex("9294727a3638bb1c13f48ef8158bfc9d").unwrap(); 82192f3ab15Sopenharmony_ci let pkey = PKey::cmac(&cipher, &key).unwrap(); 82292f3ab15Sopenharmony_ci let mut signer = Signer::new_without_digest(&pkey).unwrap(); 82392f3ab15Sopenharmony_ci 82492f3ab15Sopenharmony_ci let data = b"Hi There"; 82592f3ab15Sopenharmony_ci signer.update(data as &[u8]).unwrap(); 82692f3ab15Sopenharmony_ci 82792f3ab15Sopenharmony_ci let expected = vec![ 82892f3ab15Sopenharmony_ci 136, 101, 61, 167, 61, 30, 248, 234, 124, 166, 196, 157, 203, 52, 171, 19, 82992f3ab15Sopenharmony_ci ]; 83092f3ab15Sopenharmony_ci assert_eq!(signer.sign_to_vec().unwrap(), expected); 83192f3ab15Sopenharmony_ci } 83292f3ab15Sopenharmony_ci 83392f3ab15Sopenharmony_ci #[test] 83492f3ab15Sopenharmony_ci fn ec() { 83592f3ab15Sopenharmony_ci let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); 83692f3ab15Sopenharmony_ci let key = EcKey::generate(&group).unwrap(); 83792f3ab15Sopenharmony_ci let key = PKey::from_ec_key(key).unwrap(); 83892f3ab15Sopenharmony_ci 83992f3ab15Sopenharmony_ci let mut signer = Signer::new(MessageDigest::sha256(), &key).unwrap(); 84092f3ab15Sopenharmony_ci signer.update(b"hello world").unwrap(); 84192f3ab15Sopenharmony_ci let signature = signer.sign_to_vec().unwrap(); 84292f3ab15Sopenharmony_ci 84392f3ab15Sopenharmony_ci let mut verifier = Verifier::new(MessageDigest::sha256(), &key).unwrap(); 84492f3ab15Sopenharmony_ci verifier.update(b"hello world").unwrap(); 84592f3ab15Sopenharmony_ci assert!(verifier.verify(&signature).unwrap()); 84692f3ab15Sopenharmony_ci } 84792f3ab15Sopenharmony_ci 84892f3ab15Sopenharmony_ci #[test] 84992f3ab15Sopenharmony_ci #[cfg(any(ossl111, boringssl, libressl370))] 85092f3ab15Sopenharmony_ci fn eddsa() { 85192f3ab15Sopenharmony_ci let key = PKey::generate_ed25519().unwrap(); 85292f3ab15Sopenharmony_ci 85392f3ab15Sopenharmony_ci let mut signer = Signer::new_without_digest(&key).unwrap(); 85492f3ab15Sopenharmony_ci let signature = signer.sign_oneshot_to_vec(b"hello world").unwrap(); 85592f3ab15Sopenharmony_ci 85692f3ab15Sopenharmony_ci let mut verifier = Verifier::new_without_digest(&key).unwrap(); 85792f3ab15Sopenharmony_ci assert!(verifier.verify_oneshot(&signature, b"hello world").unwrap()); 85892f3ab15Sopenharmony_ci } 85992f3ab15Sopenharmony_ci 86092f3ab15Sopenharmony_ci #[test] 86192f3ab15Sopenharmony_ci #[cfg(ossl111)] 86292f3ab15Sopenharmony_ci fn rsa_sign_verify() { 86392f3ab15Sopenharmony_ci let key = include_bytes!("../test/rsa.pem"); 86492f3ab15Sopenharmony_ci let private_key = Rsa::private_key_from_pem(key).unwrap(); 86592f3ab15Sopenharmony_ci let pkey = PKey::from_rsa(private_key).unwrap(); 86692f3ab15Sopenharmony_ci 86792f3ab15Sopenharmony_ci let mut signer = Signer::new(MessageDigest::sha256(), &pkey).unwrap(); 86892f3ab15Sopenharmony_ci signer.set_rsa_padding(Padding::PKCS1_PSS).unwrap(); 86992f3ab15Sopenharmony_ci assert_eq!(signer.rsa_padding().unwrap(), Padding::PKCS1_PSS); 87092f3ab15Sopenharmony_ci signer 87192f3ab15Sopenharmony_ci .set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH) 87292f3ab15Sopenharmony_ci .unwrap(); 87392f3ab15Sopenharmony_ci signer.set_rsa_mgf1_md(MessageDigest::sha256()).unwrap(); 87492f3ab15Sopenharmony_ci signer.update(&Vec::from_hex(INPUT).unwrap()).unwrap(); 87592f3ab15Sopenharmony_ci let signature = signer.sign_to_vec().unwrap(); 87692f3ab15Sopenharmony_ci 87792f3ab15Sopenharmony_ci let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap(); 87892f3ab15Sopenharmony_ci verifier.set_rsa_padding(Padding::PKCS1_PSS).unwrap(); 87992f3ab15Sopenharmony_ci verifier 88092f3ab15Sopenharmony_ci .set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH) 88192f3ab15Sopenharmony_ci .unwrap(); 88292f3ab15Sopenharmony_ci verifier.set_rsa_mgf1_md(MessageDigest::sha256()).unwrap(); 88392f3ab15Sopenharmony_ci verifier.update(&Vec::from_hex(INPUT).unwrap()).unwrap(); 88492f3ab15Sopenharmony_ci assert!(verifier.verify(&signature).unwrap()); 88592f3ab15Sopenharmony_ci } 88692f3ab15Sopenharmony_ci} 887