Commit 129b6b9d authored by Steven Fackler's avatar Steven Fackler
Browse files

Overhaul verify error type

Also set the error in the hostname verification callback for 1.0.1
parent be04bc40
Loading
Loading
Loading
Loading
+134 −123
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@

extern crate libc;

use libc::{c_void, c_int, c_char, c_ulong, c_long, c_uint, c_uchar, size_t, FILE};
use libc::{c_char, c_int, c_long, c_uchar, c_uint, c_ulong, c_void, size_t, FILE};
use std::ptr;
use std::mem;

@@ -65,33 +65,21 @@ pub enum BN_BLINDING {}
pub enum DSA_METHOD {}
pub enum EVP_PKEY_ASN1_METHOD {}

pub type bio_info_cb = Option<
    unsafe extern "C" fn(*mut BIO,
                         c_int,
                         *const c_char,
                         c_int,
                         c_long,
                         c_long),
>;
pub type GEN_SESSION_CB = Option<
    unsafe extern "C" fn(*const SSL, *mut c_uchar, *mut c_uint)
                         -> c_int,
>;
pub type tls_session_ticket_ext_cb_fn = Option<
    unsafe extern "C" fn(*mut SSL,
                         *const c_uchar,
                         c_int,
                         *mut c_void)
                         -> c_int,
>;
pub type bio_info_cb =
    Option<unsafe extern "C" fn(*mut BIO, c_int, *const c_char, c_int, c_long, c_long)>;
pub type GEN_SESSION_CB =
    Option<unsafe extern "C" fn(*const SSL, *mut c_uchar, *mut c_uint) -> c_int>;
pub type tls_session_ticket_ext_cb_fn =
    Option<unsafe extern "C" fn(*mut SSL, *const c_uchar, c_int, *mut c_void) -> c_int>;
pub type tls_session_secret_cb_fn = Option<
    unsafe extern "C" fn(*mut SSL,
    unsafe extern "C" fn(
        *mut SSL,
        *mut c_void,
        *mut c_int,
        *mut stack_st_SSL_CIPHER,
        *mut *mut SSL_CIPHER,
                         *mut c_void)
                         -> c_int,
        *mut c_void,
    ) -> c_int,
>;

#[repr(C)]
@@ -167,30 +155,32 @@ pub type BN_ULONG = libc::c_ulonglong;
#[cfg(target_pointer_width = "32")]
pub type BN_ULONG = c_uint;

pub type CRYPTO_EX_new = unsafe extern "C" fn(parent: *mut c_void,
pub type CRYPTO_EX_new = unsafe extern "C" fn(
    parent: *mut c_void,
    ptr: *mut c_void,
    ad: *const CRYPTO_EX_DATA,
    idx: c_int,
    argl: c_long,
                                              argp: *const c_void)
                                              -> c_int;
pub type CRYPTO_EX_dup = unsafe extern "C" fn(to: *mut CRYPTO_EX_DATA,
    argp: *const c_void,
) -> c_int;
pub type CRYPTO_EX_dup = unsafe extern "C" fn(
    to: *mut CRYPTO_EX_DATA,
    from: *mut CRYPTO_EX_DATA,
    from_d: *mut c_void,
    idx: c_int,
    argl: c_long,
                                              argp: *mut c_void)
                                              -> c_int;
pub type CRYPTO_EX_free = unsafe extern "C" fn(parent: *mut c_void,
    argp: *mut c_void,
) -> c_int;
pub type CRYPTO_EX_free = unsafe extern "C" fn(
    parent: *mut c_void,
    ptr: *mut c_void,
    ad: *mut CRYPTO_EX_DATA,
    idx: c_int,
    argl: c_long,
                                               argp: *mut c_void);
pub type PasswordCallback = unsafe extern "C" fn(buf: *mut c_char,
                                                 size: c_int,
                                                 rwflag: c_int,
                                                 user_data: *mut c_void)
    argp: *mut c_void,
);
pub type PasswordCallback =
    unsafe extern "C" fn(buf: *mut c_char, size: c_int, rwflag: c_int, user_data: *mut c_void)
        -> c_int;

pub type SHA_LONG = c_uint;
@@ -1265,9 +1255,9 @@ pub const SSL_OP_SAFARI_ECDHE_ECDSA_BUG: c_ulong = 0x00000040;
#[cfg(not(any(libressl, ossl110f)))]
pub const SSL_OP_ALL: c_ulong = 0x80000BFF;
#[cfg(ossl110f)]
pub const SSL_OP_ALL: c_ulong = SSL_OP_CRYPTOPRO_TLSEXT_BUG | SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS |
    SSL_OP_LEGACY_SERVER_CONNECT | SSL_OP_TLSEXT_PADDING |
    SSL_OP_SAFARI_ECDHE_ECDSA_BUG;
