Allow the X509 verify error to be read from an SslRef

This commit is contained in:
Steven Fackler 2016-10-18 22:18:09 -07:00
parent cfd5192a7d
commit 5ab037f056
3 changed files with 28 additions and 19 deletions

View File

@ -647,7 +647,8 @@ extern {
pub fn SSL_get_servername(ssl: *const SSL, name_type: c_int) -> *const c_char; pub fn SSL_get_servername(ssl: *const SSL, name_type: c_int) -> *const c_char;
pub fn SSL_get_current_cipher(ssl: *const SSL) -> *const SSL_CIPHER; pub fn SSL_get_current_cipher(ssl: *const SSL) -> *const SSL_CIPHER;
#[cfg(not(ossl101))] #[cfg(not(ossl101))]
pub fn SSL_get0_param(ssl: *mut ::SSL) -> *mut X509_VERIFY_PARAM; pub fn SSL_get0_param(ssl: *mut SSL) -> *mut X509_VERIFY_PARAM;
pub fn SSL_get_verify_result(ssl: *const SSL) -> c_long;
#[cfg(not(osslconf = "OPENSSL_NO_COMP"))] #[cfg(not(osslconf = "OPENSSL_NO_COMP"))]
pub fn SSL_COMP_get_name(comp: *const COMP_METHOD) -> *const c_char; pub fn SSL_COMP_get_name(comp: *const COMP_METHOD) -> *const c_char;

View File

@ -21,7 +21,7 @@ use ffi;
use {init, cvt, cvt_p}; use {init, cvt, cvt_p};
use dh::DH; use dh::DH;
use x509::{X509StoreContext, X509FileType, X509, X509Ref}; use x509::{X509StoreContext, X509FileType, X509, X509Ref, X509VerifyError};
#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))]
use x509::verify::X509VerifyParamRef; use x509::verify::X509VerifyParamRef;
use crypto::pkey::PKey; use crypto::pkey::PKey;
@ -1007,6 +1007,13 @@ impl<'a> SslRef<'a> {
X509VerifyParamRef::from_ptr(ffi::SSL_get0_param(self.as_ptr())) X509VerifyParamRef::from_ptr(ffi::SSL_get0_param(self.as_ptr()))
} }
} }
/// Returns the result of X509 certificate verification.
pub fn verify_result(&self) -> Option<X509VerifyError> {
unsafe {
X509VerifyError::from_raw(ffi::SSL_get_verify_result(self.0))
}
}
} }
pub struct Ssl(SslRef<'static>); pub struct Ssl(SslRef<'static>);

View File

@ -100,14 +100,9 @@ impl X509StoreContext {
X509StoreContext { ctx: ctx } X509StoreContext { ctx: ctx }
} }
pub fn error(&self) -> Option<X509ValidationError> { pub fn error(&self) -> Option<X509VerifyError> {
unsafe { unsafe {
let err = ffi::X509_STORE_CTX_get_error(self.ctx) as c_long; X509VerifyError::from_raw(ffi::X509_STORE_CTX_get_error(self.ctx) as c_long)
if err == ffi::X509_V_OK as c_long {
None
} else {
Some(X509ValidationError::from_raw(err))
}
} }
} }
@ -691,38 +686,44 @@ impl<'a> Iterator for ExtensionsIter<'a> {
} }
} }
pub struct X509ValidationError(c_long); pub struct X509VerifyError(c_long);
impl fmt::Debug for X509ValidationError { impl fmt::Debug for X509VerifyError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_struct("X509ValidationError") fmt.debug_struct("X509VerifyError")
.field("code", &self.0) .field("code", &self.0)
.field("error", &self.error_string()) .field("error", &self.error_string())
.finish() .finish()
} }
} }
impl fmt::Display for X509ValidationError { impl fmt::Display for X509VerifyError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.write_str(self.error_string()) fmt.write_str(self.error_string())
} }
} }
impl Error for X509ValidationError { impl Error for X509VerifyError {
fn description(&self) -> &str { fn description(&self) -> &str {
"an X509 validation error" "an X509 validation error"
} }
} }
impl X509ValidationError { impl X509VerifyError {
/// Creates an `X509ValidationError` from a raw error number. /// Creates an `X509VerifyError` from a raw error number.
///
/// `None` will be returned if `err` is `X509_V_OK`.
/// ///
/// # Safety /// # Safety
/// ///
/// Some methods on `X509ValidationError` are not thread safe if the error /// Some methods on `X509VerifyError` are not thread safe if the error
/// number is invalid. /// number is invalid.
pub unsafe fn from_raw(err: c_long) -> X509ValidationError { pub unsafe fn from_raw(err: c_long) -> Option<X509VerifyError> {
X509ValidationError(err) if err == ffi::X509_V_OK as c_long {
None
} else {
Some(X509VerifyError(err))
}
} }
pub fn as_raw(&self) -> c_long { pub fn as_raw(&self) -> c_long {