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

Merge pull request #1788 from bkstein/kletterstein/x509purpose

X509_PURPOSE
parents 2e986986 3b14f19c
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -645,3 +645,22 @@ extern "C" {
    pub fn X509_print(bio: *mut BIO, x509: *mut X509) -> c_int;
    pub fn X509_REQ_print(bio: *mut BIO, req: *mut X509_REQ) -> c_int;
}

#[repr(C)]
pub struct X509_PURPOSE {
    pub purpose: c_int,
    pub trust: c_int, // Default trust ID
    pub flags: c_int,
    pub check_purpose:
        Option<unsafe extern "C" fn(*const X509_PURPOSE, *const X509, c_int) -> c_int>,
    pub name: *mut c_char,
    pub sname: *mut c_char,
    pub usr_data: *mut c_void,
}

const_ptr_api! {
    extern "C" {
        pub fn X509_PURPOSE_get_by_sname(sname: #[const_ptr_if(any(ossl110, libressl280))] c_char) -> c_int;
        pub fn X509_PURPOSE_get0(idx: c_int) -> *mut X509_PURPOSE;
    }
}
+3 −0
Original line number Diff line number Diff line
@@ -48,6 +48,9 @@ extern "C" {

    pub fn X509_STORE_set_default_paths(store: *mut X509_STORE) -> c_int;
    pub fn X509_STORE_set_flags(store: *mut X509_STORE, flags: c_ulong) -> c_int;
    pub fn X509_STORE_set_purpose(ctx: *mut X509_STORE, purpose: c_int) -> c_int;
    pub fn X509_STORE_set_trust(ctx: *mut X509_STORE, trust: c_int) -> c_int;

}

const_ptr_api! {
+0 −23
Original line number Diff line number Diff line
@@ -147,26 +147,3 @@ 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;
+12 −0
Original line number Diff line number Diff line
@@ -79,3 +79,15 @@ pub const XKU_TIMESTAMP: u32 = 0x40;
pub const XKU_DVCS: u32 = 0x80;
#[cfg(ossl110)]
pub const XKU_ANYEKU: u32 = 0x100;

pub const X509_PURPOSE_SSL_CLIENT: c_int = 1;
pub const X509_PURPOSE_SSL_SERVER: c_int = 2;
pub const X509_PURPOSE_NS_SSL_SERVER: c_int = 3;
pub const X509_PURPOSE_SMIME_SIGN: c_int = 4;
pub const X509_PURPOSE_SMIME_ENCRYPT: c_int = 5;
pub const X509_PURPOSE_CRL_SIGN: c_int = 6;
pub const X509_PURPOSE_ANY: c_int = 7;
pub const X509_PURPOSE_OCSP_HELPER: c_int = 8;
pub const X509_PURPOSE_TIMESTAMP_SIGN: c_int = 9;
pub const X509_PURPOSE_MIN: c_int = 1;
pub const X509_PURPOSE_MAX: c_int = 9;
+91 −1
Original line number Diff line number Diff line
@@ -8,7 +8,7 @@
//! the secure protocol for browsing the web.

use cfg_if::cfg_if;
use foreign_types::{ForeignType, ForeignTypeRef};
use foreign_types::{ForeignType, ForeignTypeRef, Opaque};
use libc::{c_int, c_long, c_uint};
use std::cmp::{self, Ordering};
use std::error::Error;
@@ -227,6 +227,7 @@ impl X509Builder {
    /// Note that the version is zero-indexed; that is, a certificate corresponding to version 3 of
    /// the X.509 standard should pass `2` to this method.
    #[corresponds(X509_set_version)]
    #[allow(clippy::useless_conversion)]
    pub fn set_version(&mut self, version: i32) -> Result<(), ErrorStack> {
        unsafe { cvt(ffi::X509_set_version(self.0.as_ptr(), version as c_long)).map(|_| ()) }
    }
@@ -1181,6 +1182,7 @@ impl X509ReqBuilder {
    /// This corresponds to [`X509_REQ_set_version`].
    ///
    ///[`X509_REQ_set_version`]: https://www.openssl.org/docs/manmaster/crypto/X509_REQ_set_version.html
    #[allow(clippy::useless_conversion)]
    pub fn set_version(&mut self, version: i32) -> Result<(), ErrorStack> {
        unsafe {
            cvt(ffi::X509_REQ_set_version(
@@ -1737,3 +1739,91 @@ cfg_if! {
        }
    }
}

#[derive(Copy, Clone, PartialEq, Eq)]
pub struct X509PurposeId(c_int);

impl X509PurposeId {
    pub const SSL_CLIENT: X509PurposeId = X509PurposeId(ffi::X509_PURPOSE_SSL_CLIENT);
    pub const SSL_SERVER: X509PurposeId = X509PurposeId(ffi::X509_PURPOSE_SSL_SERVER);
    pub const NS_SSL_SERVER: X509PurposeId = X509PurposeId(ffi::X509_PURPOSE_NS_SSL_SERVER);
    pub const SMIME_SIGN: X509PurposeId = X509PurposeId(ffi::X509_PURPOSE_SMIME_SIGN);
    pub const SMIME_ENCRYPT: X509PurposeId = X509PurposeId(ffi::X509_PURPOSE_SMIME_ENCRYPT);
    pub const CRL_SIGN: X509PurposeId = X509PurposeId(ffi::X509_PURPOSE_CRL_SIGN);
    pub const ANY: X509PurposeId = X509PurposeId(ffi::X509_PURPOSE_ANY);
    pub const OCSP_HELPER: X509PurposeId = X509PurposeId(ffi::X509_PURPOSE_OCSP_HELPER);
    pub const TIMESTAMP_SIGN: X509PurposeId = X509PurposeId(ffi::X509_PURPOSE_TIMESTAMP_SIGN);

    /// Constructs an `X509PurposeId` from a raw OpenSSL value.
    pub fn from_raw(id: c_int) -> Self {
        X509PurposeId(id)
    }

    /// Returns the raw OpenSSL value represented by this type.
    pub fn as_raw(&self) -> c_int {
        self.0
    }
}

/// A reference to an [`X509_PURPOSE`].
pub struct X509PurposeRef(Opaque);

/// Implements a wrapper type for the static `X509_PURPOSE` table in OpenSSL.
impl ForeignTypeRef for X509PurposeRef {
    type CType = ffi::X509_PURPOSE;
}

impl X509PurposeRef {
    /// Get the internal table index of an X509_PURPOSE for a given short name. Valid short
    /// names include
    ///  - "sslclient",
    ///  - "sslserver",
    ///  - "nssslserver",
    ///  - "smimesign",
    ///  - "smimeencrypt",
    ///  - "crlsign",
    ///  - "any",
    ///  - "ocsphelper",
    ///  - "timestampsign"
    /// The index can be used with `X509PurposeRef::from_idx()` to get the purpose.
    #[allow(clippy::unnecessary_cast)]
    pub fn get_by_sname(sname: &str) -> Result<c_int, ErrorStack> {
        unsafe {
            let sname = CString::new(sname).unwrap();
            cfg_if! {
                if #[cfg(any(ossl110, libressl280))] {
                    let purpose = cvt_n(ffi::X509_PURPOSE_get_by_sname(sname.as_ptr() as *const _))?;
                } else {
                    let purpose = cvt_n(ffi::X509_PURPOSE_get_by_sname(sname.as_ptr() as *mut _))?;
                }
            }
            Ok(purpose)
        }
    }
    /// Get an `X509PurposeRef` for a given index value. The index can be obtained from e.g.
    /// `X509PurposeRef::get_by_sname()`.
    #[corresponds(X509_PURPOSE_get0)]
    pub fn from_idx(idx: c_int) -> Result<&'static X509PurposeRef, ErrorStack> {
        unsafe {
            let ptr = cvt_p(ffi::X509_PURPOSE_get0(idx))?;
            Ok(X509PurposeRef::from_ptr(ptr))
        }
    }

    /// Get the purpose value from an X509Purpose structure. This value is one of
    /// - `X509_PURPOSE_SSL_CLIENT`
    /// - `X509_PURPOSE_SSL_SERVER`
    /// - `X509_PURPOSE_NS_SSL_SERVER`
    /// - `X509_PURPOSE_SMIME_SIGN`
    /// - `X509_PURPOSE_SMIME_ENCRYPT`
    /// - `X509_PURPOSE_CRL_SIGN`
    /// - `X509_PURPOSE_ANY`
    /// - `X509_PURPOSE_OCSP_HELPER`
    /// - `X509_PURPOSE_TIMESTAMP_SIGN`
    pub fn purpose(&self) -> X509PurposeId {
        unsafe {
            let x509_purpose: *mut ffi::X509_PURPOSE = self.as_ptr();
            X509PurposeId::from_raw((*x509_purpose).purpose)
        }
    }
}
Loading