Commit b0a1102d authored by Steffen Eiden's avatar Steffen Eiden
Browse files

Add bindings for more X509_VERIFY_PARAM functions

parent 7df56869
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -119,4 +119,10 @@ extern "C" {
        ip: *const c_uchar,
        iplen: size_t,
    ) -> c_int;
    #[cfg(ossl110)]
    pub fn X509_VERIFY_PARAM_set_auth_level(param: *mut X509_VERIFY_PARAM, lvl: c_int);
    #[cfg(ossl110)]
    pub fn X509_VERIFY_PARAM_get_auth_level(param: *const X509_VERIFY_PARAM) -> c_int;
    #[cfg(ossl102)]
    pub fn X509_VERIFY_PARAM_set_purpose(param: *mut X509_VERIFY_PARAM, purpose: c_int) -> c_int;
}
+23 −0
Original line number Diff line number Diff line
@@ -147,3 +147,26 @@ pub unsafe fn X509_LOOKUP_add_dir(
        std::ptr::null_mut(),
    )
}

#[cfg(ossl102)]
pub const X509_PURPOSE_SSL_CLIENT: c_int = 1;
#[cfg(ossl102)]
pub const X509_PURPOSE_SSL_SERVER: c_int = 2;
#[cfg(ossl102)]
pub const X509_PURPOSE_NS_SSL_SERVER: c_int = 3;
#[cfg(ossl102)]
pub const X509_PURPOSE_SMIME_SIGN: c_int = 4;
#[cfg(ossl102)]
pub const X509_PURPOSE_SMIME_ENCRYPT: c_int = 5;
#[cfg(ossl102)]
pub const X509_PURPOSE_CRL_SIGN: c_int = 6;
#[cfg(ossl102)]
pub const X509_PURPOSE_ANY: c_int = 7;
#[cfg(ossl102)]
pub const X509_PURPOSE_OCSP_HELPER: c_int = 8;
#[cfg(ossl102)]
pub const X509_PURPOSE_TIMESTAMP_SIGN: c_int = 9;
#[cfg(ossl102)]
pub const X509_PURPOSE_MIN: c_int = 1;
#[cfg(ossl102)]
pub const X509_PURPOSE_MAX: c_int = 9;
+75 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@ use crate::x509::extension::{
#[cfg(not(boringssl))]
use crate::x509::store::X509Lookup;
use crate::x509::store::X509StoreBuilder;
#[cfg(ossl102)]
use crate::x509::verify::X509PurposeFlags;
#[cfg(any(ossl102, libressl261))]
use crate::x509::verify::{X509VerifyFlags, X509VerifyParam};
#[cfg(ossl110)]
@@ -693,3 +695,76 @@ fn test_load_cert_file() {
        .init(&store, &cert, &chain, |c| c.verify_cert())
        .unwrap());
}

#[test]
#[cfg(ossl110)]
fn test_verify_param_auth_level() {
    let mut param = X509VerifyParam::new().unwrap();
    let auth_lvl = 2;
    let auth_lvl_default = -1;

    assert_eq!(param.auth_level(), auth_lvl_default);

    param.set_auth_level(auth_lvl);
    assert_eq!(param.auth_level(), auth_lvl);
}

#[test]
#[cfg(ossl102)]
fn test_set_purpose() {
    let cert = include_bytes!("../../test/leaf.pem");
    let cert = X509::from_pem(cert).unwrap();
    let intermediate_ca = include_bytes!("../../test/intermediate-ca.pem");
    let intermediate_ca = X509::from_pem(intermediate_ca).unwrap();
    let ca = include_bytes!("../../test/root-ca.pem");
    let ca = X509::from_pem(ca).unwrap();
    let mut chain = Stack::new().unwrap();
    chain.push(intermediate_ca).unwrap();

    let mut store_bldr = X509StoreBuilder::new().unwrap();
    store_bldr.add_cert(ca).unwrap();
    let mut verify_params = X509VerifyParam::new().unwrap();
    verify_params.set_purpose(X509PurposeFlags::ANY).unwrap();
    store_bldr.set_param(&verify_params).unwrap();
    let store = store_bldr.build();
    let mut context = X509StoreContext::new().unwrap();

    assert!(context
        .init(&store, &cert, &chain, |c| c.verify_cert())
        .unwrap());
}

