From 78aa9aa22cfd58ac33d1e19184cec667438fd2a1 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 21 Mar 2023 20:44:15 -0400 Subject: [PATCH] Always provide an X509V3Context in X509Extension::new because OpenSSL requires it for some extensions (and segfaults without) --- openssl/src/x509/mod.rs | 40 +++++++++++++++++++++++++++++++++++---- openssl/src/x509/tests.rs | 10 +++++++++- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 3d8f236fd5..60df75ae72 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -816,14 +816,30 @@ impl X509Extension { ) -> Result { let name = CString::new(name).unwrap(); let value = CString::new(value).unwrap(); + let mut ctx; unsafe { ffi::init(); let conf = conf.map_or(ptr::null_mut(), ConfRef::as_ptr); - let context = context.map_or(ptr::null_mut(), X509v3Context::as_ptr); + let context_ptr = match context { + Some(c) => c.as_ptr(), + None => { + ctx = mem::zeroed(); + + ffi::X509V3_set_ctx( + &mut ctx, + ptr::null_mut(), + ptr::null_mut(), + ptr::null_mut(), + ptr::null_mut(), + 0, + ); + &mut ctx + } + }; let name = name.as_ptr() as *mut _; let value = value.as_ptr() as *mut _; - cvt_p(ffi::X509V3_EXT_nconf(conf, context, name, value)).map(X509Extension) + cvt_p(ffi::X509V3_EXT_nconf(conf, context_ptr, name, value)).map(X509Extension) } } @@ -841,14 +857,30 @@ impl X509Extension { value: &str, ) -> Result { let value = CString::new(value).unwrap(); + let mut ctx; unsafe { ffi::init(); let conf = conf.map_or(ptr::null_mut(), ConfRef::as_ptr); - let context = context.map_or(ptr::null_mut(), X509v3Context::as_ptr); + let context_ptr = match context { + Some(c) => c.as_ptr(), + None => { + ctx = mem::zeroed(); + + ffi::X509V3_set_ctx( + &mut ctx, + ptr::null_mut(), + ptr::null_mut(), + ptr::null_mut(), + ptr::null_mut(), + 0, + ); + &mut ctx + } + }; let name = name.as_raw(); let value = value.as_ptr() as *mut _; - cvt_p(ffi::X509V3_EXT_nconf_nid(conf, context, name, value)).map(X509Extension) + cvt_p(ffi::X509V3_EXT_nconf_nid(conf, context_ptr, name, value)).map(X509Extension) } } diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index 91fd36790c..57734f2665 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -25,7 +25,7 @@ use crate::x509::X509PurposeId; #[cfg(any(ossl102, libressl261))] use crate::x509::X509PurposeRef; use crate::x509::{ - CrlStatus, X509Crl, X509Name, X509Req, X509StoreContext, X509VerifyResult, X509, + CrlStatus, X509Crl, X509Extension, X509Name, X509Req, X509StoreContext, X509VerifyResult, X509, }; use hex::{self, FromHex}; #[cfg(any(ossl102, libressl261))] @@ -287,6 +287,14 @@ fn x509_builder() { assert_eq!(serial, x509.serial_number().to_bn().unwrap()); } +#[test] +fn x509_extension_new() { + assert!(X509Extension::new(None, None, "crlDistributionPoints", "section").is_err()); + assert!(X509Extension::new(None, None, "proxyCertInfo", "").is_err()); + assert!(X509Extension::new(None, None, "certificatePolicies", "").is_err()); + assert!(X509Extension::new(None, None, "subjectAltName", "dirName:section").is_err()); +} + #[test] fn x509_extension_to_der() { let builder = X509::builder().unwrap();