Commit 56e94e33 authored by Felix Huettner's avatar Felix Huettner
Browse files

add other name support

the issue with other name SANs is that they can contain arbitary data.
As we can no longer use the old method for other_name for security
reasons we now add `other_name2` as an alternative.
parent c7e89d9b
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@ pub struct ASN1_ENCODING {

extern "C" {
    pub fn ASN1_OBJECT_free(x: *mut ASN1_OBJECT);
    pub fn OBJ_dup(x: *const ASN1_OBJECT) -> *mut ASN1_OBJECT;
}

stack!(stack_st_ASN1_OBJECT);
@@ -94,7 +95,14 @@ extern "C" {
    #[cfg(ossl110)]
    pub fn ASN1_ENUMERATED_get_int64(pr: *mut i64, a: *const ASN1_ENUMERATED) -> c_int;

    pub fn ASN1_TYPE_new() -> *mut ASN1_TYPE;
    pub fn ASN1_TYPE_set(a: *mut ASN1_TYPE, type_: c_int, value: *mut c_void);
    pub fn ASN1_TYPE_free(x: *mut ASN1_TYPE);
    pub fn d2i_ASN1_TYPE(
        k: *mut *mut ASN1_TYPE,
        buf: *mut *const u8,
        len: c_long,
    ) -> *mut ASN1_TYPE;
}

const_ptr_api! {
@@ -102,5 +110,6 @@ const_ptr_api! {
        pub fn ASN1_STRING_to_UTF8(out: *mut *mut c_uchar, s: #[const_ptr_if(any(ossl110, libressl280))] ASN1_STRING) -> c_int;
        pub fn ASN1_STRING_type(x: #[const_ptr_if(any(ossl110, libressl280))]  ASN1_STRING) -> c_int;
        pub fn ASN1_generate_v3(str: #[const_ptr_if(any(ossl110, libressl280))] c_char, cnf: *mut X509V3_CTX) -> *mut ASN1_TYPE;
        pub fn i2d_ASN1_TYPE(a: #[const_ptr_if(ossl300)] ASN1_TYPE, pp: *mut *mut c_uchar) -> c_int;
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -6,6 +6,11 @@ pub enum CONF_METHOD {}
extern "C" {
    pub fn GENERAL_NAME_new() -> *mut GENERAL_NAME;
    pub fn GENERAL_NAME_free(name: *mut GENERAL_NAME);
    pub fn GENERAL_NAME_set0_othername(
        gen: *mut GENERAL_NAME,
        oid: *mut ASN1_OBJECT,
        value: *mut ASN1_TYPE,
    ) -> c_int;
}

#[repr(C)]
+1 −0
Original line number Diff line number Diff line
@@ -655,6 +655,7 @@ impl Asn1OctetStringRef {
foreign_type_and_impl_send_sync! {
    type CType = ffi::ASN1_OBJECT;
    fn drop = ffi::ASN1_OBJECT_free;
    fn clone = ffi::OBJ_dup;

    /// Object Identifier
    ///
+18 −5
Original line number Diff line number Diff line
@@ -434,6 +434,7 @@ enum RustGeneralName {
    Uri(String),
    Ip(String),
    Rid(String),
    OtherName(Asn1Object, Vec<u8>),
}

/// An extension that allows additional identities to be bound to the subject
@@ -506,12 +507,21 @@ impl SubjectAlternativeName {

    /// Sets the `otherName` flag.
    ///
    /// Not currently actually supported, always panics.
    #[deprecated = "other_name is deprecated and always panics. Please file a bug if you have a use case for this."]
    /// Not currently actually supported, always panics. Please use other_name2
    #[deprecated = "other_name is deprecated and always panics. Please use other_name2."]
    pub fn other_name(&mut self, _other_name: &str) -> &mut SubjectAlternativeName {
        unimplemented!(
            "This has not yet been adapted for the new internals. File a bug if you need this."
        );
        unimplemented!("This has not yet been adapted for the new internals. Use other_name2.");
    }

    /// Sets the `otherName` flag.
    ///
    /// `content` must be a valid der encoded ASN1_TYPE
    ///
    /// If you want to add just a ia5string use `other_name_ia5string`
    pub fn other_name2(&mut self, oid: Asn1Object, content: &[u8]) -> &mut SubjectAlternativeName {
        self.items
            .push(RustGeneralName::OtherName(oid, content.into()));
        self
    }

    /// Return a `SubjectAlternativeName` extension as an `X509Extension`.
@@ -526,6 +536,9 @@ impl SubjectAlternativeName {
                    GeneralName::new_ip(s.parse().map_err(|_| ErrorStack::get())?)?
                }
                RustGeneralName::Rid(s) => GeneralName::new_rid(Asn1Object::from_str(s)?)?,
                RustGeneralName::OtherName(oid, content) => {
                    GeneralName::new_other_name(oid.clone(), content)?
                }
            };
            stack.push(gn)?;
        }
+31 −0
Original line number Diff line number Diff line
@@ -2054,6 +2054,37 @@ impl GeneralName {
            Ok(GeneralName::from_ptr(gn))
        }
    }

    pub(crate) fn new_other_name(
        oid: Asn1Object,
        value: &Vec<u8>,
    ) -> Result<GeneralName, ErrorStack> {
        unsafe {
            ffi::init();

            let typ = cvt_p(ffi::d2i_ASN1_TYPE(
                ptr::null_mut(),
                &mut value.as_ptr().cast(),
                value.len().try_into().unwrap(),
            ))?;

            let gn = cvt_p(ffi::GENERAL_NAME_new())?;
            (*gn).type_ = ffi::GEN_OTHERNAME;

            if let Err(e) = cvt(ffi::GENERAL_NAME_set0_othername(
                gn,
                oid.as_ptr().cast(),
                typ,
            )) {
                ffi::GENERAL_NAME_free(gn);
                return Err(e);
            }

            mem::forget(oid);

            Ok(GeneralName::from_ptr(gn))
        }
    }
}

impl GeneralNameRef {
Loading