Skip to content

Commit

Permalink
Introduce X509Extension::new_from_der and deprecate the bad APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
alex committed Apr 13, 2023
1 parent 47abce4 commit e5ffb7f
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 3 deletions.
47 changes: 45 additions & 2 deletions openssl/src/x509/mod.rs
Expand Up @@ -24,8 +24,8 @@ use std::slice;
use std::str;

use crate::asn1::{
Asn1BitStringRef, Asn1Enumerated, Asn1IntegerRef, Asn1Object, Asn1ObjectRef, Asn1StringRef,
Asn1TimeRef, Asn1Type,
Asn1BitStringRef, Asn1Enumerated, Asn1IntegerRef, Asn1Object, Asn1ObjectRef, Asn1String,
Asn1StringRef, Asn1TimeRef, Asn1Type,
};
use crate::bio::MemBioSlice;
use crate::conf::ConfRef;
Expand Down Expand Up @@ -842,6 +842,10 @@ impl X509Extension {
/// mini-language that can read arbitrary files.
///
/// See the extension module for builder types which will construct certain common extensions.
///
/// This function is deprecated, `X509Extension::new_from_der` or the
/// types in `x509::extension` should be used in its place.
#[deprecated]
pub fn new(
conf: Option<&ConfRef>,
context: Option<&X509v3Context<'_>>,
Expand Down Expand Up @@ -887,6 +891,10 @@ impl X509Extension {
/// mini-language that can read arbitrary files.
///
/// See the extension module for builder types which will construct certain common extensions.
///
/// This function is deprecated, `X509Extension::new_from_der` or the
/// types in `x509::extension` should be used in its place.
#[deprecated]
pub fn new_nid(
conf: Option<&ConfRef>,
context: Option<&X509v3Context<'_>>,
Expand Down Expand Up @@ -921,6 +929,40 @@ impl X509Extension {
}
}

/// Constructs a new X509 extension value from its OID, whether it's
/// critical, and its DER contents.
///
/// The extent structure of the DER value will vary based on the
/// extension type, and can generally be found in the RFC defining the
/// extension.
///
/// For common extension types, there are Rust APIs provided in
/// `openssl::x509::extensions` which are more ergonomic.
pub fn new_from_der(
oid: &Asn1ObjectRef,
critical: bool,
der_contents: &[u8],
) -> Result<X509Extension, ErrorStack> {
unsafe {
ffi::init();
let s = Asn1String::from_ptr(cvt_p(ffi::ASN1_STRING_type_new(
Asn1Type::OCTET_STRING.as_raw(),
))?);
cvt(ffi::ASN1_STRING_set(
s.as_ptr(),
der_contents.as_ptr().cast(),
der_contents.len().try_into().unwrap(),
))?;
cvt_p(ffi::X509_EXTENSION_create_by_OBJ(
ptr::null_mut(),
oid.as_ptr(),
critical as _,
s.as_ptr().cast(),
))
.map(X509Extension)
}
}

pub(crate) unsafe fn new_internal(
nid: Nid,
critical: bool,
Expand All @@ -936,6 +978,7 @@ impl X509Extension {
///
/// This method modifies global state without locking and therefore is not thread safe
#[corresponds(X509V3_EXT_add_alias)]
#[deprecated]
pub unsafe fn add_alias(to: Nid, from: Nid) -> Result<(), ErrorStack> {
ffi::init();
cvt(ffi::X509V3_EXT_add_alias(to.as_raw(), from.as_raw())).map(|_| ())
Expand Down
16 changes: 15 additions & 1 deletion openssl/src/x509/tests.rs
@@ -1,6 +1,6 @@
use std::cmp::Ordering;

use crate::asn1::Asn1Time;
use crate::asn1::{Asn1Object, Asn1Time};
use crate::bn::{BigNum, MsbOption};
use crate::hash::MessageDigest;
use crate::nid::Nid;
Expand Down Expand Up @@ -297,6 +297,20 @@ fn x509_extension_new() {
assert!(X509Extension::new(None, None, "subjectAltName", "dirName:section").is_err());
}

#[test]
fn x509_extension_new_from_der() {
let ext = X509Extension::new_from_der(
&Asn1Object::from_str("2.5.29.19").unwrap(),
true,
b"\x30\x03\x01\x01\xff",
)
.unwrap();
assert_eq!(
ext.to_der().unwrap(),
b"0\x0f\x06\x03U\x1d\x13\x01\x01\xff\x04\x050\x03\x01\x01\xff"
);
}

#[test]
fn x509_extension_to_der() {
let builder = X509::builder().unwrap();
Expand Down

0 comments on commit e5ffb7f

Please sign in to comment.