Support libressl 2.8.0

Closes #988
This commit is contained in:
Steven Fackler 2018-09-12 20:42:43 -07:00
parent a29c789e57
commit 8c6bc774db
14 changed files with 120 additions and 76 deletions

View File

@ -108,9 +108,9 @@ openssl_101: &OPENSSL_101
libressl_250: &LIBRESSL_250 libressl_250: &LIBRESSL_250
LIBRARY: libressl LIBRARY: libressl
VERSION: 2.5.0 VERSION: 2.5.0
libressl_270: &LIBRESSL_272 libressl_270: &LIBRESSL_280
LIBRARY: libressl LIBRARY: libressl
VERSION: 2.7.2 VERSION: 2.8.0
x86_64: &X86_64 x86_64: &X86_64
TARGET: x86_64-unknown-linux-gnu TARGET: x86_64-unknown-linux-gnu
@ -195,10 +195,10 @@ jobs:
<<: *JOB <<: *JOB
environment: environment:
<<: [*LIBRESSL_250, *X86_64, *BASE] <<: [*LIBRESSL_250, *X86_64, *BASE]
x86_64-libressl-2.7.2: x86_64-libressl-2.8.0:
<<: *JOB <<: *JOB
environment: environment:
<<: [*LIBRESSL_272, *X86_64, *BASE] <<: [*LIBRESSL_280, *X86_64, *BASE]
macos: macos:
<<: *MACOS_JOB <<: *MACOS_JOB
environment: environment:
@ -226,6 +226,6 @@ workflows:
- armhf-openssl-1.1.0 - armhf-openssl-1.1.0
- armhf-openssl-1.0.2 - armhf-openssl-1.0.2
- x86_64-libressl-2.5.0 - x86_64-libressl-2.5.0
- x86_64-libressl-2.7.2 - x86_64-libressl-2.8.0
- macos - macos
- macos-vendored - macos-vendored

View File

@ -16,6 +16,9 @@ pub fn get(openssl_version: Option<u64>, libressl_version: Option<u64>) -> Vec<&
if libressl_version >= 0x2_07_03_00_0 { if libressl_version >= 0x2_07_03_00_0 {
cfgs.push("libressl273"); cfgs.push("libressl273");
} }
if libressl_version >= 0x2_08_00_00_0 {
cfgs.push("libressl280");
}
} else { } else {
let openssl_version = openssl_version.unwrap(); let openssl_version = openssl_version.unwrap();

View File

@ -497,6 +497,7 @@ See rust-openssl README for more information:
(6, 2) => ('6', '2'), (6, 2) => ('6', '2'),
(6, _) => ('6', 'x'), (6, _) => ('6', 'x'),
(7, _) => ('7', 'x'), (7, _) => ('7', 'x'),
(8, 0) => ('8', 'x'),
_ => version_error(), _ => version_error(),
}; };

View File

