diff --git a/boring/src/util.rs b/boring/src/util.rs index 21591d2f..bb6373c1 100644 --- a/boring/src/util.rs +++ b/boring/src/util.rs @@ -1,10 +1,10 @@ +use crate::error::ErrorStack; +use foreign_types::{ForeignType, ForeignTypeRef}; use libc::{c_char, c_int, c_void}; use std::any::Any; use std::panic::{self, AssertUnwindSafe}; use std::slice; -use crate::error::ErrorStack; - /// Wraps a user-supplied callback and a slot for panics thrown inside the callback (while FFI /// frames are on the stack). /// @@ -65,3 +65,30 @@ where } } } + +#[allow(dead_code)] +pub trait ForeignTypeExt: ForeignType { + unsafe fn from_ptr_opt(ptr: *mut Self::CType) -> Option { + if ptr.is_null() { + None + } else { + Some(Self::from_ptr(ptr)) + } + } +} +impl ForeignTypeExt for FT {} + +pub trait ForeignTypeRefExt: ForeignTypeRef { + unsafe fn from_const_ptr<'a>(ptr: *const Self::CType) -> &'a Self { + Self::from_ptr(ptr as *mut Self::CType) + } + + unsafe fn from_const_ptr_opt<'a>(ptr: *const Self::CType) -> Option<&'a Self> { + if ptr.is_null() { + None + } else { + Some(Self::from_const_ptr(ptr as *mut Self::CType)) + } + } +} +impl ForeignTypeRefExt for FT {} diff --git a/boring/src/x509/mod.rs b/boring/src/x509/mod.rs index 1ef04454..eb55c305 100644 --- a/boring/src/x509/mod.rs +++ b/boring/src/x509/mod.rs @@ -36,6 +36,7 @@ use crate::pkey::{HasPrivate, HasPublic, PKey, PKeyRef, Public}; use crate::ssl::SslRef; use crate::stack::{Stack, StackRef, Stackable}; use crate::string::OpensslString; +use crate::util::ForeignTypeRefExt; use crate::x509::verify::X509VerifyParamRef; use crate::{cvt, cvt_n, cvt_p}; @@ -407,8 +408,7 @@ impl X509Ref { pub fn subject_name(&self) -> &X509NameRef { unsafe { let name = ffi::X509_get_subject_name(self.as_ptr()); - assert!(!name.is_null()); - X509NameRef::from_ptr(name) + X509NameRef::from_const_ptr_opt(name).expect("issuer name must not be null") } } @@ -419,19 +419,6 @@ impl X509Ref { unsafe { ffi::X509_subject_name_hash(self.as_ptr()) as u32 } } - /// Returns this certificate's issuer name. - /// - /// This corresponds to [`X509_get_issuer_name`]. - /// - /// [`X509_get_issuer_name`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_get_subject_name.html - pub fn issuer_name(&self) -> &X509NameRef { - unsafe { - let name = ffi::X509_get_issuer_name(self.as_ptr()); - assert!(!name.is_null()); - X509NameRef::from_ptr(name) - } - } - /// Returns this certificate's subject alternative name entries, if they exist. /// /// This corresponds to [`X509_get_ext_d2i`] called with `NID_subject_alt_name`. @@ -453,6 +440,15 @@ impl X509Ref { } } + /// Returns this certificate's issuer name. + #[corresponds(X509_get_issuer_name)] + pub fn issuer_name(&self) -> &X509NameRef { + unsafe { + let name = ffi::X509_get_issuer_name(self.as_ptr()); + X509NameRef::from_const_ptr_opt(name).expect("issuer name must not be null") + } + } + /// Returns this certificate's issuer alternative name entries, if they exist. /// /// This corresponds to [`X509_get_ext_d2i`] called with `NID_issuer_alt_name`. @@ -474,27 +470,19 @@ impl X509Ref { } } - /// Returns this certificate's subject key id. - /// - /// This corresponds to [`X509_get0_subject_key_id`]. - /// - /// [`X509_get0_subject_key_id`]: https://docs.openssl.org/1.1.1/man3/X509_get_extension_flags/ - pub fn subject_key_id(&self) -> &Asn1StringRef { + /// Returns this certificate's subject key id, if it exists. + pub fn subject_key_id(&self) -> Option<&Asn1StringRef> { unsafe { - let name = ffi::X509_get0_subject_key_id(self.as_ptr()); - Asn1StringRef::from_ptr(name as _) + let data = ffi::X509_get0_subject_key_id(self.as_ptr()); + Asn1StringRef::from_const_ptr_opt(data) } } - /// Returns this certificate's authority key id. - /// - /// This corresponds to [`X509_get0_authority_key_id`]. - /// - /// [`X509_get0_authority_key_id`]: https://docs.openssl.org/1.1.1/man3/X509_get_extension_flags/ - pub fn authority_key_id(&self) -> &Asn1StringRef { + /// Returns this certificate's authority key id, if it exists. + pub fn authority_key_id(&self) -> Option<&Asn1StringRef> { unsafe { - let name = ffi::X509_get0_authority_key_id(self.as_ptr()); - Asn1StringRef::from_ptr(name as _) + let data = ffi::X509_get0_authority_key_id(self.as_ptr()); + Asn1StringRef::from_const_ptr_opt(data) } }