Loading openssl-sys/src/evp.rs +22 −0 Original line number Diff line number Diff line Loading @@ -235,6 +235,28 @@ extern "C" { e: *mut ENGINE, pkey: *mut EVP_PKEY, ) -> c_int; } cfg_if! { if #[cfg(ossl300)] { extern "C" { pub fn EVP_DigestVerifyUpdate( ctx: *mut EVP_MD_CTX, data: *const c_void, dsize: size_t, ) -> c_int; } } else { #[inline] pub unsafe fn EVP_DigestVerifyUpdate( ctx: *mut EVP_MD_CTX, data: *const c_void, dsize: size_t, ) -> c_int { EVP_DigestUpdate(ctx, data, dsize) } } } extern "C" { pub fn EVP_SealInit( ctx: *mut EVP_CIPHER_CTX, type_: *const EVP_CIPHER, Loading openssl/src/md_ctx.rs +105 −2 Original line number Diff line number Diff line Loading @@ -21,7 +21,7 @@ //! ); //! ``` //! //! Sign data with RSA and SHA256 //! Sign and verify data with RSA and SHA256 //! //! ``` //! use openssl::md::Md; Loading @@ -29,14 +29,25 @@ //! use openssl::pkey::PKey; //! use openssl::rsa::Rsa; //! //! // Generate a random RSA key. //! let key = Rsa::generate(4096).unwrap(); //! let key = PKey::from_rsa(key).unwrap(); //! //! let text = b"Some Crypto Text"; //! //! // Create the signature //! let mut ctx = MdCtx::new().unwrap(); //! ctx.digest_sign_init(Some(Md::sha256()), &key).unwrap(); //! ctx.digest_sign_update(b"Some Crypto Text").unwrap(); //! ctx.digest_sign_update(text).unwrap(); //! let mut signature = vec![]; //! ctx.digest_sign_final_to_vec(&mut signature).unwrap(); //! //! // Verify the signature //! let mut ctx = MdCtx::new().unwrap(); //! ctx.digest_verify_init(Some(Md::sha256()), &key).unwrap(); //! ctx.digest_verify_update(text).unwrap(); //! let valid = ctx.digest_verify_final(&signature).unwrap(); //! assert!(valid); //! ``` use crate::error::ErrorStack; use crate::md::MdRef; Loading Loading @@ -121,6 +132,35 @@ impl MdCtxRef { } } /// Initializes the context to verify the signature of data. /// /// A reference to the context's inner `PkeyCtx` is returned, allowing signature settings to be configured. /// /// This corresponds to [`EVP_DigestVerifyInit`]. /// /// [`EVP_DigestVerifyInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestSignInit.html #[inline] pub fn digest_verify_init<'a, T>( &'a mut self, digest: Option<&MdRef>, pkey: &PKeyRef<T>, ) -> Result<&'a mut PkeyCtxRef<T>, ErrorStack> where T: HasPrivate, { unsafe { let mut p = ptr::null_mut(); cvt(ffi::EVP_DigestVerifyInit( self.as_ptr(), &mut p, digest.map_or(ptr::null(), |p| p.as_ptr()), ptr::null_mut(), pkey.as_ptr(), ))?; Ok(PkeyCtxRef::from_ptr_mut(p)) } } /// Updates the context with more data. /// /// This corresponds to [`EVP_DigestUpdate`]. Loading Loading @@ -157,6 +197,24 @@ impl MdCtxRef { Ok(()) } /// Updates the context with more data. /// /// This corresponds to [`EVP_DigestVerifyUpdate`]. /// /// [`EVP_DigestVerifyUpdate`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestVerifyUpdate.html #[inline] pub fn digest_verify_update(&mut self, data: &[u8]) -> Result<(), ErrorStack> { unsafe { cvt(ffi::EVP_DigestVerifyUpdate( self.as_ptr(), data.as_ptr() as *const _, data.len(), ))?; } Ok(()) } /// Copies the computed digest into the buffer, returning the number of bytes written. /// /// This corresponds to [`EVP_DigestFinal`]. Loading Loading @@ -228,6 +286,26 @@ impl MdCtxRef { Ok(len) } /// Verifies the provided signature. /// /// Returns `Ok(true)` if the signature is valid, `Ok(false)` if the signature is invalid, and `Err` if an error /// occurred. /// /// This corresponds to [`EVP_DigestVerifyFinal`]. /// /// [`EVP_DigestVerifyFinal`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestVerifyFinal.html #[inline] pub fn digest_verify_final(&mut self, signature: &[u8]) -> Result<bool, ErrorStack> { unsafe { let r = cvt(ffi::EVP_DigestVerifyFinal( self.as_ptr(), signature.as_ptr(), signature.len(), ))?; Ok(r == 1) } } /// Computes the signature of the data in `from`. /// /// If `to` is set to `None`, an upper bound on the number of bytes required for the output buffer will be Loading Loading @@ -270,4 +348,29 @@ impl MdCtxRef { to.truncate(base + len); Ok(len) } /// Verifies the signature of the data in `data`. /// /// Returns `Ok(true)` if the signature is valid, `Ok(false)` if the signature is invalid, and `Err` if an error /// occurred. /// /// Requires OpenSSL 1.1.1 or newer. /// /// This corresponds to [`EVP_DigestVerify`]. /// /// [`EVP_DigestVerify`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestVerify.html #[cfg(ossl111)] #[inline] pub fn digest_verify(&mut self, data: &[u8], signature: &[u8]) -> Result<bool, ErrorStack> { unsafe { let r = cvt(ffi::EVP_DigestVerify( self.as_ptr(), signature.as_ptr(), signature.len(), data.as_ptr(), data.len(), ))?; Ok(r == 1) } } } Loading
openssl-sys/src/evp.rs +22 −0 Original line number Diff line number Diff line Loading @@ -235,6 +235,28 @@ extern "C" { e: *mut ENGINE, pkey: *mut EVP_PKEY, ) -> c_int; } cfg_if! { if #[cfg(ossl300)] { extern "C" { pub fn EVP_DigestVerifyUpdate( ctx: *mut EVP_MD_CTX, data: *const c_void, dsize: size_t, ) -> c_int; } } else { #[inline] pub unsafe fn EVP_DigestVerifyUpdate( ctx: *mut EVP_MD_CTX, data: *const c_void, dsize: size_t, ) -> c_int { EVP_DigestUpdate(ctx, data, dsize) } } } extern "C" { pub fn EVP_SealInit( ctx: *mut EVP_CIPHER_CTX, type_: *const EVP_CIPHER, Loading
openssl/src/md_ctx.rs +105 −2 Original line number Diff line number Diff line Loading @@ -21,7 +21,7 @@ //! ); //! ``` //! //! Sign data with RSA and SHA256 //! Sign and verify data with RSA and SHA256 //! //! ``` //! use openssl::md::Md; Loading @@ -29,14 +29,25 @@ //! use openssl::pkey::PKey; //! use openssl::rsa::Rsa; //! //! // Generate a random RSA key. //! let key = Rsa::generate(4096).unwrap(); //! let key = PKey::from_rsa(key).unwrap(); //! //! let text = b"Some Crypto Text"; //! //! // Create the signature //! let mut ctx = MdCtx::new().unwrap(); //! ctx.digest_sign_init(Some(Md::sha256()), &key).unwrap(); //! ctx.digest_sign_update(b"Some Crypto Text").unwrap(); //! ctx.digest_sign_update(text).unwrap(); //! let mut signature = vec![]; //! ctx.digest_sign_final_to_vec(&mut signature).unwrap(); //! //! // Verify the signature //! let mut ctx = MdCtx::new().unwrap(); //! ctx.digest_verify_init(Some(Md::sha256()), &key).unwrap(); //! ctx.digest_verify_update(text).unwrap(); //! let valid = ctx.digest_verify_final(&signature).unwrap(); //! assert!(valid); //! ``` use crate::error::ErrorStack; use crate::md::MdRef; Loading Loading @@ -121,6 +132,35 @@ impl MdCtxRef { } } /// Initializes the context to verify the signature of data. /// /// A reference to the context's inner `PkeyCtx` is returned, allowing signature settings to be configured. /// /// This corresponds to [`EVP_DigestVerifyInit`]. /// /// [`EVP_DigestVerifyInit`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestSignInit.html #[inline] pub fn digest_verify_init<'a, T>( &'a mut self, digest: Option<&MdRef>, pkey: &PKeyRef<T>, ) -> Result<&'a mut PkeyCtxRef<T>, ErrorStack> where T: HasPrivate, { unsafe { let mut p = ptr::null_mut(); cvt(ffi::EVP_DigestVerifyInit( self.as_ptr(), &mut p, digest.map_or(ptr::null(), |p| p.as_ptr()), ptr::null_mut(), pkey.as_ptr(), ))?; Ok(PkeyCtxRef::from_ptr_mut(p)) } } /// Updates the context with more data. /// /// This corresponds to [`EVP_DigestUpdate`]. Loading Loading @@ -157,6 +197,24 @@ impl MdCtxRef { Ok(()) } /// Updates the context with more data. /// /// This corresponds to [`EVP_DigestVerifyUpdate`]. /// /// [`EVP_DigestVerifyUpdate`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestVerifyUpdate.html #[inline] pub fn digest_verify_update(&mut self, data: &[u8]) -> Result<(), ErrorStack> { unsafe { cvt(ffi::EVP_DigestVerifyUpdate( self.as_ptr(), data.as_ptr() as *const _, data.len(), ))?; } Ok(()) } /// Copies the computed digest into the buffer, returning the number of bytes written. /// /// This corresponds to [`EVP_DigestFinal`]. Loading Loading @@ -228,6 +286,26 @@ impl MdCtxRef { Ok(len) } /// Verifies the provided signature. /// /// Returns `Ok(true)` if the signature is valid, `Ok(false)` if the signature is invalid, and `Err` if an error /// occurred. /// /// This corresponds to [`EVP_DigestVerifyFinal`]. /// /// [`EVP_DigestVerifyFinal`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestVerifyFinal.html #[inline] pub fn digest_verify_final(&mut self, signature: &[u8]) -> Result<bool, ErrorStack> { unsafe { let r = cvt(ffi::EVP_DigestVerifyFinal( self.as_ptr(), signature.as_ptr(), signature.len(), ))?; Ok(r == 1) } } /// Computes the signature of the data in `from`. /// /// If `to` is set to `None`, an upper bound on the number of bytes required for the output buffer will be Loading Loading @@ -270,4 +348,29 @@ impl MdCtxRef { to.truncate(base + len); Ok(len) } /// Verifies the signature of the data in `data`. /// /// Returns `Ok(true)` if the signature is valid, `Ok(false)` if the signature is invalid, and `Err` if an error /// occurred. /// /// Requires OpenSSL 1.1.1 or newer. /// /// This corresponds to [`EVP_DigestVerify`]. /// /// [`EVP_DigestVerify`]: https://www.openssl.org/docs/manmaster/man3/EVP_DigestVerify.html #[cfg(ossl111)] #[inline] pub fn digest_verify(&mut self, data: &[u8], signature: &[u8]) -> Result<bool, ErrorStack> { unsafe { let r = cvt(ffi::EVP_DigestVerify( self.as_ptr(), signature.as_ptr(), signature.len(), data.as_ptr(), data.len(), ))?; Ok(r == 1) } } }