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

Merge pull request #1373 from max-heller/revocation-checking

Support for enabling CRL-based certificate revocation checking
parents 838e2d1c 1dec6506
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -342,6 +342,8 @@ cfg_if! {
    }
}

pub enum X509_LOOKUP_METHOD {}

pub enum X509_NAME {}

cfg_if! {
+3 −0
Original line number Diff line number Diff line
@@ -1003,6 +1003,9 @@ extern "C" {

    pub fn SSL_new(ctx: *mut SSL_CTX) -> *mut SSL;

    #[cfg(any(ossl102, libressl261))]
    pub fn SSL_CTX_get0_param(ctx: *mut SSL_CTX) -> *mut X509_VERIFY_PARAM;

    #[cfg(any(ossl102, libressl261))]
    pub fn SSL_get0_param(ssl: *mut SSL) -> *mut X509_VERIFY_PARAM;
}
+77 −0
Original line number Diff line number Diff line
@@ -95,6 +95,71 @@ cfg_if! {
    }
}

#[cfg(not(ossl110))]
pub const X509_V_FLAG_CB_ISSUER_CHECK: c_ulong = 0x1;
#[cfg(ossl110)]
pub const X509_V_FLAG_CB_ISSUER_CHECK: c_ulong = 0x0;
pub const X509_V_FLAG_USE_CHECK_TIME: c_ulong = 0x2;
pub const X509_V_FLAG_CRL_CHECK: c_ulong = 0x4;
pub const X509_V_FLAG_CRL_CHECK_ALL: c_ulong = 0x8;
pub const X509_V_FLAG_IGNORE_CRITICAL: c_ulong = 0x10;
pub const X509_V_FLAG_X509_STRICT: c_ulong = 0x20;
pub const X509_V_FLAG_ALLOW_PROXY_CERTS: c_ulong = 0x40;
pub const X509_V_FLAG_POLICY_CHECK: c_ulong = 0x80;
pub const X509_V_FLAG_EXPLICIT_POLICY: c_ulong = 0x100;
pub const X509_V_FLAG_INHIBIT_ANY: c_ulong = 0x200;
pub const X509_V_FLAG_INHIBIT_MAP: c_ulong = 0x400;
pub const X509_V_FLAG_NOTIFY_POLICY: c_ulong = 0x800;
pub const X509_V_FLAG_EXTENDED_CRL_SUPPORT: c_ulong = 0x1000;
pub const X509_V_FLAG_USE_DELTAS: c_ulong = 0x2000;
pub const X509_V_FLAG_CHECK_SS_SIGNATURE: c_ulong = 0x4000;
#[cfg(ossl102)]
pub const X509_V_FLAG_TRUSTED_FIRST: c_ulong = 0x8000;
#[cfg(ossl102)]
pub const X509_V_FLAG_SUITEB_128_LOS_ONLY: c_ulong = 0x10000;
#[cfg(ossl102)]
pub const X509_V_FLAG_SUITEB_192_LOS: c_ulong = 0x20000;
#[cfg(ossl102)]
pub const X509_V_FLAG_SUITEB_128_LOS: c_ulong = 0x30000;
#[cfg(ossl102)]
pub const X509_V_FLAG_PARTIAL_CHAIN: c_ulong = 0x80000;
#[cfg(ossl110)]
pub const X509_V_FLAG_NO_ALT_CHAINS: c_ulong = 0x100000;
#[cfg(ossl110)]
pub const X509_V_FLAG_NO_CHECK_TIME: c_ulong = 0x200000;

extern "C" {
    #[cfg(ossl110)]
    pub fn X509_LOOKUP_meth_free(method: *mut X509_LOOKUP_METHOD);
}

extern "C" {
    pub fn X509_LOOKUP_free(ctx: *mut X509_LOOKUP);
    pub fn X509_LOOKUP_hash_dir() -> *mut X509_LOOKUP_METHOD;
    pub fn X509_LOOKUP_ctrl(
        ctx: *mut X509_LOOKUP,
        cmd: c_int,
        argc: *const c_char,
        argl: c_long,
        ret: *mut *mut c_char,
    ) -> c_int;
}

pub unsafe fn X509_LOOKUP_add_dir(
    ctx: *mut X509_LOOKUP,
    name: *const c_char,
    _type: c_int,
) -> c_int {
    const X509_L_ADD_DIR: c_int = 2;
    X509_LOOKUP_ctrl(
        ctx,
        X509_L_ADD_DIR,
        name,
        _type as c_long,
        std::ptr::null_mut(),
    )
}