pub const SSL_OP_ALL: c_ulong = SSL_OP_CRYPTOPRO_TLSEXT_BUG | SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
    | SSL_OP_LEGACY_SERVER_CONNECT | SSL_OP_TLSEXT_PADDING
    | SSL_OP_SAFARI_ECDHE_ECDSA_BUG;
pub const SSL_OP_NO_QUERY_MTU: c_ulong = 0x00001000;
pub const SSL_OP_COOKIE_EXCHANGE: c_ulong = 0x00002000;
pub const SSL_OP_NO_TICKET: c_ulong = 0x00004000;
@@ -1291,8 +1281,8 @@ pub const SSL_OP_NO_DTLSv1: c_ulong = 0x04000000;
#[cfg(not(any(ossl101, libressl)))]
pub const SSL_OP_NO_DTLSv1_2: c_ulong = 0x08000000;
#[cfg(not(any(ossl101, libressl)))]
pub const SSL_OP_NO_SSL_MASK: c_ulong = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 |
    SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2;
pub const SSL_OP_NO_SSL_MASK: c_ulong =
    SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2;

pub const TLSEXT_NAMETYPE_host_name: c_int = 0;

@@ -1313,60 +1303,82 @@ pub const V_ASN1_UTCTIME: c_int = 23;
pub const X509_FILETYPE_ASN1: c_int = 2;
pub const X509_FILETYPE_DEFAULT: c_int = 3;
pub const X509_FILETYPE_PEM: c_int = 1;
pub const X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: c_int = 31;
pub const X509_V_ERR_AKID_SKID_MISMATCH: c_int = 30;
pub const X509_V_ERR_APPLICATION_VERIFICATION: c_int = 50;
pub const X509_V_ERR_CERT_CHAIN_TOO_LONG: c_int = 22;
pub const X509_V_ERR_CERT_HAS_EXPIRED: c_int = 10;
pub const X509_V_ERR_CERT_NOT_YET_VALID: c_int = 9;
pub const X509_V_ERR_CERT_REJECTED: c_int = 28;
pub const X509_V_ERR_CERT_REVOKED: c_int = 23;

