Unverified Commit 45981114 authored by Steven Fackler's avatar Steven Fackler Committed by GitHub
Browse files

Merge pull request #1562 from sfackler/pkey-ctx

Add PkeyCtx
parents 7d000285 932ac5a1
Loading
Loading
Loading
Loading
+39 −1
Original line number Diff line number Diff line
use libc::*;

use *;

#[cfg(ossl110)]
#[inline]
#[track_caller]
pub unsafe fn OPENSSL_malloc(num: usize) -> *mut c_void {
    CRYPTO_malloc(
        num,
        concat!(file!(), "\0").as_ptr() as *const _,
        line!() as _,
    )
}

#[cfg(not(ossl110))]
#[inline]
#[track_caller]
pub unsafe fn OPENSSL_malloc(num: c_int) -> *mut c_void {
    CRYPTO_malloc(
        num,
        concat!(file!(), "\0").as_ptr() as *const _,
        line!() as _,
    )
}

#[cfg(ossl110)]
#[inline]
#[track_caller]
pub unsafe fn OPENSSL_free(addr: *mut c_void) {
    CRYPTO_free(
        addr,
        concat!(file!(), "\0").as_ptr() as *const _,
        line!() as _,
    )
}

#[cfg(not(ossl110))]
#[inline]
pub unsafe fn OPENSSL_free(addr: *mut c_void) {
    CRYPTO_free(addr)
}

#[cfg(not(ossl110))]
pub const CRYPTO_LOCK_X509: c_int = 3;
#[cfg(not(ossl110))]
+10 −0
Original line number Diff line number Diff line
@@ -149,6 +149,16 @@ extern "C" {
    #[cfg(ossl111)]
    pub fn EVP_DigestFinalXOF(ctx: *mut EVP_MD_CTX, res: *mut u8, len: usize) -> c_int;

    #[cfg(ossl300)]
    pub fn EVP_MD_fetch(
        ctx: *mut OSSL_LIB_CTX,
        algorithm: *const c_char,
        properties: *const c_char,
    ) -> *mut EVP_MD;

    #[cfg(ossl300)]
    pub fn EVP_MD_free(md: *mut EVP_MD);

    pub fn EVP_BytesToKey(
        typ: *const EVP_CIPHER,
        md: *const EVP_MD,
+2 −13
Original line number Diff line number Diff line
@@ -169,11 +169,7 @@ impl<'a> Encrypter<'a> {
    #[cfg(any(ossl102, libressl310))]
    pub fn set_rsa_oaep_label(&mut self, label: &[u8]) -> Result<(), ErrorStack> {
        unsafe {
            let p = cvt_p(ffi::CRYPTO_malloc(
                label.len() as _,
                concat!(file!(), "\0").as_ptr() as *const _,
                line!() as c_int,
            ))?;
            let p = cvt_p(ffi::OPENSSL_malloc(label.len() as _))?;
            ptr::copy_nonoverlapping(label.as_ptr(), p as *mut u8, label.len());

            cvt(ffi::EVP_PKEY_CTX_set0_rsa_oaep_label(
@@ -183,14 +179,7 @@ impl<'a> Encrypter<'a> {
            ))
            .map(|_| ())
            .map_err(|e| {
                #[cfg(not(ossl110))]
                ::ffi::CRYPTO_free(p as *mut c_void);
                #[cfg(ossl110)]
                ::ffi::CRYPTO_free(
                    p as *mut c_void,
                    concat!(file!(), "\0").as_ptr() as *const _,
                    line!() as c_int,
                );
                ffi::OPENSSL_free(p);
                e
            })
        }
+5 −0
Original line number Diff line number Diff line
@@ -153,6 +153,7 @@ pub mod fips;
pub mod hash;
#[cfg(ossl300)]
pub mod lib_ctx;
pub mod md;
pub mod memcmp;
pub mod nid;
#[cfg(not(osslconf = "OPENSSL_NO_OCSP"))]
@@ -161,6 +162,7 @@ pub mod pkcs12;
pub mod pkcs5;
pub mod pkcs7;
pub mod pkey;
pub mod pkey_ctx;
pub mod rand;
pub mod rsa;
pub mod sha;
@@ -173,6 +175,7 @@ pub mod symm;
pub mod version;
pub mod x509;

#[inline]
fn cvt_p<T>(r: *mut T) -> Result<*mut T, ErrorStack> {
    if r.is_null() {
        Err(ErrorStack::get())
@@ -181,6 +184,7 @@ fn cvt_p<T>(r: *mut T) -> Result<*mut T, ErrorStack> {
    }
}

#[inline]
fn cvt(r: c_int) -> Result<c_int, ErrorStack> {
    if r <= 0 {
        Err(ErrorStack::get())
@@ -189,6 +193,7 @@ fn cvt(r: c_int) -> Result<c_int, ErrorStack> {
    }
}

#[inline]
fn cvt_n(r: c_int) -> Result<c_int, ErrorStack> {
    if r < 0 {
        Err(ErrorStack::get())

openssl/src/md.rs

0 → 100644
+234 −0
Original line number Diff line number Diff line
#[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};
#[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`].
    ///
    /// This corresponds to [`EVP_get_digestbynid`].
    ///
    /// [`EVP_get_digestbynid`]: https://www.openssl.org/docs/manmaster/crypto/EVP_DigestInit.html
    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.
    ///
    /// This corresponds to [`EVP_MD_fetch`].
    ///
    /// Requires OpenSSL 3.0.0 or newer.
    ///
    /// [`EVP_MD_fetch`]: https://www.openssl.org/docs/manmaster/man3/EVP_MD_fetch.html
    #[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.
    ///
    /// This corresponds to [`EVP_MD_size`].
    ///
    /// [`EVP_MD_size`]: https://www.openssl.org/docs/manmaster/man3/EVP_MD_size.html
    #[inline]
    pub fn size(&self) -> usize {
        unsafe { ffi::EVP_MD_size(self.as_ptr()) as usize }
    }

    /// Returns the [`Nid`] of the digest.
    ///
    /// This corresponds to [`EVP_MD_type`].
    ///
    /// [`EVP_MD_type`]: https://www.openssl.org/docs/manmaster/man3/EVP_MD_type.html
    #[inline]
    pub fn type_(&self) -> Nid {
        unsafe { Nid::from_raw(ffi::EVP_MD_type(self.as_ptr())) }
    }
}
Loading