@ -49,7 +49,7 @@ extern "C" {
} }
cfg_if! { cfg_if! {
if #[cfg(ossl110)] { if #[cfg(any(ossl110, libressl280))] {
extern "C" { extern "C" {
pub fn ASN1_STRING_to_UTF8(out: *mut *mut c_uchar, s: *const ASN1_STRING) -> c_int; pub fn ASN1_STRING_to_UTF8(out: *mut *mut c_uchar, s: *const ASN1_STRING) -> c_int;
} }

View File

@ -36,7 +36,7 @@ pub type bio_info_cb =
Option<unsafe extern "C" fn(*mut BIO, c_int, *const c_char, c_int, c_long, c_long)>; Option<unsafe extern "C" fn(*mut BIO, c_int, *const c_char, c_int, c_long, c_long)>;
cfg_if! { cfg_if! {
if #[cfg(ossl110)] { if #[cfg(any(ossl110, libressl280))] {
pub enum BIO_METHOD {} pub enum BIO_METHOD {}
} else { } else {
#[repr(C)] #[repr(C)]
@ -60,24 +60,14 @@ pub unsafe fn BIO_get_mem_data(b: *mut BIO, pp: *mut *mut c_char) -> c_long {
} }
cfg_if! { cfg_if! {
if #[cfg(ossl110)] { if #[cfg(any(ossl110, libressl280))] {
extern "C" { extern "C" {
pub fn BIO_s_file() -> *const BIO_METHOD; pub fn BIO_s_file() -> *const BIO_METHOD;
}
} else {
extern "C" {
pub fn BIO_s_file() -> *mut BIO_METHOD;
}
}
}
cfg_if! {
if #[cfg(ossl110)] {
extern "C" {
pub fn BIO_new(type_: *const BIO_METHOD) -> *mut BIO; pub fn BIO_new(type_: *const BIO_METHOD) -> *mut BIO;
} }
} else { } else {
extern "C" { extern "C" {
pub fn BIO_new(type_: *mut BIO_METHOD) -> *mut BIO; pub fn BIO_s_file() -> *mut BIO_METHOD;
} }
} }
} }
@ -96,7 +86,7 @@ extern "C" {
} }
cfg_if! { cfg_if! {
if #[cfg(ossl110)] { if #[cfg(any(ossl110, libressl280))] {
extern "C" { extern "C" {
pub fn BIO_s_mem() -> *const BIO_METHOD; pub fn BIO_s_mem() -> *const BIO_METHOD;
} }
@ -107,7 +97,7 @@ cfg_if! {
} }
} }
cfg_if! { cfg_if! {
if #[cfg(ossl102)] { if #[cfg(any(ossl102, libressl280))] {
extern "C" { extern "C" {
pub fn BIO_new_mem_buf(buf: *const c_void, len: c_int) -> *mut BIO; pub fn BIO_new_mem_buf(buf: *const c_void, len: c_int) -> *mut BIO;
} }

View File

@ -166,7 +166,7 @@ extern "C" {
} }
cfg_if! { cfg_if! {
if #[cfg(ossl110)] { if #[cfg(any(ossl110, libressl280))] {
pub enum ECDSA_SIG {} pub enum ECDSA_SIG {}
} else { } else {
#[repr(C)] #[repr(C)]

View File

@ -108,19 +108,28 @@ extern "C" {
e: *mut ENGINE, e: *mut ENGINE,
pkey: *mut EVP_PKEY, pkey: *mut EVP_PKEY,
) -> c_int; ) -> c_int;
#[cfg(not(ossl102))] }
pub fn EVP_DigestVerifyFinal( cfg_if! {
ctx: *mut EVP_MD_CTX, if #[cfg(any(ossl102, libressl280))] {
sigret: *mut c_uchar, extern "C" {
siglen: size_t, pub fn EVP_DigestVerifyFinal(
) -> c_int; ctx: *mut EVP_MD_CTX,
#[cfg(ossl102)] sigret: *const c_uchar,
pub fn EVP_DigestVerifyFinal( siglen: size_t,
ctx: *mut EVP_MD_CTX, ) -> c_int;
sigret: *const c_uchar, }
siglen: size_t, } else {
) -> c_int; extern "C" {
pub fn EVP_DigestVerifyFinal(
ctx: *mut EVP_MD_CTX,
sigret: *mut c_uchar,
siglen: size_t,
) -> c_int;
}
}
}
extern "C" {
pub fn EVP_CIPHER_CTX_new() -> *mut EVP_CIPHER_CTX; pub fn EVP_CIPHER_CTX_new() -> *mut EVP_CIPHER_CTX;
pub fn EVP_CIPHER_CTX_free(ctx: *mut EVP_CIPHER_CTX); pub fn EVP_CIPHER_CTX_free(ctx: *mut EVP_CIPHER_CTX);
pub fn EVP_MD_CTX_copy_ex(dst: *mut EVP_MD_CTX, src: *const EVP_MD_CTX) -> c_int; pub fn EVP_MD_CTX_copy_ex(dst: *mut EVP_MD_CTX, src: *const EVP_MD_CTX) -> c_int;
@ -181,7 +190,7 @@ extern "C" {
pub fn EVP_PKEY_id(pkey: *const EVP_PKEY) -> c_int; pub fn EVP_PKEY_id(pkey: *const EVP_PKEY) -> c_int;
} }
cfg_if! { cfg_if! {
if #[cfg(ossl110)] { if #[cfg(any(ossl110, libressl280))] {
extern "C" { extern "C" {
pub fn EVP_PKEY_bits(key: *const EVP_PKEY) -> c_int; pub fn EVP_PKEY_bits(key: *const EVP_PKEY) -> c_int;
} }

View File

@ -13,7 +13,7 @@ pub enum ASN1_OBJECT {}
pub enum bio_st {} // FIXME remove pub enum bio_st {} // FIXME remove
cfg_if! { cfg_if! {
if #[cfg(ossl110)] { if #[cfg(any(ossl110, libressl280))] {
pub enum BIO {} pub enum BIO {}
} else { } else {
#[repr(C)] #[repr(C)]
@ -59,7 +59,7 @@ pub enum BN_CTX {}
pub enum BN_GENCB {} pub enum BN_GENCB {}
cfg_if! { cfg_if! {
if #[cfg(ossl110)] { if #[cfg(any(ossl110, libressl280))] {
pub enum EVP_CIPHER {} pub enum EVP_CIPHER {}
} else { } else {
#[repr(C)] #[repr(C)]
@ -90,7 +90,7 @@ cfg_if! {
pub enum EVP_CIPHER_CTX {} pub enum EVP_CIPHER_CTX {}
pub enum EVP_MD {} pub enum EVP_MD {}
cfg_if! { cfg_if! {
if #[cfg(ossl110)] { if #[cfg(any(ossl110, libressl280))] {
pub enum EVP_MD_CTX {} pub enum EVP_MD_CTX {}
} else { } else {
#[repr(C)] #[repr(C)]
@ -105,7 +105,7 @@ cfg_if! {
} }
} }
cfg_if! { cfg_if! {
if #[cfg(ossl110)] { if #[cfg(any(ossl110, libressl280))] {
pub enum EVP_PKEY {} pub enum EVP_PKEY {}
} else { } else {
#[repr(C)] #[repr(C)]
@ -127,7 +127,7 @@ pub enum EVP_PKEY_ASN1_METHOD {}
pub enum EVP_PKEY_CTX {} pub enum EVP_PKEY_CTX {}
cfg_if! { cfg_if! {
if #[cfg(ossl110)] { if #[cfg(any(ossl110, libressl280))] {
pub enum HMAC_CTX {} pub enum HMAC_CTX {}
} else { } else {
#[repr(C)] #[repr(C)]
@ -143,7 +143,7 @@ cfg_if! {
} }
cfg_if! { cfg_if! {
if #[cfg(ossl110)] { if #[cfg(any(ossl110, libressl280))] {
pub enum DH {} pub enum DH {}
} else { } else {
#[repr(C)] #[repr(C)]
@ -172,7 +172,7 @@ cfg_if! {
pub enum DH_METHOD {} pub enum DH_METHOD {}
cfg_if! { cfg_if! {
if #[cfg(ossl110)] { if #[cfg(any(ossl110, libressl280))] {
pub enum DSA {} pub enum DSA {}
} else { } else {
#[repr(C)] #[repr(C)]
@ -201,7 +201,7 @@ cfg_if! {
pub enum DSA_METHOD {} pub enum DSA_METHOD {}
cfg_if! { cfg_if! {
if #[cfg(ossl110)] { if #[cfg(any(ossl110, libressl280))] {
pub enum RSA {} pub enum RSA {}
} else if #[cfg(libressl)] { } else if #[cfg(libressl)] {
#[repr(C)] #[repr(C)]
@ -267,7 +267,7 @@ pub enum RSA_METHOD {}
pub enum EC_KEY {} pub enum EC_KEY {}
cfg_if! { cfg_if! {
if #[cfg(ossl110)] { if #[cfg(any(ossl110, libressl280))] {
pub enum X509 {} pub enum X509 {}
} else if #[cfg(libressl)] { } else if #[cfg(libressl)] {
#[repr(C)] #[repr(C)]
@ -344,7 +344,7 @@ pub enum X509_STORE {}
pub enum X509_STORE_CTX {} pub enum X509_STORE_CTX {}
cfg_if! { cfg_if! {
if #[cfg(ossl110)] { if #[cfg(any(ossl110, libressl280))] {
pub enum X509_VERIFY_PARAM {} pub enum X509_VERIFY_PARAM {}
} else if #[cfg(libressl251)] { } else if #[cfg(libressl251)] {
#[repr(C)] #[repr(C)]
@ -406,7 +406,7 @@ pub enum OPENSSL_INIT_SETTINGS {}
pub enum ENGINE {} pub enum ENGINE {}
cfg_if! { cfg_if! {
if #[cfg(ossl110)] { if #[cfg(any(ossl110, libressl280))] {
pub enum SSL {} pub enum SSL {}
} else if #[cfg(libressl251)] { } else if #[cfg(libressl251)] {
#[repr(C)] #[repr(C)]
@ -708,7 +708,7 @@ cfg_if! {
} }
} }
cfg_if! { cfg_if! {
if #[cfg(ossl110)] { if #[cfg(any(ossl110, libressl280))] {
pub enum SSL_CTX {} pub enum SSL_CTX {}
} else if #[cfg(libressl251)] { } else if #[cfg(libressl251)] {
#[repr(C)] #[repr(C)]
@ -970,7 +970,7 @@ cfg_if! {
pub enum COMP_METHOD {} pub enum COMP_METHOD {}
cfg_if! { cfg_if! {
if #[cfg(ossl110)] { if #[cfg(any(ossl110, libressl280))] {
pub enum CRYPTO_EX_DATA {} pub enum CRYPTO_EX_DATA {}
} else if #[cfg(libressl)] { } else if #[cfg(libressl)] {
#[repr(C)] #[repr(C)]

View File

@ -18,7 +18,7 @@ extern "C" {
) -> c_int; ) -> c_int;
} }
cfg_if! { cfg_if! {
if #[cfg(ossl110)] { if #[cfg(any(ossl110, libressl280))] {
extern "C" { extern "C" {
pub fn PKCS12_create( pub fn PKCS12_create(
pass: *const c_char, pass: *const c_char,

View File

@ -25,7 +25,7 @@ pub const SSL_FILETYPE_ASN1: c_int = X509_FILETYPE_ASN1;
pub enum SSL_METHOD {} pub enum SSL_METHOD {}
pub enum SSL_CIPHER {} pub enum SSL_CIPHER {}
cfg_if! { cfg_if! {
if #[cfg(ossl110)] { if #[cfg(any(ossl110, libressl280))] {
pub enum SSL_SESSION {} pub enum SSL_SESSION {}
} else if #[cfg(libressl251)] { } else if #[cfg(libressl251)] {
#[repr(C)] #[repr(C)]
@ -292,7 +292,13 @@ cfg_if! {
pub const SSL_OP_ENABLE_MIDDLEBOX_COMPAT: c_ulong = 0x00100000; pub const SSL_OP_ENABLE_MIDDLEBOX_COMPAT: c_ulong = 0x00100000;
pub const SSL_OP_CIPHER_SERVER_PREFERENCE: c_ulong = 0x00400000; pub const SSL_OP_CIPHER_SERVER_PREFERENCE: c_ulong = 0x00400000;
pub const SSL_OP_TLS_ROLLBACK_BUG: c_ulong = 0x00800000; cfg_if! {
if #[cfg(libressl280)] {
pub const SSL_OP_TLS_ROLLBACK_BUG: c_ulong = 0;
} else {
pub const SSL_OP_TLS_ROLLBACK_BUG: c_ulong = 0x00800000;
}
}
cfg_if! { cfg_if! {
@ -466,7 +472,7 @@ extern "C" {
); );
} }
cfg_if! { cfg_if! {
if #[cfg(ossl110)] { if #[cfg(any(ossl110, libressl280))] {
extern "C" { extern "C" {
pub fn SSL_CTX_sess_set_get_cb( pub fn SSL_CTX_sess_set_get_cb(
ctx: *mut ::SSL_CTX, ctx: *mut ::SSL_CTX,
@ -497,7 +503,7 @@ extern "C" {
} }
cfg_if! { cfg_if! {
if #[cfg(ossl110)] { if #[cfg(any(ossl110, libressl280))] {
extern "C" { extern "C" {
pub fn SSL_CTX_set_cookie_verify_cb( pub fn SSL_CTX_set_cookie_verify_cb(
s: *mut SSL_CTX, s: *mut SSL_CTX,
@ -843,7 +849,7 @@ extern "C" {
pub fn SSL_CIPHER_get_bits(cipher: *const SSL_CIPHER, alg_bits: *mut c_int) -> c_int; pub fn SSL_CIPHER_get_bits(cipher: *const SSL_CIPHER, alg_bits: *mut c_int) -> c_int;
} }
cfg_if! { cfg_if! {
if #[cfg(ossl110)] { if #[cfg(any(ossl110, libressl280))] {
extern "C" { extern "C" {
pub fn SSL_CIPHER_get_version(cipher: *const SSL_CIPHER) -> *const c_char; pub fn SSL_CIPHER_get_version(cipher: *const SSL_CIPHER) -> *const c_char;
} }
@ -1036,11 +1042,20 @@ extern "C" {
) -> *mut c_char; ) -> *mut c_char;
pub fn SSL_get_certificate(ssl: *const SSL) -> *mut X509; pub fn SSL_get_certificate(ssl: *const SSL) -> *mut X509;
#[cfg(not(ossl102))] }
pub fn SSL_get_privatekey(ssl: *mut SSL) -> *mut EVP_PKEY; cfg_if! {
#[cfg(ossl102)] if #[cfg(any(ossl102, libressl280))] {
pub fn SSL_get_privatekey(ssl: *const SSL) -> *mut EVP_PKEY; extern "C" {
pub fn SSL_get_privatekey(ssl: *const SSL) -> *mut EVP_PKEY;
}
} else {
extern "C" {
pub fn SSL_get_privatekey(ssl: *mut SSL) -> *mut EVP_PKEY;
}
}
}
extern "C" {
#[cfg(ossl102)] #[cfg(ossl102)]
pub fn SSL_CTX_get0_certificate(ctx: *const SSL_CTX) -> *mut X509; pub fn SSL_CTX_get0_certificate(ctx: *const SSL_CTX) -> *mut X509;
#[cfg(ossl102)] #[cfg(ossl102)]

View File

@ -191,7 +191,7 @@ extern "C" {
pub fn X509_set_issuer_name(x: *mut X509, name: *mut X509_NAME) -> c_int; pub fn X509_set_issuer_name(x: *mut X509, name: *mut X509_NAME) -> c_int;
} }
cfg_if! { cfg_if! {
if #[cfg(ossl110)] { if #[cfg(any(ossl110, libressl280))] {
extern "C" { extern "C" {
pub fn X509_get_issuer_name(x: *const ::X509) -> *mut ::X509_NAME; pub fn X509_get_issuer_name(x: *const ::X509) -> *mut ::X509_NAME;
} }
@ -205,15 +205,24 @@ extern "C" {
pub fn X509_set_subject_name(x: *mut X509, name: *mut X509_NAME) -> c_int; pub fn X509_set_subject_name(x: *mut X509, name: *mut X509_NAME) -> c_int;
} }
cfg_if! { cfg_if! {
if #[cfg(ossl110)] { if #[cfg(any(ossl110, libressl280))] {
extern "C" { extern "C" {
pub fn X509_get_subject_name(x: *const ::X509) -> *mut ::X509_NAME; pub fn X509_get_subject_name(x: *const ::X509) -> *mut ::X509_NAME;
}
} else {
extern "C" {
pub fn X509_get_subject_name(x: *mut ::X509) -> *mut ::X509_NAME;
}
}
}
cfg_if! {
if #[cfg(ossl110)] {
extern "C" {
pub fn X509_set1_notBefore(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int; pub fn X509_set1_notBefore(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
pub fn X509_set1_notAfter(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int; pub fn X509_set1_notAfter(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
} }
} else { } else {
extern "C" { extern "C" {
pub fn X509_get_subject_name(x: *mut ::X509) -> *mut ::X509_NAME;
pub fn X509_set_notBefore(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int; pub fn X509_set_notBefore(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
pub fn X509_set_notAfter(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int; pub fn X509_set_notAfter(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
} }
@ -244,7 +253,7 @@ extern "C" {
} }
cfg_if! { cfg_if! {
if #[cfg(ossl110)] { if #[cfg(any(ossl110, libressl280))] {
extern "C" { extern "C" {
pub fn X509_NAME_entry_count(n: *const X509_NAME) -> c_int; pub fn X509_NAME_entry_count(n: *const X509_NAME) -> c_int;
} }
@ -255,11 +264,19 @@ cfg_if! {
} }
} }
extern "C" { cfg_if! {
pub fn X509_NAME_get_index_by_NID(n: *mut X509_NAME, nid: c_int, last_pos: c_int) -> c_int; if #[cfg(libressl280)] {
extern "C" {
pub fn X509_NAME_get_index_by_NID(n: *const X509_NAME, nid: c_int, last_pos: c_int) -> c_int;
}
} else {
extern "C" {
pub fn X509_NAME_get_index_by_NID(n: *mut X509_NAME, nid: c_int, last_pos: c_int) -> c_int;
}
}
} }
cfg_if! { cfg_if! {
if #[cfg(ossl110)] { if #[cfg(any(ossl110, libressl280))] {
extern "C" { extern "C" {
pub fn X509_NAME_get_entry(n: *const X509_NAME, loc: c_int) -> *mut X509_NAME_ENTRY; pub fn X509_NAME_get_entry(n: *const X509_NAME, loc: c_int) -> *mut X509_NAME_ENTRY;
pub fn X509_NAME_add_entry_by_NID( pub fn X509_NAME_add_entry_by_NID(
@ -305,7 +322,7 @@ extern "C" {
pub fn X509_add_ext(x: *mut X509, ext: *mut X509_EXTENSION, loc: c_int) -> c_int; pub fn X509_add_ext(x: *mut X509, ext: *mut X509_EXTENSION, loc: c_int) -> c_int;
} }
cfg_if! { cfg_if! {
if #[cfg(ossl110)] { if #[cfg(any(ossl110, libressl280))] {
extern "C" { extern "C" {
pub fn X509_get_ext_d2i( pub fn X509_get_ext_d2i(
x: *const ::X509, x: *const ::X509,

View File

@ -41,7 +41,7 @@ pub const X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS: c_uint = 0x10;
pub const X509_CHECK_FLAG_NEVER_CHECK_SUBJECT: c_uint = 0x20; pub const X509_CHECK_FLAG_NEVER_CHECK_SUBJECT: c_uint = 0x20;
cfg_if! { cfg_if! {
if #[cfg(ossl110)] { if #[cfg(any(ossl110, libressl280))] {
extern "C" { extern "C" {
pub fn X509V3_EXT_nconf_nid( pub fn X509V3_EXT_nconf_nid(
conf: *mut CONF, conf: *mut CONF,

View File

@ -49,5 +49,9 @@ fn main() {
if version >= 0x2_07_03_00_0 { if version >= 0x2_07_03_00_0 {
println!("cargo:rustc-cfg=libressl273"); println!("cargo:rustc-cfg=libressl273");
} }
if version >= 0x2_08_00_00_0 {
println!("cargo:rustc-cfg=libressl280");
}
} }
} }

View File

@ -379,10 +379,13 @@ pub unsafe extern "C" fn raw_remove_session<F>(
callback(ctx, session) callback(ctx, session)
} }
#[cfg(ossl110)] cfg_if! {
type DataPtr = *const c_uchar; if #[cfg(any(ossl110, libressl280))] {
#[cfg(not(ossl110))] type DataPtr = *const c_uchar;
type DataPtr = *mut c_uchar; } else {
type DataPtr = *mut c_uchar;
}
}
pub unsafe extern "C" fn raw_get_session<F>( pub unsafe extern "C" fn raw_get_session<F>(
ssl: *mut ffi::SSL, ssl: *mut ffi::SSL,
@ -503,11 +506,13 @@ where
} }
} }
#[cfg(ossl110)] cfg_if! {
type CookiePtr = *const c_uchar; if #[cfg(any(ossl110, libressl280))] {
type CookiePtr = *const c_uchar;
#[cfg(not(ossl110))] } else {
type CookiePtr = *mut c_uchar; type CookiePtr = *mut c_uchar;
}
}
pub extern "C" fn raw_cookie_verify<F>( pub extern "C" fn raw_cookie_verify<F>(
ssl: *mut ffi::SSL, ssl: *mut ffi::SSL,