#[test]
#[cfg(ossl102)]
fn test_set_purpose_fails_verification() {
    let cert = include_bytes!("../../test/leaf.pem");
    let cert = X509::from_pem(cert).unwrap();
    let intermediate_ca = include_bytes!("../../test/intermediate-ca.pem");
    let intermediate_ca = X509::from_pem(intermediate_ca).unwrap();
    let ca = include_bytes!("../../test/root-ca.pem");
    let ca = X509::from_pem(ca).unwrap();
    let mut chain = Stack::new().unwrap();
    chain.push(intermediate_ca).unwrap();

    let mut store_bldr = X509StoreBuilder::new().unwrap();
    store_bldr.add_cert(ca).unwrap();
    let mut verify_params = X509VerifyParam::new().unwrap();
    verify_params
        .set_purpose(X509PurposeFlags::TIMESTAMP_SIGN)
        .unwrap();
    store_bldr.set_param(&verify_params).unwrap();
    let store = store_bldr.build();

    let expected_error = "unsupported certificate purpose";
    let mut context = X509StoreContext::new().unwrap();
    assert_eq!(
        context
            .init(&store, &cert, &chain, |c| {
                c.verify_cert()?;
                Ok(c.error())
            })
            .unwrap()
            .error_string(),
        expected_error
    )
}
+44 −0
Original line number Diff line number Diff line
@@ -162,4 +162,48 @@ impl X509VerifyParamRef {
    pub fn set_depth(&mut self, depth: c_int) {
        unsafe { ffi::X509_VERIFY_PARAM_set_depth(self.as_ptr(), depth) }
    }

    /// Sets the authentication security level to auth_level
    #[corresponds(X509_VERIFY_PARAM_set_auth_level)]
    #[cfg(ossl110)]
    pub fn set_auth_level(&mut self, lvl: c_int) {
        unsafe { ffi::X509_VERIFY_PARAM_set_auth_level(self.as_ptr(), lvl) }
    }

    /// Gets the current authentication security level
    #[corresponds(X509_VERIFY_PARAM_get_auth_level)]
    #[cfg(ossl110)]
    pub fn auth_level(&self) -> i32 {
        unsafe { ffi::X509_VERIFY_PARAM_get_auth_level(self.as_ptr()) }
    }

    /// Sets the verification purpose
    #[corresponds(X509_VERIFY_PARAM_set_purpose)]
    #[cfg(ossl102)]
    pub fn set_purpose(&mut self, purpose: X509PurposeFlags) -> Result<(), ErrorStack> {
        unsafe {
            cvt(ffi::X509_VERIFY_PARAM_set_purpose(
                self.as_ptr(),
                purpose.bits,
            ))
            .map(|_| ())
        }
    }
}

#[cfg(ossl102)]
bitflags! {
    /// Bitflags defining the purpose of the verification
    pub struct X509PurposeFlags: c_int {
        const SSL_CLIENT = ffi::X509_PURPOSE_SSL_CLIENT;
        const SSL_SERVER = ffi::X509_PURPOSE_SSL_SERVER;
        const NS_SSL_SERVER = ffi::X509_PURPOSE_NS_SSL_SERVER;
        const SMIME_SIGN = ffi::X509_PURPOSE_SMIME_SIGN;
        const SMIME_ENCRYPT = ffi::X509_PURPOSE_SMIME_ENCRYPT;
        const CRL_SIGN = ffi::X509_PURPOSE_CRL_SIGN;
        const ANY = ffi::X509_PURPOSE_ANY;
        const OCSP_HELPER = ffi::X509_PURPOSE_OCSP_HELPER;
        const TIMESTAMP_SIGN = ffi::X509_PURPOSE_TIMESTAMP_SIGN;
    }

}