From b3eb8d516ca1f112fec37436bab56a061a934244 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Thu, 20 Oct 2016 22:41:42 -0700 Subject: [PATCH] Switch X509Name over to new borrow setup The use of actual references enables us to be correct with respect to mutability without needing two structs for the mutable and immutable cases and more deref impls. --- openssl/src/lib.rs | 1 + openssl/src/opaque.rs | 6 ++++++ openssl/src/x509/mod.rs | 27 +++++++++++++++++++-------- 3 files changed, 26 insertions(+), 8 deletions(-) create mode 100644 openssl/src/opaque.rs diff --git a/openssl/src/lib.rs b/openssl/src/lib.rs index 39c9fffe..10f450dd 100644 --- a/openssl/src/lib.rs +++ b/openssl/src/lib.rs @@ -32,6 +32,7 @@ pub mod nid; pub mod ssl; pub mod version; pub mod x509; +mod opaque; pub fn cvt_p(r: *mut T) -> Result<*mut T, ErrorStack> { if r.is_null() { diff --git a/openssl/src/opaque.rs b/openssl/src/opaque.rs new file mode 100644 index 00000000..9545471c --- /dev/null +++ b/openssl/src/opaque.rs @@ -0,0 +1,6 @@ +use std::cell::UnsafeCell; + +/// This is intended to be used as the inner type for types designed to be pointed to by references +/// converted from raw C pointers. It has an `UnsafeCell` internally to inform the compiler about +/// aliasability and doesn't implement `Copy`, so it can't be dereferenced. +pub struct Opaque(UnsafeCell<()>); diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 7f891231..51c1ab29 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -18,9 +18,10 @@ use bio::{MemBio, MemBioSlice}; use crypto::hash::MessageDigest; use crypto::pkey::PKey; use crypto::rand::rand_bytes; +use error::ErrorStack; use ffi; use nid::Nid; -use error::ErrorStack; +use opaque::Opaque; #[cfg(ossl10x)] use ffi::{ @@ -401,9 +402,11 @@ impl<'a> X509Ref<'a> { self.0 } - pub fn subject_name<'b>(&'b self) -> X509Name<'b> { - let name = unsafe { ffi::X509_get_subject_name(self.0) }; - X509Name(name, PhantomData) + pub fn subject_name(&self) -> &X509NameRef { + unsafe { + let name = ffi::X509_get_subject_name(self.0); + X509NameRef::from_ptr(name) + } } /// Returns this certificate's SAN entries, if they exist. @@ -534,17 +537,25 @@ impl Drop for X509 { } } -pub struct X509Name<'x>(*mut ffi::X509_NAME, PhantomData<&'x ()>); +pub struct X509NameRef(Opaque); + +impl X509NameRef { + pub unsafe fn from_ptr<'a>(ptr: *mut ffi::X509_NAME) -> &'a X509NameRef { + &*(ptr as *mut _) + } + + pub fn as_ptr(&self) -> *mut ffi::X509_NAME { + self as *const _ as *mut _ + } -impl<'x> X509Name<'x> { pub fn text_by_nid(&self, nid: Nid) -> Option { unsafe { - let loc = ffi::X509_NAME_get_index_by_NID(self.0, nid as c_int, -1); + let loc = ffi::X509_NAME_get_index_by_NID(self.as_ptr(), nid as c_int, -1); if loc == -1 { return None; } - let ne = ffi::X509_NAME_get_entry(self.0, loc); + let ne = ffi::X509_NAME_get_entry(self.as_ptr(), loc); if ne.is_null() { return None; }