Introduce ForeignTypeExt and ForeignTypeRefExt
`ForeignTypeExt` and `ForeignTypeRefExt` are inspired by https://github.com/sfackler/rust-openssl/pull/1345, which make dealing with FFI safer and more ergonomic. The new APIs (e.g. from_const_ptr_opt`) also allow for gracefully handling instances where the initial API call results in `NULL`. Instead of crashing the program, `None` will be returned.
This commit is contained in:
parent
1b5ae3251f
commit
2be6e100b6
|
|
@ -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<Self> {
|
||||
if ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(Self::from_ptr(ptr))
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<FT: ForeignType> 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<FT: ForeignTypeRef> ForeignTypeRefExt for FT {}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue