Commit 5ae938ee authored by Alex Baker's avatar Alex Baker
Browse files

Add support for X509_load_cert_file

parent 4edda635
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@ extern "C" {
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_file() -> *mut X509_LOOKUP_METHOD;
    pub fn X509_LOOKUP_ctrl(
        ctx: *mut X509_LOOKUP,
        cmd: c_int,
@@ -19,6 +20,7 @@ extern "C" {
        argl: c_long,
        ret: *mut *mut c_char,
    ) -> c_int;
    pub fn X509_load_cert_file(ctx: *mut X509_LOOKUP, file: *const c_char, _type: c_int) -> c_int;
}

extern "C" {
+33 −0
Original line number Diff line number Diff line
@@ -56,6 +56,8 @@ use crate::{cvt, cvt_p};
use openssl_macros::corresponds;
#[cfg(not(boringssl))]
use std::ffi::CString;
#[cfg(not(boringssl))]
use std::path::Path;

foreign_type_and_impl_send_sync! {
    type CType = ffi::X509_STORE;
@@ -176,6 +178,37 @@ impl X509LookupRef<HashDir> {
    }
}

/// Marker type corresponding to the [`X509_LOOKUP_file`] lookup method.
///
/// [`X509_LOOKUP_file`]: https://www.openssl.org/docs/man1.1.1/man3/X509_LOOKUP_file.html
pub struct File;

impl X509Lookup<File> {
    /// Lookup method loads all the certificates or CRLs present in a file
    /// into memory at the time the file is added as a lookup source.
    #[corresponds(X509_LOOKUP_file)]
    pub fn file() -> &'static X509LookupMethodRef<File> {
        unsafe { X509LookupMethodRef::from_ptr(ffi::X509_LOOKUP_file()) }
    }
}

#[cfg(not(boringssl))]
impl X509LookupRef<File> {
    #[corresponds(X509_load_cert_file)]
    /// Specifies a file from which certificates will be loaded
    pub fn load_cert_file<P: AsRef<Path>>(&mut self, file: P, file_type: SslFiletype) -> Result<(), ErrorStack> {
        let file = CString::new(file.as_ref().as_os_str().to_str().unwrap()).unwrap();
        unsafe {
            cvt(ffi::X509_load_cert_file(
                self.as_ptr(),
                file.as_ptr(),
                file_type.as_raw(),
            ))
            .map(|_| ())
        }
    }
}

generic_foreign_type_and_impl_send_sync! {
    type CType = ffi::X509_LOOKUP_METHOD;
    fn drop = X509_LOOKUP_meth_free;
+24 −0
Original line number Diff line number Diff line
@@ -6,11 +6,15 @@ use crate::hash::MessageDigest;
use crate::nid::Nid;
use crate::pkey::{PKey, Private};
use crate::rsa::Rsa;
#[cfg(not(boringssl))]
use crate::ssl::SslFiletype;
use crate::stack::Stack;
use crate::x509::extension::{
    AuthorityKeyIdentifier, BasicConstraints, ExtendedKeyUsage, KeyUsage, SubjectAlternativeName,
    SubjectKeyIdentifier,
};
#[cfg(not(boringssl))]
use crate::x509::store::X509Lookup;
use crate::x509::store::X509StoreBuilder;
#[cfg(any(ossl102, libressl261))]
use crate::x509::verify::{X509VerifyFlags, X509VerifyParam};
@@ -668,3 +672,23 @@ fn test_verify_param_set_depth_fails_verification() {
        expected_error
    )
}

#[test]
#[cfg(not(boringssl))]
fn test_load_cert_file() {
    let cert = include_bytes!("../../test/cert.pem");
    let cert = X509::from_pem(cert).unwrap();
    let chain = Stack::new().unwrap();

    let mut store_bldr = X509StoreBuilder::new().unwrap();
    let lookup = store_bldr.add_lookup(X509Lookup::file()).unwrap();
    lookup
        .load_cert_file("test/root-ca.pem", SslFiletype::PEM)
        .unwrap();
    let store = store_bldr.build();

    let mut context = X509StoreContext::new().unwrap();
    assert!(context
        .init(&store, &cert, &chain, |c| c.verify_cert())
        .unwrap());
}