pub const X509_V_OK: c_int = 0;
pub const X509_V_ERR_UNSPECIFIED: c_int = 1;
pub const X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: c_int = 2;
pub const X509_V_ERR_UNABLE_TO_GET_CRL: c_int = 3;
pub const X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: c_int = 4;
pub const X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: c_int = 5;
pub const X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: c_int = 6;
pub const X509_V_ERR_CERT_SIGNATURE_FAILURE: c_int = 7;
pub const X509_V_ERR_CERT_UNTRUSTED: c_int = 27;
pub const X509_V_ERR_CRL_HAS_EXPIRED: c_int = 12;
pub const X509_V_ERR_CRL_NOT_YET_VALID: c_int = 11;
pub const X509_V_ERR_CRL_PATH_VALIDATION_ERROR: c_int = 54;
pub const X509_V_ERR_CRL_SIGNATURE_FAILURE: c_int = 8;
pub const X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: c_int = 18;
pub const X509_V_ERR_DIFFERENT_CRL_SCOPE: c_int = 44;
pub const X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: c_int = 14;
pub const X509_V_ERR_CERT_NOT_YET_VALID: c_int = 9;
pub const X509_V_ERR_CERT_HAS_EXPIRED: c_int = 10;
pub const X509_V_ERR_CRL_NOT_YET_VALID: c_int = 11;
pub const X509_V_ERR_CRL_HAS_EXPIRED: c_int = 12;
pub const X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: c_int = 13;
pub const X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: c_int = 14;
pub const X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: c_int = 15;
pub const X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: c_int = 16;
pub const X509_V_ERR_EXCLUDED_VIOLATION: c_int = 48;
pub const X509_V_ERR_OUT_OF_MEM: c_int = 17;
pub const X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: c_int = 18;
pub const X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: c_int = 19;
pub const X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: c_int = 20;
pub const X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: c_int = 21;
pub const X509_V_ERR_CERT_CHAIN_TOO_LONG: c_int = 22;
pub const X509_V_ERR_CERT_REVOKED: c_int = 23;
pub const X509_V_ERR_INVALID_CA: c_int = 24;
pub const X509_V_ERR_INVALID_EXTENSION: c_int = 41;
pub const X509_V_ERR_INVALID_NON_CA: c_int = 37;
pub const X509_V_ERR_INVALID_POLICY_EXTENSION: c_int = 42;
pub const X509_V_ERR_PATH_LENGTH_EXCEEDED: c_int = 25;
pub const X509_V_ERR_INVALID_PURPOSE: c_int = 26;
pub const X509_V_ERR_CERT_UNTRUSTED: c_int = 27;
pub const X509_V_ERR_CERT_REJECTED: c_int = 28;
pub const X509_V_ERR_SUBJECT_ISSUER_MISMATCH: c_int = 29;
pub const X509_V_ERR_AKID_SKID_MISMATCH: c_int = 30;
pub const X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: c_int = 31;
pub const X509_V_ERR_KEYUSAGE_NO_CERTSIGN: c_int = 32;
pub const X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: c_int = 33;
pub const X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: c_int = 34;
pub const X509_V_ERR_KEYUSAGE_NO_CRL_SIGN: c_int = 35;
pub const X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION: c_int = 36;
pub const X509_V_ERR_INVALID_NON_CA: c_int = 37;
pub const X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED: c_int = 38;
pub const X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE: c_int = 39;
pub const X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED: c_int = 40;
pub const X509_V_ERR_INVALID_EXTENSION: c_int = 41;
pub const X509_V_ERR_INVALID_POLICY_EXTENSION: c_int = 42;
pub const X509_V_ERR_NO_EXPLICIT_POLICY: c_int = 43;
pub const X509_V_ERR_OUT_OF_MEM: c_int = 17;
pub const X509_V_ERR_PATH_LENGTH_EXCEEDED: c_int = 25;
pub const X509_V_ERR_DIFFERENT_CRL_SCOPE: c_int = 44;
pub const X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE: c_int = 45;
pub const X509_V_ERR_UNNESTED_RESOURCE: c_int = 46;
pub const X509_V_ERR_PERMITTED_VIOLATION: c_int = 47;
pub const X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED: c_int = 40;
pub const X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED: c_int = 38;
pub const X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: c_int = 19;
pub const X509_V_ERR_SUBJECT_ISSUER_MISMATCH: c_int = 29;
pub const X509_V_ERR_EXCLUDED_VIOLATION: c_int = 48;
pub const X509_V_ERR_SUBTREE_MINMAX: c_int = 49;
pub const X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: c_int = 6;
pub const X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: c_int = 4;
pub const X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: c_int = 5;
pub const X509_V_ERR_UNABLE_TO_GET_CRL: c_int = 3;
pub const X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: c_int = 33;
pub const X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: c_int = 2;
pub const X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: c_int = 20;
pub const X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: c_int = 21;
pub const X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION: c_int = 36;
pub const X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: c_int = 34;
pub const X509_V_ERR_UNNESTED_RESOURCE: c_int = 46;
pub const X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: c_int = 52;
pub const X509_V_ERR_APPLICATION_VERIFICATION: c_int = 50;
pub const X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: c_int = 51;
pub const X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE: c_int = 45;
pub const X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: c_int = 52;
pub const X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: c_int = 53;
pub const X509_V_OK: c_int = 0;
pub const X509_V_ERR_CRL_PATH_VALIDATION_ERROR: c_int = 54;

#[cfg(not(any(ossl101, libressl)))]
pub const X509_V_ERR_SUITE_B_INVALID_VERSION: c_int = 56;
#[cfg(not(any(ossl101, libressl)))]
pub const X509_V_ERR_SUITE_B_INVALID_ALGORITHM: c_int = 57;
#[cfg(not(any(ossl101, libressl)))]
pub const X509_V_ERR_SUITE_B_INVALID_CURVE: c_int = 58;
#[cfg(not(any(ossl101, libressl)))]
pub const X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM: c_int = 59;
#[cfg(not(any(ossl101, libressl)))]
pub const X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED: c_int = 60;
#[cfg(not(any(ossl101, libressl)))]
pub const X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256: c_int = 61;

#[cfg(not(any(ossl101, libressl)))]
pub const X509_V_ERR_HOSTNAME_MISMATCH: c_int = 62;
#[cfg(not(any(ossl101, libressl)))]
pub const X509_V_ERR_EMAIL_MISMATCH: c_int = 63;
#[cfg(not(any(ossl101, libressl)))]
pub const X509_V_ERR_IP_ADDRESS_MISMATCH: c_int = 64;

