224 lines
5.4 KiB
Rust
224 lines
5.4 KiB
Rust
#[cfg(ossl300)]
|
|
use crate::cvt_p;
|
|
#[cfg(ossl300)]
|
|
use crate::error::ErrorStack;
|
|
#[cfg(ossl300)]
|
|
use crate::lib_ctx::LibCtxRef;
|
|
use crate::nid::Nid;
|
|
use cfg_if::cfg_if;
|
|
use foreign_types::{ForeignTypeRef, Opaque};
|
|
use openssl_macros::corresponds;
|
|
#[cfg(ossl300)]
|
|
use std::ffi::CString;
|
|
#[cfg(ossl300)]
|
|
use std::ptr;
|
|
|
|
cfg_if! {
|
|
if #[cfg(ossl300)] {
|
|
use foreign_types::ForeignType;
|
|
use std::ops::{Deref, DerefMut};
|
|
|
|
type Inner = *mut ffi::EVP_MD;
|
|
|
|
impl Drop for Md {
|
|
#[inline]
|
|
fn drop(&mut self) {
|
|
unsafe {
|
|
ffi::EVP_MD_free(self.as_ptr());
|
|
}
|
|
}
|
|
}
|
|
|
|
impl ForeignType for Md {
|
|
type CType = ffi::EVP_MD;
|
|
type Ref = MdRef;
|
|
|
|
#[inline]
|
|
unsafe fn from_ptr(ptr: *mut Self::CType) -> Self {
|
|
Md(ptr)
|
|
}
|
|
|
|
#[inline]
|
|
fn as_ptr(&self) -> *mut Self::CType {
|
|
self.0
|
|
}
|
|
}
|
|
|
|
impl Deref for Md {
|
|
type Target = MdRef;
|
|
|
|
#[inline]
|
|
fn deref(&self) -> &Self::Target {
|
|
unsafe {
|
|
MdRef::from_ptr(self.as_ptr())
|
|
}
|
|
}
|
|
}
|
|
|
|
impl DerefMut for Md {
|
|
#[inline]
|
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
unsafe {
|
|
MdRef::from_ptr_mut(self.as_ptr())
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
enum Inner {}
|
|
}
|
|
}
|
|
|
|
/// A message digest algorithm.
|
|
pub struct Md(Inner);
|
|
|
|
unsafe impl Sync for Md {}
|
|
unsafe impl Send for Md {}
|
|
|
|
impl Md {
|
|
/// Returns the `Md` corresponding to an [`Nid`].
|
|
#[corresponds(EVP_get_digestbynid)]
|
|
pub fn from_nid(type_: Nid) -> Option<&'static MdRef> {
|
|
unsafe {
|
|
let ptr = ffi::EVP_get_digestbynid(type_.as_raw());
|
|
if ptr.is_null() {
|
|
None
|
|
} else {
|
|
Some(MdRef::from_ptr(ptr as *mut _))
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Fetches an `Md` object corresponding to the specified algorithm name and properties.
|
|
///
|
|
/// Requires OpenSSL 3.0.0 or newer.
|
|
#[corresponds(EVP_MD_fetch)]
|
|
#[cfg(ossl300)]
|
|
pub fn fetch(
|
|
ctx: Option<&LibCtxRef>,
|
|
algorithm: &str,
|
|
properties: Option<&str>,
|
|
) -> Result<Self, ErrorStack> {
|
|
let algorithm = CString::new(algorithm).unwrap();
|
|
let properties = properties.map(|s| CString::new(s).unwrap());
|
|
|
|
unsafe {
|
|
let ptr = cvt_p(ffi::EVP_MD_fetch(
|
|
ctx.map_or(ptr::null_mut(), ForeignTypeRef::as_ptr),
|
|
algorithm.as_ptr(),
|
|
properties.map_or(ptr::null_mut(), |s| s.as_ptr()),
|
|
))?;
|
|
|
|
Ok(Md::from_ptr(ptr))
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub fn null() -> &'static MdRef {
|
|
unsafe { MdRef::from_ptr(ffi::EVP_md_null() as *mut _) }
|
|
}
|
|
|
|
#[inline]
|
|
pub fn md5() -> &'static MdRef {
|
|
unsafe { MdRef::from_ptr(ffi::EVP_md5() as *mut _) }
|
|
}
|
|
|
|
#[inline]
|
|
pub fn sha1() -> &'static MdRef {
|
|
unsafe { MdRef::from_ptr(ffi::EVP_sha1() as *mut _) }
|
|
}
|
|
|
|
#[inline]
|
|
pub fn sha224() -> &'static MdRef {
|
|
unsafe { MdRef::from_ptr(ffi::EVP_sha224() as *mut _) }
|
|
}
|
|
|
|
#[inline]
|
|
pub fn sha256() -> &'static MdRef {
|
|
unsafe { MdRef::from_ptr(ffi::EVP_sha256() as *mut _) }
|
|
}
|
|
|
|
#[inline]
|
|
pub fn sha384() -> &'static MdRef {
|
|
unsafe { MdRef::from_ptr(ffi::EVP_sha384() as *mut _) }
|
|
}
|
|
|
|
#[inline]
|
|
pub fn sha512() -> &'static MdRef {
|
|
unsafe { MdRef::from_ptr(ffi::EVP_sha512() as *mut _) }
|
|
}
|
|
|
|
#[cfg(ossl111)]
|
|
#[inline]
|
|
pub fn sha3_224() -> &'static MdRef {
|
|
unsafe { MdRef::from_ptr(ffi::EVP_sha3_224() as *mut _) }
|
|
}
|
|
|
|
#[cfg(ossl111)]
|
|
#[inline]
|
|
pub fn sha3_256() -> &'static MdRef {
|
|
unsafe { MdRef::from_ptr(ffi::EVP_sha3_256() as *mut _) }
|
|
}
|
|
|
|
#[cfg(ossl111)]
|
|
#[inline]
|
|
pub fn sha3_384() -> &'static MdRef {
|
|
unsafe { MdRef::from_ptr(ffi::EVP_sha3_384() as *mut _) }
|
|
}
|
|
|
|
#[cfg(ossl111)]
|
|
#[inline]
|
|
pub fn sha3_512() -> &'static MdRef {
|
|
unsafe { MdRef::from_ptr(ffi::EVP_sha3_512() as *mut _) }
|
|
}
|
|
|
|
#[cfg(ossl111)]
|
|
#[inline]
|
|
pub fn shake128() -> &'static MdRef {
|
|
unsafe { MdRef::from_ptr(ffi::EVP_shake128() as *mut _) }
|
|
}
|
|
|
|
#[cfg(ossl111)]
|
|
#[inline]
|
|
pub fn shake256() -> &'static MdRef {
|
|
unsafe { MdRef::from_ptr(ffi::EVP_shake256() as *mut _) }
|
|
}
|
|
|
|
#[cfg(not(osslconf = "OPENSSL_NO_RMD160"))]
|
|
#[inline]
|
|
pub fn ripemd160() -> &'static MdRef {
|
|
unsafe { MdRef::from_ptr(ffi::EVP_ripemd160() as *mut _) }
|
|
}
|
|
|
|
#[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM3")))]
|
|
#[inline]
|
|
pub fn sm3() -> &'static MdRef {
|
|
unsafe { MdRef::from_ptr(ffi::EVP_sm3() as *mut _) }
|
|
}
|
|
}
|
|
|
|
/// A reference to an [`Md`].
|
|
pub struct MdRef(Opaque);
|
|
|
|
impl ForeignTypeRef for MdRef {
|
|
type CType = ffi::EVP_MD;
|
|
}
|
|
|
|
unsafe impl Sync for MdRef {}
|
|
unsafe impl Send for MdRef {}
|
|
|
|
impl MdRef {
|
|
/// Returns the size of the digest in bytes.
|
|
#[corresponds(EVP_MD_size)]
|
|
#[inline]
|
|
pub fn size(&self) -> usize {
|
|
unsafe { ffi::EVP_MD_size(self.as_ptr()) as usize }
|
|
}
|
|
|
|
/// Returns the [`Nid`] of the digest.
|
|
#[corresponds(EVP_MD_type)]
|
|
#[inline]
|
|
pub fn type_(&self) -> Nid {
|
|
unsafe { Nid::from_raw(ffi::EVP_MD_type(self.as_ptr())) }
|
|
}
|
|
}
|