extern "C" {
    pub fn X509_STORE_new() -> *mut X509_STORE;
    pub fn X509_STORE_free(store: *mut X509_STORE);
@@ -112,6 +177,11 @@ extern "C" {

    pub fn X509_STORE_add_cert(store: *mut X509_STORE, x: *mut X509) -> c_int;

    pub fn X509_STORE_add_lookup(
        store: *mut X509_STORE,
        meth: *mut X509_LOOKUP_METHOD,
    ) -> *mut X509_LOOKUP;

    pub fn X509_STORE_set_default_paths(store: *mut X509_STORE) -> c_int;

    pub fn X509_STORE_CTX_get_ex_data(ctx: *mut X509_STORE_CTX, idx: c_int) -> *mut c_void;
@@ -136,6 +206,13 @@ extern "C" {
    #[cfg(any(ossl102, libressl261))]
    pub fn X509_VERIFY_PARAM_free(param: *mut X509_VERIFY_PARAM);

    #[cfg(any(ossl102, libressl261))]
    pub fn X509_VERIFY_PARAM_set_flags(param: *mut X509_VERIFY_PARAM, flags: c_ulong) -> c_int;
    #[cfg(any(ossl102, libressl261))]
    pub fn X509_VERIFY_PARAM_clear_flags(param: *mut X509_VERIFY_PARAM, flags: c_ulong) -> c_int;
    #[cfg(any(ossl102, libressl261))]
    pub fn X509_VERIFY_PARAM_get_flags(param: *mut X509_VERIFY_PARAM) -> c_ulong;

    #[cfg(any(ossl102, libressl261))]
    pub fn X509_VERIFY_PARAM_set1_host(
        param: *mut X509_VERIFY_PARAM,
+24 −0
Original line number Diff line number Diff line
@@ -1342,6 +1342,30 @@ impl SslContextBuilder {
        unsafe { X509StoreBuilderRef::from_ptr_mut(ffi::SSL_CTX_get_cert_store(self.as_ptr())) }
    }

    /// Returns a reference to the X509 verification configuration.
    ///
    /// Requires OpenSSL 1.0.2 or newer.
    ///
    /// This corresponds to [`SSL_CTX_get0_param`].
    ///
    /// [`SSL_CTX_get0_param`]: https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_get0_param.html
    #[cfg(any(ossl102, libressl261))]
    pub fn verify_param(&self) -> &X509VerifyParamRef {
        unsafe { X509VerifyParamRef::from_ptr(ffi::SSL_CTX_get0_param(self.as_ptr())) }
    }

    /// Returns a mutable reference to the X509 verification configuration.
    ///
    /// Requires OpenSSL 1.0.2 or newer.
    ///
    /// This corresponds to [`SSL_CTX_get0_param`].
    ///
    /// [`SSL_CTX_get0_param`]: https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_get0_param.html
    #[cfg(any(ossl102, libressl261))]
    pub fn verify_param_mut(&mut self) -> &mut X509VerifyParamRef {
        unsafe { X509VerifyParamRef::from_ptr_mut(ffi::SSL_CTX_get0_param(self.as_ptr())) }
    }

    /// Sets the callback dealing with OCSP stapling.
    ///
    /// On the client side, this callback is responsible for validating the OCSP status response
+79 −0
Original line number Diff line number Diff line
@@ -94,6 +94,85 @@ impl X509StoreBuilderRef {
    pub fn set_default_paths(&mut self) -> Result<(), ErrorStack> {
        unsafe { cvt(ffi::X509_STORE_set_default_paths(self.as_ptr())).map(|_| ()) }
    }

    /// Adds a lookup method to the store.
    ///
    /// This corresponds to [`X509_STORE_add_lookup`].
    ///
    /// [`X509_STORE_add_lookup`]: https://www.openssl.org/docs/man1.1.1/man3/X509_STORE_add_lookup.html
    pub fn add_lookup<T>(
        &mut self,
        method: &'static X509LookupMethodRef<T>,
    ) -> Result<&mut X509LookupRef<T>, ErrorStack> {
        let lookup = unsafe { ffi::X509_STORE_add_lookup(self.as_ptr(), method.as_ptr()) };
        cvt_p(lookup).map(|ptr| unsafe { X509LookupRef::from_ptr_mut(ptr) })
    }
}

generic_foreign_type_and_impl_send_sync! {
    type CType = ffi::X509_LOOKUP;
    fn drop = ffi::X509_LOOKUP_free;

    /// Information used by an `X509Store` to look up certificates and CRLs.
    pub struct X509Lookup<T>;
    /// Reference to an `X509Lookup`.
    pub struct X509LookupRef<T>;
}

/// Marker type corresponding to the [`X509_LOOKUP_hash_dir`] lookup method.
///
/// [`X509_LOOKUP_hash_dir`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_LOOKUP_hash_dir.html
pub struct HashDir;

impl X509Lookup<HashDir> {
    /// Lookup method that loads certificates and CRLs on demand and caches
    /// them in memory once they are loaded. It also checks for newer CRLs upon
    /// each lookup, so that newer CRLs are used as soon as they appear in the
    /// directory.
    ///
    /// This corresponds to [`X509_LOOKUP_hash_dir`].
    ///
    /// [`X509_LOOKUP_hash_dir`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_LOOKUP_hash_dir.html
    pub fn hash_dir() -> &'static X509LookupMethodRef<HashDir> {
        unsafe { X509LookupMethodRef::from_ptr(ffi::X509_LOOKUP_hash_dir()) }
    }
}

impl X509LookupRef<HashDir> {
    /// Specifies a directory from which certificates and CRLs will be loaded
    /// on-demand. Must be used with `X509Lookup::hash_dir`.
    ///
    /// This corresponds to [`X509_LOOKUP_add_dir`].
    ///
    /// [`X509_LOOKUP_add_dir`]: https://www.openssl.org/docs/man1.1.1/man3/X509_LOOKUP_add_dir.html
    pub fn add_dir(
        &mut self,
        name: &str,
        file_type: crate::ssl::SslFiletype,
    ) -> Result<(), ErrorStack> {
        let name = std::ffi::CString::new(name).unwrap();
        unsafe {
            cvt(ffi::X509_LOOKUP_add_dir(
                self.as_ptr(),
                name.as_ptr(),
                file_type.as_raw(),
            ))
            .map(|_| ())
        }
    }
}

generic_foreign_type_and_impl_send_sync! {
    type CType = ffi::X509_LOOKUP_METHOD;
    fn drop = |_method| {
        #[cfg(ossl110)]
        ffi::X509_LOOKUP_meth_free(_method);
    };

    /// Method used to look up certificates and CRLs.
    pub struct X509LookupMethod<T>;
    /// Reference to an `X509LookupMethod`.
    pub struct X509LookupMethodRef<T>;
}

foreign_type_and_impl_send_sync! {
Loading