#[cfg(not(any(ossl101, libressl)))]
pub const X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT: c_uint = 0x1;
@@ -2425,34 +2437,31 @@ extern "C" {

    pub fn SSL_CTX_set_next_protos_advertised_cb(
        ssl: *mut SSL_CTX,
        cb: extern "C" fn(ssl: *mut SSL,
        cb: extern "C" fn(
            ssl: *mut SSL,
            out: *mut *const c_uchar,
            outlen: *mut c_uint,
                          arg: *mut c_void)
                          -> c_int,
            arg: *mut c_void,
        ) -> c_int,
        arg: *mut c_void,
    );
    pub fn SSL_CTX_set_next_proto_select_cb(
        ssl: *mut SSL_CTX,
        cb: extern "C" fn(ssl: *mut SSL,
        cb: extern "C" fn(
            ssl: *mut SSL,
            out: *mut *mut c_uchar,
            outlen: *mut c_uchar,
            inbuf: *const c_uchar,
            inlen: c_uint,
                          arg: *mut c_void)
                          -> c_int,
            arg: *mut c_void,
        ) -> c_int,
        arg: *mut c_void,
    );
    #[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
    pub fn SSL_CTX_set_psk_client_callback(
        ssl: *mut SSL_CTX,
        psk_client_cb: Option<
            extern "C" fn(*mut SSL,
                          *const c_char,
                          *mut c_char,
                          c_uint,
                          *mut c_uchar,
                          c_uint)
            extern "C" fn(*mut SSL, *const c_char, *mut c_char, c_uint, *mut c_uchar, c_uint)
                -> c_uint,
        >,
    );
@@ -2488,13 +2497,14 @@ extern "C" {
    #[cfg(not(ossl101))]
    pub fn SSL_CTX_set_alpn_select_cb(
        ssl: *mut SSL_CTX,
        cb: extern "C" fn(ssl: *mut SSL,
        cb: extern "C" fn(
            ssl: *mut SSL,
            out: *mut *const c_uchar,
            outlen: *mut c_uchar,
            inbuf: *const c_uchar,
            inlen: c_uint,
                          arg: *mut c_void)
                          -> c_int,
            arg: *mut c_void,
        ) -> c_int,
        arg: *mut c_void,
    );
    #[cfg(not(ossl101))]
@@ -2556,6 +2566,7 @@ extern "C" {
    pub fn X509_STORE_CTX_free(ctx: *mut X509_STORE_CTX);
    pub fn X509_STORE_CTX_get_current_cert(ctx: *mut X509_STORE_CTX) -> *mut X509;
    pub fn X509_STORE_CTX_get_error(ctx: *mut X509_STORE_CTX) -> c_int;
    pub fn X509_STORE_CTX_set_error(ctx: *mut X509_STORE_CTX, error: c_int);
    pub fn X509_STORE_CTX_get_ex_data(ctx: *mut X509_STORE_CTX, idx: c_int) -> *mut c_void;
    pub fn X509_STORE_CTX_get_error_depth(ctx: *mut X509_STORE_CTX) -> c_int;

+76 −158

File changed.

Preview size limit exceeded, changes collapsed.

+9 −1
Original line number Diff line number Diff line
use libc::{c_int, c_void, c_char, c_uchar, c_ulong, c_long, c_uint, size_t};
use libc::{c_char, c_int, c_long, c_uchar, c_uint, c_ulong, c_void, size_t};
use std::sync::{Once, ONCE_INIT};
use std::ptr;

@@ -55,6 +55,14 @@ pub const CRYPTO_EX_INDEX_SSL_CTX: c_int = 1;

pub const OPENSSL_INIT_LOAD_SSL_STRINGS: u64 = 0x00200000;

pub const X509_V_ERR_DANE_NO_MATCH: c_int = 65;
pub const X509_V_ERR_EE_KEY_TOO_SMALL: c_int = 66;
pub const X509_V_ERR_CA_KEY_TOO_SMALL: c_int = 67;
pub const X509_V_ERR_CA_MD_TOO_WEAK: c_int = 68;
pub const X509_V_ERR_INVALID_CALL: c_int = 69;
pub const X509_V_ERR_STORE_LOOKUP: c_int = 70;
pub const X509_V_ERR_NO_VALID_SCTS: c_int = 71;

pub const X509_CHECK_FLAG_NEVER_CHECK_SUBJECT: c_uint = 0x20;

pub fn init() {
+3 −4
Original line number Diff line number Diff line
@@ -9,8 +9,7 @@ use openssl::error::ErrorStack;
use openssl::hash::MessageDigest;
use openssl::pkey::{PKey, PKeyRef};
use openssl::rsa::Rsa;
use openssl::x509::{X509, X509Ref};
use openssl::x509::{X509NameBuilder, X509Req, X509ReqBuilder};
use openssl::x509::{X509, X509NameBuilder, X509Ref, X509Req, X509ReqBuilder, X509VerifyResult};
use openssl::x509::extension::{AuthorityKeyIdentifier, BasicConstraints, KeyUsage,
                               SubjectAlternativeName, SubjectKeyIdentifier};

@@ -137,8 +136,8 @@ fn real_main() -> Result<(), ErrorStack> {

    // Verify that this cert was issued by this ca
    match ca_cert.issued(&cert) {
        Err(ver_err) => println!("Failed to verify certificate: {}", ver_err),
        Ok(()) => println!("Certificate verified!"),
        X509VerifyResult::OK => println!("Certificate verified!"),
        ver_err => println!("Failed to verify certificate: {}", ver_err),
    };

    Ok(())
+26 −25
Original line number Diff line number Diff line
@@ -7,11 +7,6 @@ use ssl::{HandshakeError, Ssl, SslContext, SslContextBuilder, SslMethod, SslMode
          SslRef, SslStream, SslVerifyMode};
use version;

#[cfg(ossl101)]
lazy_static! {
    static ref HOSTNAME_IDX: ::ex_data::Index<Ssl, String> = Ssl::new_ex_index().unwrap();
}

// ffdhe2048 from https://wiki.mozilla.org/Security/Server_Side_TLS#ffdhe2048
const DHPARAM_PEM: &'static str = "
-----BEGIN DH PARAMETERS-----
@@ -297,16 +292,7 @@ fn setup_verify(ctx: &mut SslContextBuilder) {

#[cfg(ossl101)]
fn setup_verify(ctx: &mut SslContextBuilder) {
    ctx.set_verify_callback(SslVerifyMode::PEER, |p, x509| {
        let hostname = match x509.ssl() {
            Ok(Some(ssl)) => ssl.ex_data(*HOSTNAME_IDX),
            _ => None,
        };
        match hostname {
            Some(hostname) => verify::verify_callback(hostname, p, x509),
            None => p,
        }
    });
    ctx.set_verify_callback(SslVerifyMode::PEER, verify::verify_callback);
}

#[cfg(any(ossl102, ossl110))]
@@ -322,7 +308,7 @@ fn setup_verify_hostname(ssl: &mut Ssl, domain: &str) -> Result<(), ErrorStack>
#[cfg(ossl101)]
fn setup_verify_hostname(ssl: &mut Ssl, domain: &str) -> Result<(), ErrorStack> {
    let domain = domain.to_string();
    ssl.set_ex_data(*HOSTNAME_IDX, domain);
    ssl.set_ex_data(*verify::HOSTNAME_IDX, domain);
    Ok(())
}

@@ -331,23 +317,38 @@ mod verify {
    use std::net::IpAddr;
    use std::str;

    use ex_data::Index;
    use nid::Nid;
    use x509::{GeneralName, X509NameRef, X509Ref, X509StoreContextRef};
    use x509::{GeneralName, X509NameRef, X509Ref, X509StoreContextRef, X509VerifyResult};
    use stack::Stack;
    use ssl::Ssl;

    pub fn verify_callback(
        domain: &str,
        preverify_ok: bool,
        x509_ctx: &X509StoreContextRef,
    ) -> bool {
    lazy_static! {
        pub static ref HOSTNAME_IDX: Index<Ssl, String> = Ssl::new_ex_index().unwrap();
    }

    pub fn verify_callback(preverify_ok: bool, x509_ctx: &mut X509StoreContextRef) -> bool {
        if !preverify_ok || x509_ctx.error_depth() != 0 {
            return preverify_ok;
        }

        match x509_ctx.current_cert() {
            Some(x509) => verify_hostname(domain, &x509),
            None => true,
        let ok = match (
            x509_ctx.current_cert(),
            x509_ctx
                .ssl()
                .ok()
                .and_then(|s| s)
                .and_then(|s| s.ex_data(*HOSTNAME_IDX)),
        ) {
            (Some(x509), Some(domain)) => verify_hostname(domain, &x509),
            _ => true,
        };

        if !ok {
            x509_ctx.set_error(X509VerifyResult::APPLICATION_VERIFICATION);
        }

        ok
    }

    fn verify_hostname(domain: &str, cert: &X509Ref) -> bool {
Loading