Merge pull request #923 from sfackler/libressl-hostname

Hostname verification support on libressl
This commit is contained in:
Steven Fackler 2018-05-20 12:47:00 -07:00 committed by GitHub
commit 440ede3b54
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 1013 additions and 967 deletions

View File

@ -7,37 +7,35 @@ pub fn get(openssl_version: Option<u64>, libressl_version: Option<u64>) -> Vec<&
if libressl_version >= 0x2_05_01_00_0 { if libressl_version >= 0x2_05_01_00_0 {
cfgs.push("libressl251"); cfgs.push("libressl251");
} }
if libressl_version >= 0x2_06_01_00_0 { if libressl_version >= 0x2_06_01_00_0 {
cfgs.push("libressl261"); cfgs.push("libressl261");
} }
if libressl_version >= 0x2_07_00_00_0 { if libressl_version >= 0x2_07_00_00_0 {
cfgs.push("libressl270"); cfgs.push("libressl270");
} }
} else { } else {
let openssl_version = openssl_version.unwrap(); let openssl_version = openssl_version.unwrap();
if openssl_version >= 0x1_00_01_00_0 {
cfgs.push("ossl101");
}
if openssl_version >= 0x1_00_02_00_0 {
cfgs.push("ossl102");
}
if openssl_version >= 0x1_00_02_08_0 { if openssl_version >= 0x1_00_02_08_0 {
cfgs.push("ossl102h"); cfgs.push("ossl102h");
} }
if openssl_version >= 0x1_01_00_00_0 {
cfgs.push("ossl110");
}
if openssl_version >= 0x1_01_00_06_0 {
cfgs.push("ossl110f");
}
if openssl_version >= 0x1_01_00_07_0 { if openssl_version >= 0x1_01_00_07_0 {
cfgs.push("ossl110g"); cfgs.push("ossl110g");
} }
if openssl_version >= 0x1_01_01_00_0 { if openssl_version >= 0x1_01_01_00_0 {
cfgs.push("ossl111"); cfgs.push("ossl111");
cfgs.push("ossl110");
} else if openssl_version >= 0x1_01_00_06_0 {
cfgs.push("ossl110");
cfgs.push("ossl110f");
} else if openssl_version >= 0x1_01_00_00_0 {
cfgs.push("ossl110");
} else if openssl_version >= 0x1_00_02_00_0 {
cfgs.push("ossl102");
} else if openssl_version >= 0x1_00_01_00_0 {
cfgs.push("ossl101");
} }
} }

View File

@ -1261,7 +1261,7 @@ pub const SSL_VERIFY_NONE: c_int = 0;
pub const SSL_VERIFY_PEER: c_int = 1; pub const SSL_VERIFY_PEER: c_int = 1;
pub const SSL_VERIFY_FAIL_IF_NO_PEER_CERT: c_int = 2; pub const SSL_VERIFY_FAIL_IF_NO_PEER_CERT: c_int = 2;
#[cfg(not(any(libressl261, ossl101)))] #[cfg(any(ossl102, all(libressl, not(libressl261))))]
pub const SSL_OP_TLSEXT_PADDING: c_ulong = 0x00000010; pub const SSL_OP_TLSEXT_PADDING: c_ulong = 0x00000010;
#[cfg(libressl261)] #[cfg(libressl261)]
pub const SSL_OP_TLSEXT_PADDING: c_ulong = 0x0; pub const SSL_OP_TLSEXT_PADDING: c_ulong = 0x0;
@ -1271,9 +1271,9 @@ pub const SSL_OP_CRYPTOPRO_TLSEXT_BUG: c_ulong = 0x80000000;
#[cfg(libressl261)] #[cfg(libressl261)]
pub const SSL_OP_CRYPTOPRO_TLSEXT_BUG: c_ulong = 0x0; pub const SSL_OP_CRYPTOPRO_TLSEXT_BUG: c_ulong = 0x0;
pub const SSL_OP_LEGACY_SERVER_CONNECT: c_ulong = 0x00000004; pub const SSL_OP_LEGACY_SERVER_CONNECT: c_ulong = 0x00000004;
#[cfg(not(any(libressl, ossl110f, ossl111)))] #[cfg(not(any(libressl, ossl110f)))]
pub const SSL_OP_ALL: c_ulong = 0x80000BFF; pub const SSL_OP_ALL: c_ulong = 0x80000BFF;
#[cfg(any(ossl110f, ossl111))] #[cfg(ossl110f)]
pub const SSL_OP_ALL: c_ulong = SSL_OP_CRYPTOPRO_TLSEXT_BUG pub const SSL_OP_ALL: c_ulong = SSL_OP_CRYPTOPRO_TLSEXT_BUG
| SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS | SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
| SSL_OP_LEGACY_SERVER_CONNECT | SSL_OP_LEGACY_SERVER_CONNECT
@ -1289,7 +1289,7 @@ pub const SSL_OP_NO_TLSv1: c_ulong = 0x04000000;
pub const SSL_OP_NO_TLSv1_1: c_ulong = 0x10000000; pub const SSL_OP_NO_TLSv1_1: c_ulong = 0x10000000;
pub const SSL_OP_NO_TLSv1_2: c_ulong = 0x08000000; pub const SSL_OP_NO_TLSv1_2: c_ulong = 0x08000000;
#[cfg(not(any(ossl101, libressl, ossl111)))] #[cfg(all(ossl102, not(ossl111)))]
pub const SSL_OP_NO_SSL_MASK: c_ulong = 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; SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2;
#[cfg(ossl111)] #[cfg(ossl111)]
@ -1393,35 +1393,35 @@ 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_ERR_UNSUPPORTED_NAME_SYNTAX: c_int = 53;
pub const X509_V_ERR_CRL_PATH_VALIDATION_ERROR: c_int = 54; pub const X509_V_ERR_CRL_PATH_VALIDATION_ERROR: c_int = 54;
#[cfg(not(any(ossl101, libressl)))] #[cfg(ossl102)]
pub const X509_V_ERR_SUITE_B_INVALID_VERSION: c_int = 56; pub const X509_V_ERR_SUITE_B_INVALID_VERSION: c_int = 56;
#[cfg(not(any(ossl101, libressl)))] #[cfg(ossl102)]
pub const X509_V_ERR_SUITE_B_INVALID_ALGORITHM: c_int = 57; pub const X509_V_ERR_SUITE_B_INVALID_ALGORITHM: c_int = 57;
#[cfg(not(any(ossl101, libressl)))] #[cfg(ossl102)]
pub const X509_V_ERR_SUITE_B_INVALID_CURVE: c_int = 58; pub const X509_V_ERR_SUITE_B_INVALID_CURVE: c_int = 58;
#[cfg(not(any(ossl101, libressl)))] #[cfg(ossl102)]
pub const X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM: c_int = 59; pub const X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM: c_int = 59;
#[cfg(not(any(ossl101, libressl)))] #[cfg(ossl102)]
pub const X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED: c_int = 60; pub const X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED: c_int = 60;
#[cfg(not(any(ossl101, libressl)))] #[cfg(ossl102)]
pub const X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256: c_int = 61; pub const X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256: c_int = 61;
#[cfg(not(any(ossl101, libressl)))] #[cfg(ossl102)]
pub const X509_V_ERR_HOSTNAME_MISMATCH: c_int = 62; pub const X509_V_ERR_HOSTNAME_MISMATCH: c_int = 62;
#[cfg(not(any(ossl101, libressl)))] #[cfg(ossl102)]
pub const X509_V_ERR_EMAIL_MISMATCH: c_int = 63; pub const X509_V_ERR_EMAIL_MISMATCH: c_int = 63;
#[cfg(not(any(ossl101, libressl)))] #[cfg(ossl102)]
pub const X509_V_ERR_IP_ADDRESS_MISMATCH: c_int = 64; pub const X509_V_ERR_IP_ADDRESS_MISMATCH: c_int = 64;
#[cfg(not(any(ossl101, libressl)))] #[cfg(any(ossl102, libressl261))]
pub const X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT: c_uint = 0x1; pub const X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT: c_uint = 0x1;
#[cfg(not(any(ossl101, libressl)))] #[cfg(any(ossl102, libressl261))]
pub const X509_CHECK_FLAG_NO_WILDCARDS: c_uint = 0x2; pub const X509_CHECK_FLAG_NO_WILDCARDS: c_uint = 0x2;
#[cfg(not(any(ossl101, libressl)))] #[cfg(any(ossl102, libressl261))]
pub const X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS: c_uint = 0x4; pub const X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS: c_uint = 0x4;
#[cfg(not(any(ossl101, libressl)))] #[cfg(any(ossl102, libressl261))]
pub const X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS: c_uint = 0x8; pub const X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS: c_uint = 0x8;
#[cfg(not(any(ossl101, libressl)))] #[cfg(any(ossl102, libressl261))]
pub const X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS: c_uint = 0x10; pub const X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS: c_uint = 0x10;
pub const GEN_OTHERNAME: c_int = 0; pub const GEN_OTHERNAME: c_int = 0;
@ -1526,7 +1526,7 @@ pub unsafe fn SSL_CTX_add_extra_chain_cert(ctx: *mut SSL_CTX, x509: *mut X509) -
SSL_CTX_ctrl(ctx, SSL_CTRL_EXTRA_CHAIN_CERT, 0, x509 as *mut c_void) SSL_CTX_ctrl(ctx, SSL_CTRL_EXTRA_CHAIN_CERT, 0, x509 as *mut c_void)
} }
#[cfg(not(any(ossl101, libressl)))] #[cfg(ossl102)]
pub unsafe fn SSL_CTX_set0_verify_cert_store(ctx: *mut SSL_CTX, st: *mut X509_STORE) -> c_long { pub unsafe fn SSL_CTX_set0_verify_cert_store(ctx: *mut SSL_CTX, st: *mut X509_STORE) -> c_long {
SSL_CTX_ctrl(ctx, SSL_CTRL_SET_VERIFY_CERT_STORE, 0, st as *mut c_void) SSL_CTX_ctrl(ctx, SSL_CTRL_SET_VERIFY_CERT_STORE, 0, st as *mut c_void)
} }
@ -1641,9 +1641,9 @@ extern "C" {
pub fn BIO_new_socket(sock: c_int, close_flag: c_int) -> *mut BIO; pub fn BIO_new_socket(sock: c_int, close_flag: c_int) -> *mut BIO;
pub fn BIO_read(b: *mut BIO, buf: *mut c_void, len: c_int) -> c_int; pub fn BIO_read(b: *mut BIO, buf: *mut c_void, len: c_int) -> c_int;
pub fn BIO_write(b: *mut BIO, buf: *const c_void, len: c_int) -> c_int; pub fn BIO_write(b: *mut BIO, buf: *const c_void, len: c_int) -> c_int;
#[cfg(any(ossl101, libressl))] #[cfg(not(ossl102))]
pub fn BIO_new_mem_buf(buf: *mut c_void, len: c_int) -> *mut BIO; pub fn BIO_new_mem_buf(buf: *mut c_void, len: c_int) -> *mut BIO;
#[cfg(not(any(ossl101, libressl)))] #[cfg(ossl102)]
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;
pub fn BIO_set_flags(b: *mut BIO, flags: c_int); pub fn BIO_set_flags(b: *mut BIO, flags: c_int);
pub fn BIO_clear_flags(b: *mut BIO, flags: c_int); pub fn BIO_clear_flags(b: *mut BIO, flags: c_int);
@ -1774,11 +1774,11 @@ extern "C" {
pub fn DH_new() -> *mut DH; pub fn DH_new() -> *mut DH;
pub fn DH_free(dh: *mut DH); pub fn DH_free(dh: *mut DH);
#[cfg(not(any(ossl101, libressl)))] #[cfg(ossl102)]
pub fn DH_get_1024_160() -> *mut DH; pub fn DH_get_1024_160() -> *mut DH;
#[cfg(not(any(ossl101, libressl)))] #[cfg(ossl102)]
pub fn DH_get_2048_224() -> *mut DH; pub fn DH_get_2048_224() -> *mut DH;
#[cfg(not(any(ossl101, libressl)))] #[cfg(ossl102)]
pub fn DH_get_2048_256() -> *mut DH; pub fn DH_get_2048_256() -> *mut DH;
pub fn EC_KEY_new() -> *mut EC_KEY; pub fn EC_KEY_new() -> *mut EC_KEY;
@ -2036,13 +2036,13 @@ extern "C" {
e: *mut ENGINE, e: *mut ENGINE,
pkey: *mut EVP_PKEY, pkey: *mut EVP_PKEY,
) -> c_int; ) -> c_int;
#[cfg(any(ossl101, libressl))] #[cfg(not(ossl102))]
pub fn EVP_DigestVerifyFinal( pub fn EVP_DigestVerifyFinal(
ctx: *mut EVP_MD_CTX, ctx: *mut EVP_MD_CTX,
sigret: *mut c_uchar, sigret: *mut c_uchar,
siglen: size_t, siglen: size_t,
) -> c_int; ) -> c_int;
#[cfg(not(any(ossl101, libressl)))] #[cfg(ossl102)]
pub fn EVP_DigestVerifyFinal( pub fn EVP_DigestVerifyFinal(
ctx: *mut EVP_MD_CTX, ctx: *mut EVP_MD_CTX,
sigret: *const c_uchar, sigret: *const c_uchar,
@ -2446,14 +2446,14 @@ extern "C" {
pub fn SSL_get_ex_data(ssl: *const SSL, idx: c_int) -> *mut c_void; pub fn SSL_get_ex_data(ssl: *const SSL, idx: c_int) -> *mut c_void;
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(any(ossl101, libressl)))] #[cfg(any(ossl102, libressl261))]
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; pub fn SSL_get_verify_result(ssl: *const SSL) -> c_long;
pub fn SSL_shutdown(ssl: *mut SSL) -> c_int; pub fn SSL_shutdown(ssl: *mut SSL) -> c_int;
pub fn SSL_get_certificate(ssl: *const SSL) -> *mut X509; pub fn SSL_get_certificate(ssl: *const SSL) -> *mut X509;
#[cfg(any(ossl101, libressl))] #[cfg(not(ossl102))]
pub fn SSL_get_privatekey(ssl: *mut SSL) -> *mut EVP_PKEY; pub fn SSL_get_privatekey(ssl: *mut SSL) -> *mut EVP_PKEY;
#[cfg(not(any(ossl101, libressl)))] #[cfg(ossl102)]
pub fn SSL_get_privatekey(ssl: *const SSL) -> *mut EVP_PKEY; pub fn SSL_get_privatekey(ssl: *const SSL) -> *mut EVP_PKEY;
pub fn SSL_load_client_CA_file(file: *const c_char) -> *mut stack_st_X509_NAME; pub fn SSL_load_client_CA_file(file: *const c_char) -> *mut stack_st_X509_NAME;
pub fn SSL_set_tmp_dh_callback( pub fn SSL_set_tmp_dh_callback(
@ -2546,9 +2546,9 @@ extern "C" {
remove_session_cb: Option<unsafe extern "C" fn(*mut SSL_CTX, *mut SSL_SESSION)>, remove_session_cb: Option<unsafe extern "C" fn(*mut SSL_CTX, *mut SSL_SESSION)>,
); );
#[cfg(not(any(ossl101, libressl)))] #[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(not(any(ossl101, libressl)))] #[cfg(ossl102)]
pub fn SSL_CTX_get0_privatekey(ctx: *const SSL_CTX) -> *mut EVP_PKEY; pub fn SSL_CTX_get0_privatekey(ctx: *const SSL_CTX) -> *mut EVP_PKEY;
pub fn SSL_CTX_set_cipher_list(ssl: *mut SSL_CTX, s: *const c_char) -> c_int; pub fn SSL_CTX_set_cipher_list(ssl: *mut SSL_CTX, s: *const c_char) -> c_int;
@ -2599,9 +2599,9 @@ extern "C" {
); );
pub fn SSL_get_session(s: *const SSL) -> *mut SSL_SESSION; pub fn SSL_get_session(s: *const SSL) -> *mut SSL_SESSION;
pub fn SSL_set_session(ssl: *mut SSL, session: *mut SSL_SESSION) -> c_int; pub fn SSL_set_session(ssl: *mut SSL, session: *mut SSL_SESSION) -> c_int;
#[cfg(not(any(ossl101, libressl, ossl110f, ossl111)))] #[cfg(all(ossl102, not(ossl110f)))]
pub fn SSL_is_server(s: *mut SSL) -> c_int; pub fn SSL_is_server(s: *mut SSL) -> c_int;
#[cfg(any(ossl110f, ossl111))] #[cfg(ossl110f)]
pub fn SSL_is_server(s: *const SSL) -> c_int; pub fn SSL_is_server(s: *const SSL) -> c_int;
pub fn SSL_SESSION_free(s: *mut SSL_SESSION); pub fn SSL_SESSION_free(s: *mut SSL_SESSION);
@ -2614,14 +2614,14 @@ extern "C" {
) -> *mut SSL_SESSION; ) -> *mut SSL_SESSION;
pub fn i2d_SSL_SESSION(s: *mut SSL_SESSION, pp: *mut *mut c_uchar) -> c_int; pub fn i2d_SSL_SESSION(s: *mut SSL_SESSION, pp: *mut *mut c_uchar) -> c_int;
#[cfg(not(ossl101))] #[cfg(ossl102)]
pub fn SSL_CTX_set_alpn_protos(s: *mut SSL_CTX, data: *const c_uchar, len: c_uint) -> c_int; pub fn SSL_CTX_set_alpn_protos(s: *mut SSL_CTX, data: *const c_uchar, len: c_uint) -> c_int;
#[cfg(not(ossl101))] #[cfg(ossl102)]
pub fn SSL_set_alpn_protos(s: *mut SSL, data: *const c_uchar, len: c_uint) -> c_int; pub fn SSL_set_alpn_protos(s: *mut SSL, data: *const c_uchar, len: c_uint) -> c_int;
// FIXME should take an Option<unsafe extern "C" fn> // FIXME should take an Option<unsafe extern "C" fn>
#[cfg(not(ossl101))] #[cfg(ossl102)]
pub fn SSL_CTX_set_alpn_select_cb( pub fn SSL_CTX_set_alpn_select_cb(
ssl: *mut SSL_CTX, ssl: *mut SSL_CTX,
cb: extern "C" fn( cb: extern "C" fn(
@ -2634,7 +2634,7 @@ extern "C" {
) -> c_int, ) -> c_int,
arg: *mut c_void, arg: *mut c_void,
); );
#[cfg(not(ossl101))] #[cfg(ossl102)]
pub fn SSL_get0_alpn_selected(s: *const SSL, data: *mut *const c_uchar, len: *mut c_uint); pub fn SSL_get0_alpn_selected(s: *const SSL, data: *mut *const c_uchar, len: *mut c_uint);
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;
@ -2726,17 +2726,17 @@ extern "C" {
pub fn X509_REQ_get_extensions(req: *mut X509_REQ) -> *mut stack_st_X509_EXTENSION; pub fn X509_REQ_get_extensions(req: *mut X509_REQ) -> *mut stack_st_X509_EXTENSION;
pub fn X509_REQ_sign(x: *mut X509_REQ, pkey: *mut EVP_PKEY, md: *const EVP_MD) -> c_int; pub fn X509_REQ_sign(x: *mut X509_REQ, pkey: *mut EVP_PKEY, md: *const EVP_MD) -> c_int;
#[cfg(not(ossl101))] #[cfg(any(ossl102, libressl261))]
pub fn X509_VERIFY_PARAM_free(param: *mut X509_VERIFY_PARAM); pub fn X509_VERIFY_PARAM_free(param: *mut X509_VERIFY_PARAM);
#[cfg(not(any(ossl101, libressl)))] #[cfg(any(ossl102, libressl261))]
pub fn X509_VERIFY_PARAM_set_hostflags(param: *mut X509_VERIFY_PARAM, flags: c_uint); pub fn X509_VERIFY_PARAM_set_hostflags(param: *mut X509_VERIFY_PARAM, flags: c_uint);
#[cfg(not(any(ossl101, libressl)))] #[cfg(any(ossl102, libressl261))]
pub fn X509_VERIFY_PARAM_set1_host( pub fn X509_VERIFY_PARAM_set1_host(
param: *mut X509_VERIFY_PARAM, param: *mut X509_VERIFY_PARAM,
name: *const c_char, name: *const c_char,
namelen: size_t, namelen: size_t,
) -> c_int; ) -> c_int;
#[cfg(not(any(ossl101, libressl)))] #[cfg(any(ossl102, libressl261))]
pub fn X509_VERIFY_PARAM_set1_ip( pub fn X509_VERIFY_PARAM_set1_ip(
param: *mut X509_VERIFY_PARAM, param: *mut X509_VERIFY_PARAM,
ip: *const c_uchar, ip: *const c_uchar,

View File

@ -447,6 +447,28 @@ pub unsafe fn SSL_session_reused(ssl: *mut ::SSL) -> c_int {
::SSL_ctrl(ssl, SSL_CTRL_GET_SESSION_REUSED, 0, ptr::null_mut()) as c_int ::SSL_ctrl(ssl, SSL_CTRL_GET_SESSION_REUSED, 0, ptr::null_mut()) as c_int
} }
pub unsafe fn SSL_CTX_get_options(ctx: *const ::SSL_CTX) -> c_ulong {
::SSL_CTX_ctrl(ctx as *mut _, ::SSL_CTRL_OPTIONS, 0, ptr::null_mut()) as c_ulong
}
pub unsafe fn SSL_CTX_set_options(ctx: *const ::SSL_CTX, op: c_ulong) -> c_ulong {
::SSL_CTX_ctrl(
ctx as *mut _,
::SSL_CTRL_OPTIONS,
op as c_long,
ptr::null_mut(),
) as c_ulong
}
pub unsafe fn SSL_CTX_clear_options(ctx: *const ::SSL_CTX, op: c_ulong) -> c_ulong {
::SSL_CTX_ctrl(
ctx as *mut _,
::SSL_CTRL_CLEAR_OPTIONS,
op as c_long,
ptr::null_mut(),
) as c_ulong
}
extern "C" { extern "C" {
pub fn BIO_new(type_: *mut BIO_METHOD) -> *mut BIO; pub fn BIO_new(type_: *mut BIO_METHOD) -> *mut BIO;
pub fn BIO_s_file() -> *mut BIO_METHOD; pub fn BIO_s_file() -> *mut BIO_METHOD;

View File

@ -1,8 +1,8 @@
use libc::{c_int, c_long, c_uchar, c_uint, c_ulong}; use libc::{c_int, c_long, c_uchar, c_uint, c_ulong};
#[cfg(any(ossl101, ossl102))] #[cfg(not(ossl110))]
mod v10x; mod v10x;
#[cfg(any(ossl101, ossl102))] #[cfg(not(ossl110))]
pub use openssl::v10x::*; pub use openssl::v10x::*;
#[cfg(ossl110)] #[cfg(ossl110)]
@ -15,7 +15,7 @@ mod v111;
#[cfg(ossl111)] #[cfg(ossl111)]
pub use openssl::v111::*; pub use openssl::v111::*;
#[cfg(not(ossl101))] #[cfg(ossl102)]
pub const SSL_CTRL_SET_VERIFY_CERT_STORE: c_int = 106; pub const SSL_CTRL_SET_VERIFY_CERT_STORE: c_int = 106;
pub const SSL_MODE_SEND_CLIENTHELLO_TIME: c_long = 0x20; pub const SSL_MODE_SEND_CLIENTHELLO_TIME: c_long = 0x20;
@ -28,9 +28,9 @@ pub const SSL_OP_CISCO_ANYCONNECT: c_ulong = 0x00008000;
pub const SSL_OP_NO_COMPRESSION: c_ulong = 0x00020000; pub const SSL_OP_NO_COMPRESSION: c_ulong = 0x00020000;
pub const SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION: c_ulong = 0x00040000; pub const SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION: c_ulong = 0x00040000;
pub const SSL_OP_NO_SSLv3: c_ulong = 0x02000000; pub const SSL_OP_NO_SSLv3: c_ulong = 0x02000000;
#[cfg(not(ossl101))] #[cfg(ossl102)]
pub const SSL_OP_NO_DTLSv1: c_ulong = 0x04000000; pub const SSL_OP_NO_DTLSv1: c_ulong = 0x04000000;
#[cfg(not(ossl101))] #[cfg(ossl102)]
pub const SSL_OP_NO_DTLSv1_2: c_ulong = 0x08000000; pub const SSL_OP_NO_DTLSv1_2: c_ulong = 0x08000000;
pub const X509_V_ERR_UNSPECIFIED: c_int = 1; pub const X509_V_ERR_UNSPECIFIED: c_int = 1;
@ -55,7 +55,7 @@ pub const CMS_PARTIAL: c_uint = 0x4000;
pub const CMS_REUSE_DIGEST: c_uint = 0x8000; pub const CMS_REUSE_DIGEST: c_uint = 0x8000;
pub const CMS_USE_KEYID: c_uint = 0x10000; pub const CMS_USE_KEYID: c_uint = 0x10000;
pub const CMS_DEBUG_DECRYPT: c_uint = 0x20000; pub const CMS_DEBUG_DECRYPT: c_uint = 0x20000;
#[cfg(not(ossl101))] #[cfg(ossl102)]
pub const CMS_KEY_PARAM: c_uint = 0x40000; pub const CMS_KEY_PARAM: c_uint = 0x40000;
extern "C" { extern "C" {

View File

@ -5,7 +5,7 @@ use std::ptr;
use std::sync::{Mutex, MutexGuard}; use std::sync::{Mutex, MutexGuard};
use std::sync::{Once, ONCE_INIT}; use std::sync::{Once, ONCE_INIT};
#[cfg(not(ossl101))] #[cfg(ossl102)]
use libc::time_t; use libc::time_t;
use libc::{c_char, c_int, c_long, c_uchar, c_uint, c_ulong, c_void, size_t}; use libc::{c_char, c_int, c_long, c_uchar, c_uint, c_ulong, c_void, size_t};
@ -573,9 +573,6 @@ pub struct SSL_CTX {
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl101))] #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl101))]
srtp_profiles: *mut c_void, srtp_profiles: *mut c_void,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
srtp_profiles: *mut c_void,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))] #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
alpn_select_cb: *mut c_void, alpn_select_cb: *mut c_void,
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))] #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
@ -669,7 +666,7 @@ pub struct SRP_CTX {
} }
#[repr(C)] #[repr(C)]
#[cfg(not(ossl101))] #[cfg(ossl102)]
pub struct X509_VERIFY_PARAM { pub struct X509_VERIFY_PARAM {
pub name: *mut c_char, pub name: *mut c_char,
pub check_time: time_t, pub check_time: time_t,
@ -682,7 +679,7 @@ pub struct X509_VERIFY_PARAM {
pub id: *mut X509_VERIFY_PARAM_ID, pub id: *mut X509_VERIFY_PARAM_ID,
} }
#[cfg(not(ossl101))] #[cfg(ossl102)]
pub enum X509_VERIFY_PARAM_ID {} pub enum X509_VERIFY_PARAM_ID {}
pub enum PKCS12 {} pub enum PKCS12 {}
@ -810,6 +807,28 @@ pub unsafe fn SSL_session_reused(ssl: *mut ::SSL) -> c_int {
::SSL_ctrl(ssl, SSL_CTRL_GET_SESSION_REUSED, 0, ptr::null_mut()) as c_int ::SSL_ctrl(ssl, SSL_CTRL_GET_SESSION_REUSED, 0, ptr::null_mut()) as c_int
} }
pub unsafe fn SSL_CTX_get_options(ctx: *const ::SSL_CTX) -> c_ulong {
::SSL_CTX_ctrl(ctx as *mut _, ::SSL_CTRL_OPTIONS, 0, ptr::null_mut()) as c_ulong
}
pub unsafe fn SSL_CTX_set_options(ctx: *const ::SSL_CTX, op: c_ulong) -> c_ulong {
::SSL_CTX_ctrl(
ctx as *mut _,
::SSL_CTRL_OPTIONS,
op as c_long,
ptr::null_mut(),
) as c_ulong
}
pub unsafe fn SSL_CTX_clear_options(ctx: *const ::SSL_CTX, op: c_ulong) -> c_ulong {
::SSL_CTX_ctrl(
ctx as *mut _,
::SSL_CTRL_CLEAR_OPTIONS,
op as c_long,
ptr::null_mut(),
) as c_ulong
}
extern "C" { extern "C" {
pub fn BIO_new(type_: *mut BIO_METHOD) -> *mut BIO; pub fn BIO_new(type_: *mut BIO_METHOD) -> *mut BIO;
pub fn BIO_s_file() -> *mut BIO_METHOD; pub fn BIO_s_file() -> *mut BIO_METHOD;
@ -925,15 +944,15 @@ extern "C" {
loc: c_int, loc: c_int,
set: c_int, set: c_int,
) -> c_int; ) -> c_int;
#[cfg(not(ossl101))] #[cfg(ossl102)]
pub fn X509_get0_signature( pub fn X509_get0_signature(
psig: *mut *mut ::ASN1_BIT_STRING, psig: *mut *mut ::ASN1_BIT_STRING,
palg: *mut *mut ::X509_ALGOR, palg: *mut *mut ::X509_ALGOR,
x: *const ::X509, x: *const ::X509,
); );
#[cfg(not(ossl101))] #[cfg(ossl102)]
pub fn X509_get_signature_nid(x: *const X509) -> c_int; pub fn X509_get_signature_nid(x: *const X509) -> c_int;
#[cfg(not(ossl101))] #[cfg(ossl102)]
pub fn X509_ALGOR_get0( pub fn X509_ALGOR_get0(
paobj: *mut *mut ::ASN1_OBJECT, paobj: *mut *mut ::ASN1_OBJECT,
pptype: *mut c_int, pptype: *mut c_int,

View File

@ -18,9 +18,11 @@ v111 = []
[dependencies] [dependencies]
bitflags = "1.0" bitflags = "1.0"
cfg-if = "0.1"
foreign-types = "0.3.1" foreign-types = "0.3.1"
lazy_static = "1" lazy_static = "1"
libc = "0.2" libc = "0.2"
openssl-sys = { version = "0.9.30", path = "../openssl-sys" } openssl-sys = { version = "0.9.30", path = "../openssl-sys" }
[dev-dependencies] [dev-dependencies]

View File

@ -1,25 +1,6 @@
use std::env; use std::env;
fn main() { fn main() {
match env::var("DEP_OPENSSL_VERSION") {
Ok(ref v) if v == "101" => {
println!("cargo:rustc-cfg=ossl101");
println!("cargo:rustc-cfg=ossl10x");
}
Ok(ref v) if v == "102" => {
println!("cargo:rustc-cfg=ossl102");
println!("cargo:rustc-cfg=ossl10x");
}
Ok(ref v) if v == "110" => {
println!("cargo:rustc-cfg=ossl110");
}
Ok(ref v) if v == "111" => {
println!("cargo:rustc-cfg=ossl110");
println!("cargo:rustc-cfg=ossl111");
}
_ => panic!("Unable to detect OpenSSL version"),
}
if let Ok(_) = env::var("DEP_OPENSSL_LIBRESSL") { if let Ok(_) = env::var("DEP_OPENSSL_LIBRESSL") {
println!("cargo:rustc-cfg=libressl"); println!("cargo:rustc-cfg=libressl");
} }
@ -37,9 +18,21 @@ fn main() {
if let Ok(version) = env::var("DEP_OPENSSL_VERSION_NUMBER") { if let Ok(version) = env::var("DEP_OPENSSL_VERSION_NUMBER") {
let version = u64::from_str_radix(&version, 16).unwrap(); let version = u64::from_str_radix(&version, 16).unwrap();
if version >= 0x1_00_01_00_0 {
println!("cargo:rustc-cfg=ossl101");
}
if version >= 0x1_00_02_00_0 {
println!("cargo:rustc-cfg=ossl102");
}
if version >= 0x1_01_00_00_0 {
println!("cargo:rustc-cfg=ossl110");
}
if version >= 0x1_01_00_07_0 { if version >= 0x1_01_00_07_0 {
println!("cargo:rustc-cfg=ossl110g"); println!("cargo:rustc-cfg=ossl110g");
} }
if version >= 0x1_01_01_00_0 {
println!("cargo:rustc-cfg=ossl111");
}
} }
if let Ok(version) = env::var("DEP_OPENSSL_LIBRESSL_VERSION_NUMBER") { if let Ok(version) = env::var("DEP_OPENSSL_LIBRESSL_VERSION_NUMBER") {

View File

@ -32,12 +32,12 @@ use std::ptr;
use std::slice; use std::slice;
use std::str; use std::str;
use {cvt, cvt_p};
use bio::MemBio; use bio::MemBio;
use bn::BigNum; use bn::BigNum;
use error::ErrorStack; use error::ErrorStack;
use nid::Nid; use nid::Nid;
use string::OpensslString; use string::OpensslString;
use {cvt, cvt_p};
foreign_type_and_impl_send_sync! { foreign_type_and_impl_send_sync! {
type CType = ffi::ASN1_GENERALIZEDTIME; type CType = ffi::ASN1_GENERALIZEDTIME;
@ -162,7 +162,7 @@ impl Asn1StringRef {
/// ///
/// [`as_utf8`]: struct.Asn1String.html#method.as_utf8 /// [`as_utf8`]: struct.Asn1String.html#method.as_utf8
pub fn as_slice(&self) -> &[u8] { pub fn as_slice(&self) -> &[u8] {
unsafe { slice::from_raw_parts(ASN1_STRING_data(self.as_ptr()), self.len()) } unsafe { slice::from_raw_parts(ASN1_STRING_get0_data(self.as_ptr()), self.len()) }
} }
/// Return the length of the Asn1String (number of bytes) /// Return the length of the Asn1String (number of bytes)
@ -241,11 +241,11 @@ foreign_type_and_impl_send_sync! {
impl Asn1BitStringRef { impl Asn1BitStringRef {
/// Returns the Asn1BitString as a slice /// Returns the Asn1BitString as a slice
pub fn as_slice(&self) -> &[u8] { pub fn as_slice(&self) -> &[u8] {
unsafe { slice::from_raw_parts(ASN1_STRING_data(self.as_ptr() as *mut _), self.len()) } unsafe { slice::from_raw_parts(ASN1_STRING_get0_data(self.as_ptr() as *mut _), self.len()) }
} }
/// Length of Asn1BitString in number of bytes. /// Length of Asn1BitString in number of bytes.
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
unsafe { ffi::ASN1_STRING_length(self.as_ptr() as *mut _) as usize } unsafe { ffi::ASN1_STRING_length(self.as_ptr() as *const _) as usize }
} }
} }
@ -296,11 +296,13 @@ impl fmt::Display for Asn1ObjectRef {
} }
} }
#[cfg(any(ossl101, ossl102))] cfg_if! {
use ffi::ASN1_STRING_data; if #[cfg(ossl110)] {
use ffi::ASN1_STRING_get0_data;
#[cfg(ossl110)] } else {
#[allow(bad_style)] #[allow(bad_style)]
unsafe fn ASN1_STRING_data(s: *mut ffi::ASN1_STRING) -> *mut ::libc::c_uchar { unsafe fn ASN1_STRING_get0_data(s: *mut ffi::ASN1_STRING) -> *const ::libc::c_uchar {
ffi::ASN1_STRING_get0_data(s) as *mut _ ffi::ASN1_STRING_data(s)
}
}
} }

View File

@ -1,8 +1,8 @@
use ffi;
use libc::c_int;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::ptr; use std::ptr;
use std::slice; use std::slice;
use libc::c_int;
use ffi;
use cvt_p; use cvt_p;
use error::ErrorStack; use error::ErrorStack;
@ -68,11 +68,13 @@ impl MemBio {
} }
} }
#[cfg(not(ossl101))] cfg_if! {
use ffi::BIO_new_mem_buf; if #[cfg(ossl102)] {
use ffi::BIO_new_mem_buf;
#[cfg(ossl101)] } else {
#[allow(bad_style)] #[allow(bad_style)]
unsafe fn BIO_new_mem_buf(buf: *const ::libc::c_void, len: ::libc::c_int) -> *mut ffi::BIO { unsafe fn BIO_new_mem_buf(buf: *const ::libc::c_void, len: ::libc::c_int) -> *mut ffi::BIO {
ffi::BIO_new_mem_buf(buf as *mut _, len) ffi::BIO_new_mem_buf(buf as *mut _, len)
}
}
} }

View File

@ -30,28 +30,39 @@ use foreign_types::{ForeignType, ForeignTypeRef};
use libc::c_int; use libc::c_int;
use std::cmp::Ordering; use std::cmp::Ordering;
use std::ffi::CString; use std::ffi::CString;
use std::{fmt, ptr};
use std::ops::{Add, Deref, Div, Mul, Neg, Rem, Shl, Shr, Sub}; use std::ops::{Add, Deref, Div, Mul, Neg, Rem, Shl, Shr, Sub};
use std::{fmt, ptr};
use {cvt, cvt_n, cvt_p};
use asn1::Asn1Integer; use asn1::Asn1Integer;
use error::ErrorStack; use error::ErrorStack;
use string::OpensslString; use string::OpensslString;
use {cvt, cvt_n, cvt_p};
#[cfg(ossl10x)] cfg_if! {
use ffi::{get_rfc2409_prime_1024 as BN_get_rfc2409_prime_1024, if #[cfg(ossl110)] {
get_rfc2409_prime_768 as BN_get_rfc2409_prime_768, use ffi::{
get_rfc3526_prime_1536 as BN_get_rfc3526_prime_1536, BN_get_rfc2409_prime_1024, BN_get_rfc2409_prime_768, BN_get_rfc3526_prime_1536,
get_rfc3526_prime_2048 as BN_get_rfc3526_prime_2048, BN_get_rfc3526_prime_2048, BN_get_rfc3526_prime_3072, BN_get_rfc3526_prime_4096,
get_rfc3526_prime_3072 as BN_get_rfc3526_prime_3072, BN_get_rfc3526_prime_6144, BN_get_rfc3526_prime_8192, BN_is_negative,
get_rfc3526_prime_4096 as BN_get_rfc3526_prime_4096, };
get_rfc3526_prime_6144 as BN_get_rfc3526_prime_6144, } else {
get_rfc3526_prime_8192 as BN_get_rfc3526_prime_8192}; use ffi::{
get_rfc2409_prime_1024 as BN_get_rfc2409_prime_1024,
get_rfc2409_prime_768 as BN_get_rfc2409_prime_768,
get_rfc3526_prime_1536 as BN_get_rfc3526_prime_1536,
get_rfc3526_prime_2048 as BN_get_rfc3526_prime_2048,
get_rfc3526_prime_3072 as BN_get_rfc3526_prime_3072,
get_rfc3526_prime_4096 as BN_get_rfc3526_prime_4096,
get_rfc3526_prime_6144 as BN_get_rfc3526_prime_6144,
get_rfc3526_prime_8192 as BN_get_rfc3526_prime_8192,
};
#[cfg(ossl110)] #[allow(bad_style)]
use ffi::{BN_get_rfc2409_prime_1024, BN_get_rfc2409_prime_768, BN_get_rfc3526_prime_1536, unsafe fn BN_is_negative(bn: *const ffi::BIGNUM) -> c_int {
BN_get_rfc3526_prime_2048, BN_get_rfc3526_prime_3072, BN_get_rfc3526_prime_4096, (*bn).neg
BN_get_rfc3526_prime_6144, BN_get_rfc3526_prime_8192}; }
}
}
/// Options for the most significant bits of a randomly generated `BigNum`. /// Options for the most significant bits of a randomly generated `BigNum`.
pub struct MsbOption(c_int); pub struct MsbOption(c_int);
@ -361,17 +372,7 @@ impl BigNumRef {
/// Returns `true` if `self` is negative. /// Returns `true` if `self` is negative.
pub fn is_negative(&self) -> bool { pub fn is_negative(&self) -> bool {
self._is_negative() unsafe { BN_is_negative(self.as_ptr()) == 1 }
}
#[cfg(ossl10x)]
fn _is_negative(&self) -> bool {
unsafe { (*self.as_ptr()).neg == 1 }
}
#[cfg(ossl110)]
fn _is_negative(&self) -> bool {
unsafe { ffi::BN_is_negative(self.as_ptr()) == 1 }
} }
/// Returns the number of significant bits in `self`. /// Returns the number of significant bits in `self`.
@ -1218,7 +1219,7 @@ macro_rules! delegate {
$t::$m(self.deref(), oth.deref()) $t::$m(self.deref(), oth.deref())
} }
} }
} };
} }
impl<'a, 'b> Add<&'b BigNumRef> for &'a BigNumRef { impl<'a, 'b> Add<&'b BigNumRef> for &'a BigNumRef {

View File

@ -4,9 +4,9 @@ use foreign_types::{ForeignType, ForeignTypeRef};
use std::mem; use std::mem;
use std::ptr; use std::ptr;
use {cvt, cvt_p};
use bn::BigNum; use bn::BigNum;
use pkey::{HasParams, Params}; use pkey::{HasParams, Params};
use {cvt, cvt_p};
generic_foreign_type_and_impl_send_sync! { generic_foreign_type_and_impl_send_sync! {
type CType = ffi::DH; type CType = ffi::DH;
@ -48,12 +48,7 @@ impl Dh<Params> {
pub fn from_params(p: BigNum, g: BigNum, q: BigNum) -> Result<Dh<Params>, ErrorStack> { pub fn from_params(p: BigNum, g: BigNum, q: BigNum) -> Result<Dh<Params>, ErrorStack> {
unsafe { unsafe {
let dh = Dh::from_ptr(cvt_p(ffi::DH_new())?); let dh = Dh::from_ptr(cvt_p(ffi::DH_new())?);
cvt(compat::DH_set0_pqg( cvt(DH_set0_pqg(dh.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?;
dh.0,
p.as_ptr(),
q.as_ptr(),
g.as_ptr(),
))?;
mem::forget((p, g, q)); mem::forget((p, g, q));
Ok(dh) Ok(dh)
} }
@ -111,34 +106,29 @@ impl Dh<Params> {
} }
} }
#[cfg(ossl110)] cfg_if! {
mod compat { if #[cfg(ossl110)] {
pub use ffi::DH_set0_pqg; use ffi::DH_set0_pqg;
} } else {
#[allow(bad_style)]
#[cfg(ossl10x)] unsafe fn DH_set0_pqg(
#[allow(bad_style)] dh: *mut ffi::DH,
mod compat { p: *mut ffi::BIGNUM,
use ffi; q: *mut ffi::BIGNUM,
use libc::c_int; g: *mut ffi::BIGNUM,
) -> ::libc::c_int {
pub unsafe fn DH_set0_pqg( (*dh).p = p;
dh: *mut ffi::DH, (*dh).q = q;
p: *mut ffi::BIGNUM, (*dh).g = g;
q: *mut ffi::BIGNUM, 1
g: *mut ffi::BIGNUM, }
) -> c_int {
(*dh).p = p;
(*dh).q = q;
(*dh).g = g;
1
} }
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use dh::Dh;
use bn::BigNum; use bn::BigNum;
use dh::Dh;
use ssl::{SslContext, SslMethod}; use ssl::{SslContext, SslMethod};
#[test] #[test]

View File

@ -11,10 +11,10 @@ use libc::c_int;
use std::fmt; use std::fmt;
use std::ptr; use std::ptr;
use {cvt, cvt_p};
use bn::BigNumRef; use bn::BigNumRef;
use error::ErrorStack; use error::ErrorStack;
use pkey::{HasParams, HasPublic, Private, Public}; use pkey::{HasParams, HasPublic, Private, Public};
use {cvt, cvt_p};
generic_foreign_type_and_impl_send_sync! { generic_foreign_type_and_impl_send_sync! {
type CType = ffi::DSA; type CType = ffi::DSA;
@ -101,7 +101,8 @@ where
/// Returns the DSA prime parameter of `self`. /// Returns the DSA prime parameter of `self`.
pub fn p(&self) -> &BigNumRef { pub fn p(&self) -> &BigNumRef {
unsafe { unsafe {
let p = compat::pqg(self.as_ptr())[0]; let mut p = ptr::null();
DSA_get0_pqg(self.as_ptr(), &mut p, ptr::null_mut(), ptr::null_mut());
BigNumRef::from_ptr(p as *mut _) BigNumRef::from_ptr(p as *mut _)
} }
} }
@ -109,7 +110,8 @@ where
/// Returns the DSA sub-prime parameter of `self`. /// Returns the DSA sub-prime parameter of `self`.
pub fn q(&self) -> &BigNumRef { pub fn q(&self) -> &BigNumRef {
unsafe { unsafe {
let q = compat::pqg(self.as_ptr())[1]; let mut q = ptr::null();
DSA_get0_pqg(self.as_ptr(), ptr::null_mut(), &mut q, ptr::null_mut());
BigNumRef::from_ptr(q as *mut _) BigNumRef::from_ptr(q as *mut _)
} }
} }
@ -117,7 +119,8 @@ where
/// Returns the DSA base parameter of `self`. /// Returns the DSA base parameter of `self`.
pub fn g(&self) -> &BigNumRef { pub fn g(&self) -> &BigNumRef {
unsafe { unsafe {
let g = compat::pqg(self.as_ptr())[2]; let mut g = ptr::null();
DSA_get0_pqg(self.as_ptr(), ptr::null_mut(), ptr::null_mut(), &mut g);
BigNumRef::from_ptr(g as *mut _) BigNumRef::from_ptr(g as *mut _)
} }
} }
@ -184,24 +187,27 @@ impl<T> fmt::Debug for Dsa<T> {
} }
} }
#[cfg(ossl110)] cfg_if! {
mod compat { if #[cfg(ossl110)] {
use std::ptr; use ffi::DSA_get0_pqg;
use ffi::{self, BIGNUM, DSA}; } else {
#[allow(bad_style)]
pub unsafe fn pqg(d: *const DSA) -> [*const BIGNUM; 3] { unsafe fn DSA_get0_pqg(
let (mut p, mut q, mut g) = (ptr::null(), ptr::null(), ptr::null()); d: *mut ffi::DSA,
ffi::DSA_get0_pqg(d, &mut p, &mut q, &mut g); p: *mut *const ffi::BIGNUM,
[p, q, g] q: *mut *const ffi::BIGNUM,
} g: *mut *const ffi::BIGNUM)
} {
if !p.is_null() {
#[cfg(ossl10x)] *p = (*d).p;
mod compat { }
use ffi::{BIGNUM, DSA}; if !q.is_null() {
*q = (*d).q;
pub unsafe fn pqg(d: *const DSA) -> [*const BIGNUM; 3] { }
[(*d).p, (*d).q, (*d).g] if !g.is_null() {
*g = (*d).g;
}
}
} }
} }

View File

@ -3,12 +3,13 @@ use ffi;
use foreign_types::{ForeignType, ForeignTypeRef}; use foreign_types::{ForeignType, ForeignTypeRef};
use libc::c_int; use libc::c_int;
use std::mem; use std::mem;
use std::ptr;
use bn::{BigNum, BigNumRef}; use bn::{BigNum, BigNumRef};
use {cvt, cvt_n, cvt_p};
use ec::EcKeyRef; use ec::EcKeyRef;
use error::ErrorStack; use error::ErrorStack;
use pkey::{Private, Public}; use pkey::{Private, Public};
use {cvt_n, cvt_p};
foreign_type_and_impl_send_sync! { foreign_type_and_impl_send_sync! {
type CType = ffi::ECDSA_SIG; type CType = ffi::ECDSA_SIG;
@ -53,7 +54,7 @@ impl EcdsaSig {
pub fn from_private_components(r: BigNum, s: BigNum) -> Result<EcdsaSig, ErrorStack> { pub fn from_private_components(r: BigNum, s: BigNum) -> Result<EcdsaSig, ErrorStack> {
unsafe { unsafe {
let sig = cvt_p(ffi::ECDSA_SIG_new())?; let sig = cvt_p(ffi::ECDSA_SIG_new())?;
cvt(compat::set_numbers(sig, r.as_ptr(), s.as_ptr()))?; ECDSA_SIG_set0(sig, r.as_ptr(), s.as_ptr());
mem::forget((r, s)); mem::forget((r, s));
Ok(EcdsaSig::from_ptr(sig as *mut _)) Ok(EcdsaSig::from_ptr(sig as *mut _))
} }
@ -83,8 +84,9 @@ impl EcdsaSig {
/// [`ECDSA_SIG_get0`]: https://www.openssl.org/docs/man1.1.0/crypto/ECDSA_SIG_get0.html /// [`ECDSA_SIG_get0`]: https://www.openssl.org/docs/man1.1.0/crypto/ECDSA_SIG_get0.html
pub fn r(&self) -> &BigNumRef { pub fn r(&self) -> &BigNumRef {
unsafe { unsafe {
let xs = compat::get_numbers(self.as_ptr()); let mut r = ptr::null();
BigNumRef::from_ptr(xs[0] as *mut _) ECDSA_SIG_get0(self.as_ptr(), &mut r, ptr::null_mut());
BigNumRef::from_ptr(r as *mut _)
} }
} }
@ -95,53 +97,50 @@ impl EcdsaSig {
/// [`ECDSA_SIG_get0`]: https://www.openssl.org/docs/man1.1.0/crypto/ECDSA_SIG_get0.html /// [`ECDSA_SIG_get0`]: https://www.openssl.org/docs/man1.1.0/crypto/ECDSA_SIG_get0.html
pub fn s(&self) -> &BigNumRef { pub fn s(&self) -> &BigNumRef {
unsafe { unsafe {
let xs = compat::get_numbers(self.as_ptr()); let mut s = ptr::null();
BigNumRef::from_ptr(xs[1] as *mut _) ECDSA_SIG_get0(self.as_ptr(), ptr::null_mut(), &mut s);
BigNumRef::from_ptr(s as *mut _)
} }
} }
} }
#[cfg(ossl110)] cfg_if! {
mod compat { if #[cfg(ossl110)] {
use std::ptr; use ffi::{ECDSA_SIG_set0, ECDSA_SIG_get0};
} else {
#[allow(bad_style)]
unsafe fn ECDSA_SIG_set0(
sig: *mut ffi::ECDSA_SIG,
r: *mut ffi::BIGNUM,
s: *mut ffi::BIGNUM,
) -> c_int {
(*sig).r = r;
(*sig).s = s;
1
}
use libc::c_int; #[allow(bad_style)]
use ffi::{self, BIGNUM, ECDSA_SIG}; unsafe fn ECDSA_SIG_get0(
sig: *const ffi::ECDSA_SIG,
pub unsafe fn set_numbers(sig: *mut ECDSA_SIG, r: *mut BIGNUM, s: *mut BIGNUM) -> c_int { pr: *mut *const ffi::BIGNUM,
ffi::ECDSA_SIG_set0(sig, r, s) ps: *mut *const ffi::BIGNUM)
{
if !pr.is_null() {
(*pr) = (*sig).r;
}
if !ps.is_null() {
(*ps) = (*sig).s;
}
}
} }
pub unsafe fn get_numbers(sig: *mut ECDSA_SIG) -> [*const BIGNUM; 2] {
let (mut r, mut s) = (ptr::null(), ptr::null());
ffi::ECDSA_SIG_get0(sig, &mut r, &mut s);
[r, s]
}
}
#[cfg(ossl10x)]
mod compat {
use libc::c_int;
use ffi::{BIGNUM, ECDSA_SIG};
pub unsafe fn set_numbers(sig: *mut ECDSA_SIG, r: *mut BIGNUM, s: *mut BIGNUM) -> c_int {
(*sig).r = r;
(*sig).s = s;
1
}
pub unsafe fn get_numbers(sig: *mut ECDSA_SIG) -> [*const BIGNUM; 2] {
[(*sig).r, (*sig).s]
}
} }
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use nid::Nid; use super::*;
use ec::EcGroup; use ec::EcGroup;
use ec::EcKey; use ec::EcKey;
use super::*; use nid::Nid;
#[cfg(not(osslconf = "OPENSSL_NO_EC2M"))] #[cfg(not(osslconf = "OPENSSL_NO_EC2M"))]
static CURVE_IDENTIFER: Nid = Nid::X9_62_PRIME192V1; static CURVE_IDENTIFER: Nid = Nid::X9_62_PRIME192V1;
@ -171,7 +170,8 @@ mod test {
assert!(verification); assert!(verification);
// Signature will not be verified using the incorrect data but the correct public key // Signature will not be verified using the incorrect data but the correct public key
let verification2 = res.verify(String::from("hello2").as_bytes(), &public_key) let verification2 = res
.verify(String::from("hello2").as_bytes(), &public_key)
.unwrap(); .unwrap();
assert!(verification2 == false); assert!(verification2 == false);

View File

@ -1,22 +1,27 @@
use std::io::prelude::*;
use std::io;
use std::ops::{Deref, DerefMut};
use std::fmt;
use ffi; use ffi;
use std::fmt;
use std::io;
use std::io::prelude::*;
use std::ops::{Deref, DerefMut};
#[cfg(ossl110)] cfg_if! {
use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new}; if #[cfg(ossl110)] {
#[cfg(any(ossl101, ossl102))] use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new};
use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free}; } else {
use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free};
}
}
use {cvt, cvt_p};
use error::ErrorStack; use error::ErrorStack;
use {cvt, cvt_p};
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct MessageDigest(*const ffi::EVP_MD); pub struct MessageDigest(*const ffi::EVP_MD);
impl MessageDigest { impl MessageDigest {
pub unsafe fn from_ptr(x: *const ffi::EVP_MD) -> Self { MessageDigest(x) } pub unsafe fn from_ptr(x: *const ffi::EVP_MD) -> Self {
MessageDigest(x)
}
pub fn md5() -> MessageDigest { pub fn md5() -> MessageDigest {
unsafe { MessageDigest(ffi::EVP_md5()) } unsafe { MessageDigest(ffi::EVP_md5()) }
@ -382,12 +387,10 @@ mod tests {
#[test] #[test]
fn test_sha256() { fn test_sha256() {
let tests = [ let tests = [(
( "616263",
"616263", "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", )];
),
];
for test in tests.iter() { for test in tests.iter() {
hash_test(MessageDigest::sha256(), test); hash_test(MessageDigest::sha256(), test);

View File

@ -3,6 +3,8 @@
#[macro_use] #[macro_use]
extern crate bitflags; extern crate bitflags;
#[macro_use] #[macro_use]
extern crate cfg_if;
#[macro_use]
extern crate foreign_types; extern crate foreign_types;
#[macro_use] #[macro_use]
extern crate lazy_static; extern crate lazy_static;
@ -53,8 +55,8 @@ pub mod pkcs5;
pub mod pkey; pub mod pkey;
pub mod rand; pub mod rand;
pub mod rsa; pub mod rsa;
pub mod sign;
pub mod sha; pub mod sha;
pub mod sign;
pub mod ssl; pub mod ssl;
pub mod stack; pub mod stack;
pub mod string; pub mod string;

View File

@ -189,7 +189,8 @@ where
/// [`RSA_get0_key`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html /// [`RSA_get0_key`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html
pub fn d(&self) -> &BigNumRef { pub fn d(&self) -> &BigNumRef {
unsafe { unsafe {
let d = compat::key(self.as_ptr())[2]; let mut d = ptr::null();
RSA_get0_key(self.as_ptr(), ptr::null_mut(), ptr::null_mut(), &mut d);
BigNumRef::from_ptr(d as *mut _) BigNumRef::from_ptr(d as *mut _)
} }
} }
@ -201,7 +202,8 @@ where
/// [`RSA_get0_factors`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html /// [`RSA_get0_factors`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html
pub fn p(&self) -> Option<&BigNumRef> { pub fn p(&self) -> Option<&BigNumRef> {
unsafe { unsafe {
let p = compat::factors(self.as_ptr())[0]; let mut p = ptr::null();
RSA_get0_factors(self.as_ptr(), &mut p, ptr::null_mut());
if p.is_null() { if p.is_null() {
None None
} else { } else {
@ -217,7 +219,8 @@ where
/// [`RSA_get0_factors`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html /// [`RSA_get0_factors`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html
pub fn q(&self) -> Option<&BigNumRef> { pub fn q(&self) -> Option<&BigNumRef> {
unsafe { unsafe {
let q = compat::factors(self.as_ptr())[1]; let mut q = ptr::null();
RSA_get0_factors(self.as_ptr(), ptr::null_mut(), &mut q);
if q.is_null() { if q.is_null() {
None None
} else { } else {
@ -233,7 +236,8 @@ where
/// [`RSA_get0_crt_params`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html /// [`RSA_get0_crt_params`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html
pub fn dmp1(&self) -> Option<&BigNumRef> { pub fn dmp1(&self) -> Option<&BigNumRef> {
unsafe { unsafe {
let dp = compat::crt_params(self.as_ptr())[0]; let mut dp = ptr::null();
RSA_get0_crt_params(self.as_ptr(), &mut dp, ptr::null_mut(), ptr::null_mut());
if dp.is_null() { if dp.is_null() {
None None
} else { } else {
@ -249,7 +253,8 @@ where
/// [`RSA_get0_crt_params`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html /// [`RSA_get0_crt_params`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html
pub fn dmq1(&self) -> Option<&BigNumRef> { pub fn dmq1(&self) -> Option<&BigNumRef> {
unsafe { unsafe {
let dq = compat::crt_params(self.as_ptr())[1]; let mut dq = ptr::null();
RSA_get0_crt_params(self.as_ptr(), ptr::null_mut(), &mut dq, ptr::null_mut());
if dq.is_null() { if dq.is_null() {
None None
} else { } else {
@ -265,7 +270,8 @@ where
/// [`RSA_get0_crt_params`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html /// [`RSA_get0_crt_params`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html
pub fn iqmp(&self) -> Option<&BigNumRef> { pub fn iqmp(&self) -> Option<&BigNumRef> {
unsafe { unsafe {
let qi = compat::crt_params(self.as_ptr())[2]; let mut qi = ptr::null();
RSA_get0_crt_params(self.as_ptr(), ptr::null_mut(), ptr::null_mut(), &mut qi);
if qi.is_null() { if qi.is_null() {
None None
} else { } else {
@ -391,7 +397,8 @@ where
/// [`RSA_get0_key`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html /// [`RSA_get0_key`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html
pub fn n(&self) -> &BigNumRef { pub fn n(&self) -> &BigNumRef {
unsafe { unsafe {
let n = compat::key(self.as_ptr())[0]; let mut n = ptr::null();
RSA_get0_key(self.as_ptr(), &mut n, ptr::null_mut(), ptr::null_mut());
BigNumRef::from_ptr(n as *mut _) BigNumRef::from_ptr(n as *mut _)
} }
} }
@ -403,7 +410,8 @@ where
/// [`RSA_get0_key`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html /// [`RSA_get0_key`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html
pub fn e(&self) -> &BigNumRef { pub fn e(&self) -> &BigNumRef {
unsafe { unsafe {
let e = compat::key(self.as_ptr())[1]; let mut e = ptr::null();
RSA_get0_key(self.as_ptr(), ptr::null_mut(), &mut e, ptr::null_mut());
BigNumRef::from_ptr(e as *mut _) BigNumRef::from_ptr(e as *mut _)
} }
} }
@ -421,15 +429,10 @@ impl Rsa<Public> {
/// [`RSA_set0_key`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_set0_key.html /// [`RSA_set0_key`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_set0_key.html
pub fn from_public_components(n: BigNum, e: BigNum) -> Result<Rsa<Public>, ErrorStack> { pub fn from_public_components(n: BigNum, e: BigNum) -> Result<Rsa<Public>, ErrorStack> {
unsafe { unsafe {
let rsa = Rsa::from_ptr(cvt_p(ffi::RSA_new())?); let rsa = cvt_p(ffi::RSA_new())?;
cvt(compat::set_key( RSA_set0_key(rsa, n.as_ptr(), e.as_ptr(), ptr::null_mut());
rsa.0,
n.as_ptr(),
e.as_ptr(),
ptr::null_mut(),
))?;
mem::forget((n, e)); mem::forget((n, e));
Ok(rsa) Ok(Rsa::from_ptr(rsa))
} }
} }
@ -498,10 +501,12 @@ impl RsaPrivateKeyBuilder {
/// [`RSA_set0_key`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_set0_key.html /// [`RSA_set0_key`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_set0_key.html
pub fn new(n: BigNum, e: BigNum, d: BigNum) -> Result<RsaPrivateKeyBuilder, ErrorStack> { pub fn new(n: BigNum, e: BigNum, d: BigNum) -> Result<RsaPrivateKeyBuilder, ErrorStack> {
unsafe { unsafe {
let rsa = Rsa::from_ptr(cvt_p(ffi::RSA_new())?); let rsa = cvt_p(ffi::RSA_new())?;
cvt(compat::set_key(rsa.0, n.as_ptr(), e.as_ptr(), d.as_ptr()))?; RSA_set0_key(rsa, n.as_ptr(), e.as_ptr(), d.as_ptr());
mem::forget((n, e, d)); mem::forget((n, e, d));
Ok(RsaPrivateKeyBuilder { rsa }) Ok(RsaPrivateKeyBuilder {
rsa: Rsa::from_ptr(rsa),
})
} }
} }
@ -512,9 +517,10 @@ impl RsaPrivateKeyBuilder {
/// This correspond to [`RSA_set0_factors`]. /// This correspond to [`RSA_set0_factors`].
/// ///
/// [`RSA_set0_factors`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_set0_factors.html /// [`RSA_set0_factors`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_set0_factors.html
// FIXME should be infallible
pub fn set_factors(self, p: BigNum, q: BigNum) -> Result<RsaPrivateKeyBuilder, ErrorStack> { pub fn set_factors(self, p: BigNum, q: BigNum) -> Result<RsaPrivateKeyBuilder, ErrorStack> {
unsafe { unsafe {
cvt(compat::set_factors(self.rsa.0, p.as_ptr(), q.as_ptr()))?; RSA_set0_factors(self.rsa.as_ptr(), p.as_ptr(), q.as_ptr());
mem::forget((p, q)); mem::forget((p, q));
} }
Ok(self) Ok(self)
@ -528,6 +534,7 @@ impl RsaPrivateKeyBuilder {
/// This correspond to [`RSA_set0_crt_params`]. /// This correspond to [`RSA_set0_crt_params`].
/// ///
/// [`RSA_set0_crt_params`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_set0_crt_params.html /// [`RSA_set0_crt_params`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_set0_crt_params.html
// FIXME should be infallible
pub fn set_crt_params( pub fn set_crt_params(
self, self,
dmp1: BigNum, dmp1: BigNum,
@ -535,12 +542,12 @@ impl RsaPrivateKeyBuilder {
iqmp: BigNum, iqmp: BigNum,
) -> Result<RsaPrivateKeyBuilder, ErrorStack> { ) -> Result<RsaPrivateKeyBuilder, ErrorStack> {
unsafe { unsafe {
cvt(compat::set_crt_params( RSA_set0_crt_params(
self.rsa.0, self.rsa.as_ptr(),
dmp1.as_ptr(), dmp1.as_ptr(),
dmq1.as_ptr(), dmq1.as_ptr(),
iqmp.as_ptr(), iqmp.as_ptr(),
))?; );
mem::forget((dmp1, dmq1, iqmp)); mem::forget((dmp1, dmq1, iqmp));
} }
Ok(self) Ok(self)
@ -637,89 +644,99 @@ impl<T> fmt::Debug for Rsa<T> {
} }
} }
#[cfg(ossl110)] cfg_if! {
mod compat { if #[cfg(ossl110)] {
use std::ptr; use ffi::{
RSA_get0_key, RSA_get0_factors, RSA_get0_crt_params, RSA_set0_key, RSA_set0_factors,
RSA_set0_crt_params,
};
} else {
#[allow(bad_style)]
unsafe fn RSA_get0_key(
r: *const ffi::RSA,
n: *mut *const ffi::BIGNUM,
e: *mut *const ffi::BIGNUM,
d: *mut *const ffi::BIGNUM,
) {
if !n.is_null() {
*n = (*r).n;
}
if !e.is_null() {
*e = (*r).e;
}
if !d.is_null() {
*d = (*r).d;
}
}
use ffi::{self, BIGNUM, RSA}; #[allow(bad_style)]
use libc::c_int; unsafe fn RSA_get0_factors(
r: *const ffi::RSA,
p: *mut *const ffi::BIGNUM,
q: *mut *const ffi::BIGNUM,
) {
if !p.is_null() {
*p = (*r).p;
}
if !q.is_null() {
*q = (*r).q;
}
}
pub unsafe fn key(r: *const RSA) -> [*const BIGNUM; 3] { #[allow(bad_style)]
let (mut n, mut e, mut d) = (ptr::null(), ptr::null(), ptr::null()); unsafe fn RSA_get0_crt_params(
ffi::RSA_get0_key(r, &mut n, &mut e, &mut d); r: *const ffi::RSA,
[n, e, d] dmp1: *mut *const ffi::BIGNUM,
} dmq1: *mut *const ffi::BIGNUM,
iqmp: *mut *const ffi::BIGNUM,
) {
if !dmp1.is_null() {
*dmp1 = (*r).dmp1;
}
if !dmq1.is_null() {
*dmq1 = (*r).dmq1;
}
if !iqmp.is_null() {
*iqmp = (*r).iqmp;
}
}
pub unsafe fn factors(r: *const RSA) -> [*const BIGNUM; 2] { #[allow(bad_style)]
let (mut p, mut q) = (ptr::null(), ptr::null()); unsafe fn RSA_set0_key(
ffi::RSA_get0_factors(r, &mut p, &mut q); r: *mut ffi::RSA,
[p, q] n: *mut ffi::BIGNUM,
} e: *mut ffi::BIGNUM,
d: *mut ffi::BIGNUM,
) -> c_int {
(*r).n = n;
(*r).e = e;
(*r).d = d;
1
}
pub unsafe fn crt_params(r: *const RSA) -> [*const BIGNUM; 3] { #[allow(bad_style)]
let (mut dp, mut dq, mut qi) = (ptr::null(), ptr::null(), ptr::null()); unsafe fn RSA_set0_factors(
ffi::RSA_get0_crt_params(r, &mut dp, &mut dq, &mut qi); r: *mut ffi::RSA,
[dp, dq, qi] p: *mut ffi::BIGNUM,
} q: *mut ffi::BIGNUM,
) -> c_int {
(*r).p = p;
(*r).q = q;
1
}
pub unsafe fn set_key(r: *mut RSA, n: *mut BIGNUM, e: *mut BIGNUM, d: *mut BIGNUM) -> c_int { #[allow(bad_style)]
ffi::RSA_set0_key(r, n, e, d) unsafe fn RSA_set0_crt_params(
} r: *mut ffi::RSA,
dmp1: *mut ffi::BIGNUM,
pub unsafe fn set_factors(r: *mut RSA, p: *mut BIGNUM, q: *mut BIGNUM) -> c_int { dmq1: *mut ffi::BIGNUM,
ffi::RSA_set0_factors(r, p, q) iqmp: *mut ffi::BIGNUM,
} ) -> c_int {
(*r).dmp1 = dmp1;
pub unsafe fn set_crt_params( (*r).dmq1 = dmq1;
r: *mut RSA, (*r).iqmp = iqmp;
dmp1: *mut BIGNUM, 1
dmq1: *mut BIGNUM, }
iqmp: *mut BIGNUM,
) -> c_int {
ffi::RSA_set0_crt_params(r, dmp1, dmq1, iqmp)
}
}
#[cfg(ossl10x)]
mod compat {
use ffi::{BIGNUM, RSA};
use libc::c_int;
pub unsafe fn key(r: *const RSA) -> [*const BIGNUM; 3] {
[(*r).n, (*r).e, (*r).d]
}
pub unsafe fn factors(r: *const RSA) -> [*const BIGNUM; 2] {
[(*r).p, (*r).q]
}
pub unsafe fn crt_params(r: *const RSA) -> [*const BIGNUM; 3] {
[(*r).dmp1, (*r).dmq1, (*r).iqmp]
}
pub unsafe fn set_key(r: *mut RSA, n: *mut BIGNUM, e: *mut BIGNUM, d: *mut BIGNUM) -> c_int {
(*r).n = n;
(*r).e = e;
(*r).d = d;
1 // TODO: is this right? should it be 0? what's success?
}
pub unsafe fn set_factors(r: *mut RSA, p: *mut BIGNUM, q: *mut BIGNUM) -> c_int {
(*r).p = p;
(*r).q = q;
1 // TODO: is this right? should it be 0? what's success?
}
pub unsafe fn set_crt_params(
r: *mut RSA,
dmp1: *mut BIGNUM,
dmq1: *mut BIGNUM,
iqmp: *mut BIGNUM,
) -> c_int {
(*r).dmp1 = dmp1;
(*r).dmq1 = dmq1;
(*r).iqmp = iqmp;
1 // TODO: is this right? should it be 0? what's success?
} }
} }

View File

@ -63,21 +63,24 @@
//! ``` //! ```
use ffi; use ffi;
use foreign_types::ForeignTypeRef; use foreign_types::ForeignTypeRef;
use libc::c_int;
use std::io::{self, Write}; use std::io::{self, Write};
use std::marker::PhantomData; use std::marker::PhantomData;
use std::ptr; use std::ptr;
use libc::c_int;
use {cvt, cvt_p}; use error::ErrorStack;
use hash::MessageDigest; use hash::MessageDigest;
use pkey::{HasPrivate, HasPublic, PKeyRef}; use pkey::{HasPrivate, HasPublic, PKeyRef};
use error::ErrorStack;
use rsa::Padding; use rsa::Padding;
use {cvt, cvt_p};
#[cfg(ossl110)] cfg_if! {
use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new}; if #[cfg(ossl110)] {
#[cfg(any(ossl101, ossl102))] use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new};
use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free}; } else {
use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free};
}
}
/// Salt lengths that must be used with `set_rsa_pss_saltlen`. /// Salt lengths that must be used with `set_rsa_pss_saltlen`.
pub struct RsaPssSaltlen(c_int); pub struct RsaPssSaltlen(c_int);
@ -459,7 +462,7 @@ impl<'a> Verifier<'a> {
pub fn verify(&self, signature: &[u8]) -> Result<bool, ErrorStack> { pub fn verify(&self, signature: &[u8]) -> Result<bool, ErrorStack> {
unsafe { unsafe {
let r = let r =
EVP_DigestVerifyFinal(self.md_ctx, signature.as_ptr() as *const _, signature.len()); EVP_DigestVerifyFinal(self.md_ctx, signature.as_ptr() as *mut _, signature.len());
match r { match r {
1 => Ok(true), 1 => Ok(true),
0 => { 0 => {
@ -501,12 +504,12 @@ mod test {
use hex::{self, FromHex}; use hex::{self, FromHex};
use std::iter; use std::iter;
use hash::MessageDigest;
use sign::{RsaPssSaltlen, Signer, Verifier};
use ec::{EcGroup, EcKey}; use ec::{EcGroup, EcKey};
use hash::MessageDigest;
use nid::Nid; use nid::Nid;
use rsa::{Padding, Rsa};
use pkey::PKey; use pkey::PKey;
use rsa::{Padding, Rsa};
use sign::{RsaPssSaltlen, Signer, Verifier};
const INPUT: &'static str = const INPUT: &'static str =
"65794a68624763694f694a53557a49314e694a392e65794a7063334d694f694a71623255694c41304b49434a6c\ "65794a68624763694f694a53557a49314e694a392e65794a7063334d694f694a71623255694c41304b49434a6c\
@ -673,7 +676,7 @@ mod test {
signer.update(data as &[u8]).unwrap(); signer.update(data as &[u8]).unwrap();
let expected = vec![ let expected = vec![
136, 101, 61, 167, 61, 30, 248, 234, 124, 166, 196, 157, 203, 52, 171, 19 136, 101, 61, 167, 61, 30, 248, 234, 124, 166, 196, 157, 203, 52, 171, 19,
]; ];
assert_eq!(signer.sign_to_vec().unwrap(), expected); assert_eq!(signer.sign_to_vec().unwrap(), expected);
} }

View File

@ -1,11 +1,13 @@
use ffi::{
self, BIO_clear_retry_flags, BIO_new, BIO_set_retry_read, BIO_set_retry_write, BIO,
BIO_CTRL_FLUSH,
};
use libc::{c_char, c_int, c_long, c_void, strlen}; use libc::{c_char, c_int, c_long, c_void, strlen};
use ffi::{BIO, BIO_CTRL_FLUSH, BIO_new, BIO_clear_retry_flags, BIO_set_retry_read,
BIO_set_retry_write};
use std::any::Any; use std::any::Any;
use std::io; use std::io;
use std::io::prelude::*; use std::io::prelude::*;
use std::mem; use std::mem;
use std::panic::{AssertUnwindSafe, catch_unwind}; use std::panic::{catch_unwind, AssertUnwindSafe};
use std::ptr; use std::ptr;
use std::slice; use std::slice;
@ -19,11 +21,11 @@ pub struct StreamState<S> {
} }
/// Safe wrapper for BIO_METHOD /// Safe wrapper for BIO_METHOD
pub struct BioMethod(compat::BIO_METHOD); pub struct BioMethod(BIO_METHOD);
impl BioMethod { impl BioMethod {
fn new<S: Read + Write>() -> BioMethod { fn new<S: Read + Write>() -> BioMethod {
BioMethod(compat::BIO_METHOD::new::<S>()) BioMethod(BIO_METHOD::new::<S>())
} }
} }
@ -41,8 +43,8 @@ pub fn new<S: Read + Write>(stream: S) -> Result<(*mut BIO, BioMethod), ErrorSta
unsafe { unsafe {
let bio = cvt_p(BIO_new(method.0.get()))?; let bio = cvt_p(BIO_new(method.0.get()))?;
compat::BIO_set_data(bio, Box::into_raw(state) as *mut _); BIO_set_data(bio, Box::into_raw(state) as *mut _);
compat::BIO_set_init(bio, 1); BIO_set_init(bio, 1);
return Ok((bio, method)); return Ok((bio, method));
} }
@ -59,7 +61,7 @@ pub unsafe fn take_panic<S>(bio: *mut BIO) -> Option<Box<Any + Send>> {
} }
pub unsafe fn get_ref<'a, S: 'a>(bio: *mut BIO) -> &'a S { pub unsafe fn get_ref<'a, S: 'a>(bio: *mut BIO) -> &'a S {
let state: &'a StreamState<S> = mem::transmute(compat::BIO_get_data(bio)); let state: &'a StreamState<S> = mem::transmute(BIO_get_data(bio));
&state.stream &state.stream
} }
@ -68,7 +70,7 @@ pub unsafe fn get_mut<'a, S: 'a>(bio: *mut BIO) -> &'a mut S {
} }
unsafe fn state<'a, S: 'a>(bio: *mut BIO) -> &'a mut StreamState<S> { unsafe fn state<'a, S: 'a>(bio: *mut BIO) -> &'a mut StreamState<S> {
&mut *(compat::BIO_get_data(bio) as *mut _) &mut *(BIO_get_data(bio) as *mut _)
} }
unsafe extern "C" fn bwrite<S: Write>(bio: *mut BIO, buf: *const c_char, len: c_int) -> c_int { unsafe extern "C" fn bwrite<S: Write>(bio: *mut BIO, buf: *const c_char, len: c_int) -> c_int {
@ -117,8 +119,7 @@ unsafe extern "C" fn bread<S: Read>(bio: *mut BIO, buf: *mut c_char, len: c_int)
fn retriable_error(err: &io::Error) -> bool { fn retriable_error(err: &io::Error) -> bool {
match err.kind() { match err.kind() {
io::ErrorKind::WouldBlock | io::ErrorKind::WouldBlock | io::ErrorKind::NotConnected => true,
io::ErrorKind::NotConnected => true,
_ => false, _ => false,
} }
} }
@ -153,10 +154,10 @@ unsafe extern "C" fn ctrl<S: Write>(
} }
unsafe extern "C" fn create(bio: *mut BIO) -> c_int { unsafe extern "C" fn create(bio: *mut BIO) -> c_int {
compat::BIO_set_init(bio, 0); BIO_set_init(bio, 0);
compat::BIO_set_num(bio, 0); BIO_set_num(bio, 0);
compat::BIO_set_data(bio, ptr::null_mut()); BIO_set_data(bio, ptr::null_mut());
compat::BIO_set_flags(bio, 0); BIO_set_flags(bio, 0);
1 1
} }
@ -165,115 +166,110 @@ unsafe extern "C" fn destroy<S>(bio: *mut BIO) -> c_int {
return 0; return 0;
} }
let data = compat::BIO_get_data(bio); let data = BIO_get_data(bio);
assert!(!data.is_null()); assert!(!data.is_null());
Box::<StreamState<S>>::from_raw(data as *mut _); Box::<StreamState<S>>::from_raw(data as *mut _);
compat::BIO_set_data(bio, ptr::null_mut()); BIO_set_data(bio, ptr::null_mut());
compat::BIO_set_init(bio, 0); BIO_set_init(bio, 0);
1 1
} }
#[cfg(ossl110)] cfg_if! {
#[allow(bad_style)] if #[cfg(ossl110)] {
mod compat { use ffi::{BIO_get_data, BIO_set_data, BIO_set_flags, BIO_set_init};
use std::io::{Read, Write};
use libc::c_int; #[allow(bad_style)]
use ffi; unsafe fn BIO_set_num(_bio: *mut ffi::BIO, _num: c_int) {}
pub use ffi::{BIO_set_init, BIO_set_flags, BIO_set_data, BIO_get_data};
pub unsafe fn BIO_set_num(_bio: *mut ffi::BIO, _num: c_int) {} #[allow(bad_style)]
struct BIO_METHOD(*mut ffi::BIO_METHOD);
pub struct BIO_METHOD(*mut ffi::BIO_METHOD); impl BIO_METHOD {
fn new<S: Read + Write>() -> BIO_METHOD {
unsafe {
let ptr = ffi::BIO_meth_new(ffi::BIO_TYPE_NONE, b"rust\0".as_ptr() as *const _);
assert!(!ptr.is_null());
let ret = BIO_METHOD(ptr);
assert!(ffi::BIO_meth_set_write(ptr, bwrite::<S>) != 0);
assert!(ffi::BIO_meth_set_read(ptr, bread::<S>) != 0);
assert!(ffi::BIO_meth_set_puts(ptr, bputs::<S>) != 0);
assert!(ffi::BIO_meth_set_ctrl(ptr, ctrl::<S>) != 0);
assert!(ffi::BIO_meth_set_create(ptr, create) != 0);
assert!(ffi::BIO_meth_set_destroy(ptr, destroy::<S>) != 0);
return ret;
}
}
impl BIO_METHOD { fn get(&self) -> *mut ffi::BIO_METHOD {
pub fn new<S: Read + Write>() -> BIO_METHOD { self.0
unsafe {
let ptr = ffi::BIO_meth_new(ffi::BIO_TYPE_NONE, b"rust\0".as_ptr() as *const _);
assert!(!ptr.is_null());
let ret = BIO_METHOD(ptr);
assert!(ffi::BIO_meth_set_write(ptr, super::bwrite::<S>) != 0);
assert!(ffi::BIO_meth_set_read(ptr, super::bread::<S>) != 0);
assert!(ffi::BIO_meth_set_puts(ptr, super::bputs::<S>) != 0);
assert!(ffi::BIO_meth_set_ctrl(ptr, super::ctrl::<S>) != 0);
assert!(ffi::BIO_meth_set_create(ptr, super::create) != 0);
assert!(ffi::BIO_meth_set_destroy(ptr, super::destroy::<S>) != 0);
return ret;
} }
} }
pub fn get(&self) -> *mut ffi::BIO_METHOD { impl Drop for BIO_METHOD {
self.0 fn drop(&mut self) {
} unsafe {
} ffi::BIO_meth_free(self.0);
}
impl Drop for BIO_METHOD {
fn drop(&mut self) {
unsafe {
ffi::BIO_meth_free(self.0);
} }
} }
} else {
#[allow(bad_style)]
struct BIO_METHOD(*mut ffi::BIO_METHOD);
impl BIO_METHOD {
fn new<S: Read + Write>() -> BIO_METHOD {
let ptr = Box::new(ffi::BIO_METHOD {
type_: ffi::BIO_TYPE_NONE,
name: b"rust\0".as_ptr() as *const _,
bwrite: Some(bwrite::<S>),
bread: Some(bread::<S>),
bputs: Some(bputs::<S>),
bgets: None,
ctrl: Some(ctrl::<S>),
create: Some(create),
destroy: Some(destroy::<S>),
callback_ctrl: None,
});
BIO_METHOD(Box::into_raw(ptr))
}
fn get(&self) -> *mut ffi::BIO_METHOD {
self.0
}
}
impl Drop for BIO_METHOD {
fn drop(&mut self) {
unsafe {
Box::<ffi::BIO_METHOD>::from_raw(self.0);
}
}
}
#[allow(bad_style)]
unsafe fn BIO_set_init(bio: *mut ffi::BIO, init: c_int) {
(*bio).init = init;
}
#[allow(bad_style)]
unsafe fn BIO_set_flags(bio: *mut ffi::BIO, flags: c_int) {
(*bio).flags = flags;
}
#[allow(bad_style)]
unsafe fn BIO_get_data(bio: *mut ffi::BIO) -> *mut c_void {
(*bio).ptr
}
#[allow(bad_style)]
unsafe fn BIO_set_data(bio: *mut ffi::BIO, data: *mut c_void) {
(*bio).ptr = data;
}
#[allow(bad_style)]
unsafe fn BIO_set_num(bio: *mut ffi::BIO, num: c_int) {
(*bio).num = num;
}
} }
} }
#[cfg(ossl10x)]
#[allow(bad_style)]
mod compat {
use std::io::{Read, Write};
use ffi;
use libc::{c_int, c_void};
pub struct BIO_METHOD(*mut ffi::BIO_METHOD);
impl BIO_METHOD {
pub fn new<S: Read + Write>() -> BIO_METHOD {
let ptr = Box::new(ffi::BIO_METHOD {
type_: ffi::BIO_TYPE_NONE,
name: b"rust\0".as_ptr() as *const _,
bwrite: Some(super::bwrite::<S>),
bread: Some(super::bread::<S>),
bputs: Some(super::bputs::<S>),
bgets: None,
ctrl: Some(super::ctrl::<S>),
create: Some(super::create),
destroy: Some(super::destroy::<S>),
callback_ctrl: None,
});
BIO_METHOD(Box::into_raw(ptr))
}
pub fn get(&self) -> *mut ffi::BIO_METHOD {
self.0
}
}
impl Drop for BIO_METHOD {
fn drop(&mut self) {
unsafe {
Box::<ffi::BIO_METHOD>::from_raw(self.0);
}
}
}
pub unsafe fn BIO_set_init(bio: *mut ffi::BIO, init: c_int) {
(*bio).init = init;
}
pub unsafe fn BIO_set_flags(bio: *mut ffi::BIO, flags: c_int) {
(*bio).flags = flags;
}
pub unsafe fn BIO_get_data(bio: *mut ffi::BIO) -> *mut c_void {
(*bio).ptr
}
pub unsafe fn BIO_set_data(bio: *mut ffi::BIO, data: *mut c_void) {
(*bio).ptr = data;
}
pub unsafe fn BIO_set_num(bio: *mut ffi::BIO, num: c_int) {
(*bio).num = num;
}
}

View File

@ -13,11 +13,11 @@ use std::str;
use std::sync::Arc; use std::sync::Arc;
use dh::Dh; use dh::Dh;
#[cfg(any(ossl101, ossl102))] #[cfg(all(ossl101, not(ossl110)))]
use ec::EcKey; use ec::EcKey;
use error::ErrorStack; use error::ErrorStack;
use pkey::Params; use pkey::Params;
#[cfg(any(ossl102, ossl110))] #[cfg(ossl102)]
use ssl::AlpnError; use ssl::AlpnError;
#[cfg(ossl111)] #[cfg(ossl111)]
use ssl::ExtensionContext; use ssl::ExtensionContext;
@ -37,7 +37,8 @@ where
// raw pointer shenanigans to break the borrow of ctx // raw pointer shenanigans to break the borrow of ctx
// the callback can't mess with its own ex_data slot so this is safe // the callback can't mess with its own ex_data slot so this is safe
let verify = ctx.ex_data(ssl_idx) let verify = ctx
.ex_data(ssl_idx)
.expect("BUG: store context missing ssl") .expect("BUG: store context missing ssl")
.ssl_context() .ssl_context()
.ex_data(verify_idx) .ex_data(verify_idx)
@ -66,7 +67,8 @@ where
let ssl = SslRef::from_ptr_mut(ssl); let ssl = SslRef::from_ptr_mut(ssl);
let callback_idx = SslContext::cached_ex_index::<F>(); let callback_idx = SslContext::cached_ex_index::<F>();
let callback = ssl.ssl_context() let callback = ssl
.ssl_context()
.ex_data(callback_idx) .ex_data(callback_idx)
.expect("BUG: psk callback missing") as *const F; .expect("BUG: psk callback missing") as *const F;
let hint = if hint != ptr::null() { let hint = if hint != ptr::null() {
@ -96,7 +98,8 @@ where
let ssl_idx = X509StoreContext::ssl_idx().expect("BUG: store context ssl index missing"); let ssl_idx = X509StoreContext::ssl_idx().expect("BUG: store context ssl index missing");
let callback_idx = Ssl::cached_ex_index::<Arc<F>>(); let callback_idx = Ssl::cached_ex_index::<Arc<F>>();
let callback = ctx.ex_data(ssl_idx) let callback = ctx
.ex_data(ssl_idx)
.expect("BUG: store context missing ssl") .expect("BUG: store context missing ssl")
.ex_data(callback_idx) .ex_data(callback_idx)
.expect("BUG: ssl verify callback missing") .expect("BUG: ssl verify callback missing")
@ -112,7 +115,8 @@ where
{ {
unsafe { unsafe {
let ssl = SslRef::from_ptr_mut(ssl); let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl.ssl_context() let callback = ssl
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>()) .ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: sni callback missing") as *const F; .expect("BUG: sni callback missing") as *const F;
let mut alert = SslAlert(*al); let mut alert = SslAlert(*al);
@ -140,7 +144,8 @@ where
{ {
unsafe { unsafe {
let ssl = SslRef::from_ptr_mut(ssl); let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl.ssl_context() let callback = ssl
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>()) .ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: alpn callback missing") as *const F; .expect("BUG: alpn callback missing") as *const F;
let protos = slice::from_raw_parts(inbuf as *const u8, inlen as usize); let protos = slice::from_raw_parts(inbuf as *const u8, inlen as usize);
@ -165,7 +170,8 @@ where
F: Fn(&mut SslRef, bool, u32) -> Result<Dh<Params>, ErrorStack> + 'static + Sync + Send, F: Fn(&mut SslRef, bool, u32) -> Result<Dh<Params>, ErrorStack> + 'static + Sync + Send,
{ {
let ssl = SslRef::from_ptr_mut(ssl); let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl.ssl_context() let callback = ssl
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>()) .ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: tmp dh callback missing") as *const F; .expect("BUG: tmp dh callback missing") as *const F;
@ -182,7 +188,7 @@ where
} }
} }
#[cfg(any(ossl101, ossl102))] #[cfg(all(ossl101, not(ossl110)))]
pub unsafe extern "C" fn raw_tmp_ecdh<F>( pub unsafe extern "C" fn raw_tmp_ecdh<F>(
ssl: *mut ffi::SSL, ssl: *mut ffi::SSL,
is_export: c_int, is_export: c_int,
@ -192,7 +198,8 @@ where
F: Fn(&mut SslRef, bool, u32) -> Result<EcKey<Params>, ErrorStack> + 'static + Sync + Send, F: Fn(&mut SslRef, bool, u32) -> Result<EcKey<Params>, ErrorStack> + 'static + Sync + Send,
{ {
let ssl = SslRef::from_ptr_mut(ssl); let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl.ssl_context() let callback = ssl
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>()) .ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: tmp ecdh callback missing") as *const F; .expect("BUG: tmp ecdh callback missing") as *const F;
@ -218,7 +225,8 @@ where
F: Fn(&mut SslRef, bool, u32) -> Result<Dh<Params>, ErrorStack> + 'static + Sync + Send, F: Fn(&mut SslRef, bool, u32) -> Result<Dh<Params>, ErrorStack> + 'static + Sync + Send,
{ {
let ssl = SslRef::from_ptr_mut(ssl); let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl.ex_data(Ssl::cached_ex_index::<Arc<F>>()) let callback = ssl
.ex_data(Ssl::cached_ex_index::<Arc<F>>())
.expect("BUG: ssl tmp dh callback missing") .expect("BUG: ssl tmp dh callback missing")
.clone(); .clone();
@ -235,7 +243,7 @@ where
} }
} }
#[cfg(any(ossl101, ossl102))] #[cfg(all(ossl101, not(ossl110)))]
pub unsafe extern "C" fn raw_tmp_ecdh_ssl<F>( pub unsafe extern "C" fn raw_tmp_ecdh_ssl<F>(
ssl: *mut ffi::SSL, ssl: *mut ffi::SSL,
is_export: c_int, is_export: c_int,
@ -245,7 +253,8 @@ where
F: Fn(&mut SslRef, bool, u32) -> Result<EcKey<Params>, ErrorStack> + 'static + Sync + Send, F: Fn(&mut SslRef, bool, u32) -> Result<EcKey<Params>, ErrorStack> + 'static + Sync + Send,
{ {
let ssl = SslRef::from_ptr_mut(ssl); let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl.ex_data(Ssl::cached_ex_index::<Arc<F>>()) let callback = ssl
.ex_data(Ssl::cached_ex_index::<Arc<F>>())
.expect("BUG: ssl tmp ecdh callback missing") .expect("BUG: ssl tmp ecdh callback missing")
.clone(); .clone();
@ -267,7 +276,8 @@ where
F: Fn(&mut SslRef) -> Result<bool, ErrorStack> + 'static + Sync + Send, F: Fn(&mut SslRef) -> Result<bool, ErrorStack> + 'static + Sync + Send,
{ {
let ssl = SslRef::from_ptr_mut(ssl); let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl.ssl_context() let callback = ssl
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>()) .ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: ocsp callback missing") as *const F; .expect("BUG: ocsp callback missing") as *const F;
let ret = (*callback)(ssl); let ret = (*callback)(ssl);
@ -301,7 +311,8 @@ where
F: Fn(&mut SslRef, SslSession) + 'static + Sync + Send, F: Fn(&mut SslRef, SslSession) + 'static + Sync + Send,
{ {
let ssl = SslRef::from_ptr_mut(ssl); let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl.ssl_context() let callback = ssl
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>()) .ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: new session callback missing") as *const F; .expect("BUG: new session callback missing") as *const F;
let session = SslSession::from_ptr(session); let session = SslSession::from_ptr(session);
@ -319,7 +330,8 @@ pub unsafe extern "C" fn raw_remove_session<F>(
F: Fn(&SslContextRef, &SslSessionRef) + 'static + Sync + Send, F: Fn(&SslContextRef, &SslSessionRef) + 'static + Sync + Send,
{ {
let ctx = SslContextRef::from_ptr(ctx); let ctx = SslContextRef::from_ptr(ctx);
let callback = ctx.ex_data(SslContext::cached_ex_index::<F>()) let callback = ctx
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: remove session callback missing"); .expect("BUG: remove session callback missing");
let session = SslSessionRef::from_ptr(session); let session = SslSessionRef::from_ptr(session);
@ -341,7 +353,8 @@ where
F: Fn(&mut SslRef, &[u8]) -> Option<SslSession> + 'static + Sync + Send, F: Fn(&mut SslRef, &[u8]) -> Option<SslSession> + 'static + Sync + Send,
{ {
let ssl = SslRef::from_ptr_mut(ssl); let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl.ssl_context() let callback = ssl
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>()) .ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: get session callback missing") as *const F; .expect("BUG: get session callback missing") as *const F;
let data = slice::from_raw_parts(data as *const u8, len as usize); let data = slice::from_raw_parts(data as *const u8, len as usize);
@ -363,7 +376,8 @@ where
F: Fn(&SslRef, &str) + 'static + Sync + Send, F: Fn(&SslRef, &str) + 'static + Sync + Send,
{ {
let ssl = SslRef::from_ptr(ssl as *mut _); let ssl = SslRef::from_ptr(ssl as *mut _);
let callback = ssl.ssl_context() let callback = ssl
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>()) .ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: get session callback missing"); .expect("BUG: get session callback missing");
let line = CStr::from_ptr(line).to_bytes(); let line = CStr::from_ptr(line).to_bytes();
@ -382,7 +396,8 @@ where
F: Fn(&mut SslRef, &mut [u8]) -> Result<usize, ErrorStack> + 'static + Sync + Send, F: Fn(&mut SslRef, &mut [u8]) -> Result<usize, ErrorStack> + 'static + Sync + Send,
{ {
let ssl = SslRef::from_ptr_mut(ssl); let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl.ssl_context() let callback = ssl
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>()) .ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: stateless cookie generate callback missing") as *const F; .expect("BUG: stateless cookie generate callback missing") as *const F;
let slice = slice::from_raw_parts_mut(cookie as *mut u8, ffi::SSL_COOKIE_LENGTH as usize); let slice = slice::from_raw_parts_mut(cookie as *mut u8, ffi::SSL_COOKIE_LENGTH as usize);
@ -408,7 +423,8 @@ where
F: Fn(&mut SslRef, &[u8]) -> bool + 'static + Sync + Send, F: Fn(&mut SslRef, &[u8]) -> bool + 'static + Sync + Send,
{ {
let ssl = SslRef::from_ptr_mut(ssl); let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl.ssl_context() let callback = ssl
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>()) .ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: stateless cookie verify callback missing") as *const F; .expect("BUG: stateless cookie verify callback missing") as *const F;
let slice = slice::from_raw_parts(cookie as *const c_uchar as *const u8, cookie_len as usize); let slice = slice::from_raw_parts(cookie as *const c_uchar as *const u8, cookie_len as usize);
@ -425,7 +441,8 @@ where
{ {
unsafe { unsafe {
let ssl = SslRef::from_ptr_mut(ssl); let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl.ssl_context() let callback = ssl
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>()) .ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: cookie generate callback missing") as *const F; .expect("BUG: cookie generate callback missing") as *const F;
// We subtract 1 from DTLS1_COOKIE_LENGTH as the ostensible value, 256, is erroneous but retained for // We subtract 1 from DTLS1_COOKIE_LENGTH as the ostensible value, 256, is erroneous but retained for
@ -461,7 +478,8 @@ where
{ {
unsafe { unsafe {
let ssl = SslRef::from_ptr_mut(ssl); let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl.ssl_context() let callback = ssl
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>()) .ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: cookie verify callback missing") as *const F; .expect("BUG: cookie verify callback missing") as *const F;
let slice = let slice =
@ -494,7 +512,8 @@ where
{ {
unsafe { unsafe {
let ssl = SslRef::from_ptr_mut(ssl); let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl.ssl_context() let callback = ssl
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>()) .ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: custom ext add callback missing") as *const F; .expect("BUG: custom ext add callback missing") as *const F;
let ectx = ExtensionContext::from_bits_truncate(context); let ectx = ExtensionContext::from_bits_truncate(context);
@ -570,7 +589,8 @@ where
{ {
unsafe { unsafe {
let ssl = SslRef::from_ptr_mut(ssl); let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl.ssl_context() let callback = ssl
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>()) .ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: custom ext parse callback missing") as *const F; .expect("BUG: custom ext parse callback missing") as *const F;
let ectx = ExtensionContext::from_bits_truncate(context); let ectx = ExtensionContext::from_bits_truncate(context);

View File

@ -3,16 +3,22 @@ use std::ops::{Deref, DerefMut};
use dh::Dh; use dh::Dh;
use error::ErrorStack; use error::ErrorStack;
use ssl::{HandshakeError, Ssl, SslContext, SslContextBuilder, SslMethod, SslMode, SslOptions, use ssl::{
SslRef, SslStream, SslVerifyMode}; HandshakeError, Ssl, SslContext, SslContextBuilder, SslMethod, SslMode, SslOptions, SslRef,
SslStream, SslVerifyMode,
};
use version; use version;
fn ctx(method: SslMethod) -> Result<SslContextBuilder, ErrorStack> { fn ctx(method: SslMethod) -> Result<SslContextBuilder, ErrorStack> {
let mut ctx = SslContextBuilder::new(method)?; let mut ctx = SslContextBuilder::new(method)?;
let mut opts = SslOptions::ALL | SslOptions::NO_COMPRESSION | SslOptions::NO_SSLV2 let mut opts = SslOptions::ALL
| SslOptions::NO_SSLV3 | SslOptions::SINGLE_DH_USE | SslOptions::NO_COMPRESSION
| SslOptions::SINGLE_ECDH_USE | SslOptions::CIPHER_SERVER_PREFERENCE; | SslOptions::NO_SSLV2
| SslOptions::NO_SSLV3
| SslOptions::SINGLE_DH_USE
| SslOptions::SINGLE_ECDH_USE
| SslOptions::CIPHER_SERVER_PREFERENCE;
opts &= !SslOptions::DONT_INSERT_EMPTY_FRAGMENTS; opts &= !SslOptions::DONT_INSERT_EMPTY_FRAGMENTS;
ctx.set_options(opts); ctx.set_options(opts);
@ -23,7 +29,7 @@ fn ctx(method: SslMethod) -> Result<SslContextBuilder, ErrorStack> {
// This is quite a useful optimization for saving memory, but historically // This is quite a useful optimization for saving memory, but historically
// caused CVEs in OpenSSL pre-1.0.1h, according to // caused CVEs in OpenSSL pre-1.0.1h, according to
// https://bugs.python.org/issue25672 // https://bugs.python.org/issue25672
if version::number() >= 0x1000108f { if version::number() >= 0x1_00_01_08_0 {
mode |= SslMode::RELEASE_BUFFERS; mode |= SslMode::RELEASE_BUFFERS;
} }
@ -277,226 +283,228 @@ impl DerefMut for SslAcceptorBuilder {
} }
} }
#[cfg(ossl101)] cfg_if! {
fn setup_curves(ctx: &mut SslContextBuilder) -> Result<(), ErrorStack> { if #[cfg(ossl110)] {
use ec::EcKey; fn setup_curves(_: &mut SslContextBuilder) -> Result<(), ErrorStack> {
use nid::Nid; Ok(())
let curve = EcKey::from_curve_name(Nid::X9_62_PRIME256V1)?;
ctx.set_tmp_ecdh(&curve)
}
#[cfg(ossl102)]
fn setup_curves(ctx: &mut SslContextBuilder) -> Result<(), ErrorStack> {
ctx.set_ecdh_auto(true)
}
#[cfg(ossl110)]
fn setup_curves(_: &mut SslContextBuilder) -> Result<(), ErrorStack> {
Ok(())
}
#[cfg(any(ossl102, ossl110))]
fn setup_verify(ctx: &mut SslContextBuilder) {
ctx.set_verify(SslVerifyMode::PEER);
}
#[cfg(ossl101)]
fn setup_verify(ctx: &mut SslContextBuilder) {
ctx.set_verify_callback(SslVerifyMode::PEER, verify::verify_callback);
}
#[cfg(any(ossl102, ossl110))]
fn setup_verify_hostname(ssl: &mut Ssl, domain: &str) -> Result<(), ErrorStack> {
use x509::verify::X509CheckFlags;
let param = ssl.param_mut();
param.set_hostflags(X509CheckFlags::NO_PARTIAL_WILDCARDS);
match domain.parse() {
Ok(ip) => param.set_ip(ip),
Err(_) => param.set_host(domain),
}
}
#[cfg(ossl101)]
fn setup_verify_hostname(ssl: &mut Ssl, domain: &str) -> Result<(), ErrorStack> {
let domain = domain.to_string();
ssl.set_ex_data(*verify::HOSTNAME_IDX, domain);
Ok(())
}
#[cfg(ossl101)]
mod verify {
use std::net::IpAddr;
use std::str;
use ex_data::Index;
use nid::Nid;
use x509::{GeneralName, X509NameRef, X509Ref, X509StoreContext, X509StoreContextRef,
X509VerifyResult};
use stack::Stack;
use ssl::Ssl;
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;
} }
} else if #[cfg(any(ossl102, libressl))] {
let ok = match ( fn setup_curves(ctx: &mut SslContextBuilder) -> Result<(), ErrorStack> {
x509_ctx.current_cert(), ctx.set_ecdh_auto(true)
X509StoreContext::ssl_idx()
.ok()
.and_then(|idx| x509_ctx.ex_data(idx))
.and_then(|ssl| ssl.ex_data(*HOSTNAME_IDX)),
) {
(Some(x509), Some(domain)) => verify_hostname(domain, &x509),
_ => true,
};
if !ok {
x509_ctx.set_error(X509VerifyResult::APPLICATION_VERIFICATION);
} }
} else {
fn setup_curves(ctx: &mut SslContextBuilder) -> Result<(), ErrorStack> {
use ec::EcKey;
use nid::Nid;
ok let curve = EcKey::from_curve_name(Nid::X9_62_PRIME256V1)?;
} ctx.set_tmp_ecdh(&curve)
fn verify_hostname(domain: &str, cert: &X509Ref) -> bool {
match cert.subject_alt_names() {
Some(names) => verify_subject_alt_names(domain, names),
None => verify_subject_name(domain, &cert.subject_name()),
} }
} }
}
fn verify_subject_alt_names(domain: &str, names: Stack<GeneralName>) -> bool { cfg_if! {
let ip = domain.parse(); if #[cfg(any(ossl102, libressl261))] {
fn setup_verify(ctx: &mut SslContextBuilder) {
ctx.set_verify(SslVerifyMode::PEER);
}
for name in &names { fn setup_verify_hostname(ssl: &mut SslRef, domain: &str) -> Result<(), ErrorStack> {
match ip { use x509::verify::X509CheckFlags;
Ok(ip) => {
if let Some(actual) = name.ipaddress() { let param = ssl.param_mut();
if matches_ip(&ip, actual) { param.set_hostflags(X509CheckFlags::NO_PARTIAL_WILDCARDS);
return true; match domain.parse() {
} Ok(ip) => param.set_ip(ip),
} Err(_) => param.set_host(domain),
}
Err(_) => {
if let Some(pattern) = name.dnsname() {
if matches_dns(pattern, domain) {
return true;
}
}
}
} }
} }
} else {
fn setup_verify(ctx: &mut SslContextBuilder) {
ctx.set_verify_callback(SslVerifyMode::PEER, verify::verify_callback);
}
false fn setup_verify_hostname(ssl: &mut Ssl, domain: &str) -> Result<(), ErrorStack> {
} let domain = domain.to_string();
ssl.set_ex_data(*verify::HOSTNAME_IDX, domain);
Ok(())
}
fn verify_subject_name(domain: &str, subject_name: &X509NameRef) -> bool { mod verify {
match subject_name.entries_by_nid(Nid::COMMONNAME).next() { use std::net::IpAddr;
Some(pattern) => { use std::str;
let pattern = match str::from_utf8(pattern.data().as_slice()) {
Ok(pattern) => pattern, use ex_data::Index;
Err(_) => return false, use nid::Nid;
use ssl::Ssl;
use stack::Stack;
use x509::{
GeneralName, X509NameRef, X509Ref, X509StoreContext, X509StoreContextRef,
X509VerifyResult,
};
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;
}
let ok = match (
x509_ctx.current_cert(),
X509StoreContext::ssl_idx()
.ok()
.and_then(|idx| x509_ctx.ex_data(idx))
.and_then(|ssl| ssl.ex_data(*HOSTNAME_IDX)),
) {
(Some(x509), Some(domain)) => verify_hostname(domain, &x509),
_ => true,
}; };
// Unlike SANs, IP addresses in the subject name don't have a if !ok {
// different encoding. x509_ctx.set_error(X509VerifyResult::APPLICATION_VERIFICATION);
match domain.parse::<IpAddr>() { }
Ok(ip) => pattern
.parse::<IpAddr>() ok
.ok() }
.map_or(false, |pattern| pattern == ip),
Err(_) => matches_dns(pattern, domain), fn verify_hostname(domain: &str, cert: &X509Ref) -> bool {
match cert.subject_alt_names() {
Some(names) => verify_subject_alt_names(domain, names),
None => verify_subject_name(domain, &cert.subject_name()),
} }
} }
None => false,
}
}
fn matches_dns(mut pattern: &str, mut hostname: &str) -> bool { fn verify_subject_alt_names(domain: &str, names: Stack<GeneralName>) -> bool {
// first strip trailing . off of pattern and hostname to normalize let ip = domain.parse();
if pattern.ends_with('.') {
pattern = &pattern[..pattern.len() - 1];
}
if hostname.ends_with('.') {
hostname = &hostname[..hostname.len() - 1];
}
matches_wildcard(pattern, hostname).unwrap_or_else(|| pattern == hostname) for name in &names {
} match ip {
Ok(ip) => {
if let Some(actual) = name.ipaddress() {
if matches_ip(&ip, actual) {
return true;
}
}
}
Err(_) => {
if let Some(pattern) = name.dnsname() {
if matches_dns(pattern, domain) {
return true;
}
}
}
}
}
fn matches_wildcard(pattern: &str, hostname: &str) -> Option<bool> { false
// internationalized domains can't involved in wildcards }
if pattern.starts_with("xn--") {
return None;
}
let wildcard_location = match pattern.find('*') { fn verify_subject_name(domain: &str, subject_name: &X509NameRef) -> bool {
Some(l) => l, match subject_name.entries_by_nid(Nid::COMMONNAME).next() {
None => return None, Some(pattern) => {
}; let pattern = match str::from_utf8(pattern.data().as_slice()) {
Ok(pattern) => pattern,
Err(_) => return false,
};
let mut dot_idxs = pattern.match_indices('.').map(|(l, _)| l); // Unlike SANs, IP addresses in the subject name don't have a
let wildcard_end = match dot_idxs.next() { // different encoding.
Some(l) => l, match domain.parse::<IpAddr>() {
None => return None, Ok(ip) => pattern
}; .parse::<IpAddr>()
.ok()
.map_or(false, |pattern| pattern == ip),
Err(_) => matches_dns(pattern, domain),
}
}
None => false,
}
}
// Never match wildcards if the pattern has less than 2 '.'s (no *.com) fn matches_dns(mut pattern: &str, mut hostname: &str) -> bool {
// // first strip trailing . off of pattern and hostname to normalize
// This is a bit dubious, as it doesn't disallow other TLDs like *.co.uk. if pattern.ends_with('.') {
// Chrome has a black- and white-list for this, but Firefox (via NSS) does pattern = &pattern[..pattern.len() - 1];
// the same thing we do here. }
// if hostname.ends_with('.') {
// The Public Suffix (https://www.publicsuffix.org/) list could hostname = &hostname[..hostname.len() - 1];
// potentially be used here, but it's both huge and updated frequently }
// enough that management would be a PITA.
if dot_idxs.next().is_none() {
return None;
}
// Wildcards can only be in the first component matches_wildcard(pattern, hostname).unwrap_or_else(|| pattern == hostname)
if wildcard_location > wildcard_end { }
return None;
}
let hostname_label_end = match hostname.find('.') { fn matches_wildcard(pattern: &str, hostname: &str) -> Option<bool> {
Some(l) => l, // internationalized domains can't involved in wildcards
None => return None, if pattern.starts_with("xn--") {
}; return None;
}
// check that the non-wildcard parts are identical let wildcard_location = match pattern.find('*') {
if pattern[wildcard_end..] != hostname[hostname_label_end..] { Some(l) => l,
return Some(false); None => return None,
} };
let wildcard_prefix = &pattern[..wildcard_location]; let mut dot_idxs = pattern.match_indices('.').map(|(l, _)| l);
let wildcard_suffix = &pattern[wildcard_location + 1..wildcard_end]; let wildcard_end = match dot_idxs.next() {
Some(l) => l,
None => return None,
};
let hostname_label = &hostname[..hostname_label_end]; // Never match wildcards if the pattern has less than 2 '.'s (no *.com)
//
// This is a bit dubious, as it doesn't disallow other TLDs like *.co.uk.
// Chrome has a black- and white-list for this, but Firefox (via NSS) does
// the same thing we do here.
//
// The Public Suffix (https://www.publicsuffix.org/) list could
// potentially be used here, but it's both huge and updated frequently
// enough that management would be a PITA.
if dot_idxs.next().is_none() {
return None;
}
// check the prefix of the first label // Wildcards can only be in the first component
if !hostname_label.starts_with(wildcard_prefix) { if wildcard_location > wildcard_end {
return Some(false); return None;
} }
// and the suffix let hostname_label_end = match hostname.find('.') {
if !hostname_label[wildcard_prefix.len()..].ends_with(wildcard_suffix) { Some(l) => l,
return Some(false); None => return None,
} };
Some(true) // check that the non-wildcard parts are identical
} if pattern[wildcard_end..] != hostname[hostname_label_end..] {
return Some(false);
}
fn matches_ip(expected: &IpAddr, actual: &[u8]) -> bool { let wildcard_prefix = &pattern[..wildcard_location];
match *expected { let wildcard_suffix = &pattern[wildcard_location + 1..wildcard_end];
IpAddr::V4(ref addr) => actual == addr.octets(),
IpAddr::V6(ref addr) => actual == addr.octets(), let hostname_label = &hostname[..hostname_label_end];
// check the prefix of the first label
if !hostname_label.starts_with(wildcard_prefix) {
return Some(false);
}
// and the suffix
if !hostname_label[wildcard_prefix.len()..].ends_with(wildcard_suffix) {
return Some(false);
}
Some(true)
}
fn matches_ip(expected: &IpAddr, actual: &[u8]) -> bool {
match *expected {
IpAddr::V4(ref addr) => actual == addr.octets(),
IpAddr::V6(ref addr) => actual == addr.octets(),
}
}
} }
} }
} }

View File

@ -78,7 +78,7 @@ use std::str;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use dh::{Dh, DhRef}; use dh::{Dh, DhRef};
#[cfg(any(ossl101, ossl102))] #[cfg(all(ossl101, not(ossl110)))]
use ec::EcKey; use ec::EcKey;
use ec::EcKeyRef; use ec::EcKeyRef;
use error::ErrorStack; use error::ErrorStack;
@ -91,10 +91,10 @@ use ssl::bio::BioMethod;
use ssl::callbacks::*; use ssl::callbacks::*;
use ssl::error::InnerError; use ssl::error::InnerError;
use stack::{Stack, StackRef}; use stack::{Stack, StackRef};
#[cfg(any(ossl102, ossl110))] #[cfg(ossl102)]
use x509::store::X509Store; use x509::store::X509Store;
use x509::store::{X509StoreBuilderRef, X509StoreRef}; use x509::store::{X509StoreBuilderRef, X509StoreRef};
#[cfg(any(ossl102, ossl110))] #[cfg(any(ossl102, libressl261))]
use x509::verify::X509VerifyParamRef; use x509::verify::X509VerifyParamRef;
use x509::{X509, X509Name, X509Ref, X509StoreContextRef, X509VerifyResult}; use x509::{X509, X509Name, X509Ref, X509StoreContextRef, X509VerifyResult};
use {cvt, cvt_n, cvt_p, init}; use {cvt, cvt_n, cvt_p, init};
@ -284,7 +284,7 @@ impl SslMethod {
/// This corresponds to `TLS_method` on OpenSSL 1.1.0 and `SSLv23_method` /// This corresponds to `TLS_method` on OpenSSL 1.1.0 and `SSLv23_method`
/// on OpenSSL 1.0.x. /// on OpenSSL 1.0.x.
pub fn tls() -> SslMethod { pub fn tls() -> SslMethod {
SslMethod(compat::tls_method()) unsafe { SslMethod(TLS_method()) }
} }
/// Support all versions of the DTLS protocol. /// Support all versions of the DTLS protocol.
@ -292,7 +292,7 @@ impl SslMethod {
/// This corresponds to `DTLS_method` on OpenSSL 1.1.0 and `DTLSv1_method` /// This corresponds to `DTLS_method` on OpenSSL 1.1.0 and `DTLSv1_method`
/// on OpenSSL 1.0.x. /// on OpenSSL 1.0.x.
pub fn dtls() -> SslMethod { pub fn dtls() -> SslMethod {
SslMethod(compat::dtls_method()) unsafe { SslMethod(DTLS_method()) }
} }
/// Constructs an `SslMethod` from a pointer to the underlying OpenSSL value. /// Constructs an `SslMethod` from a pointer to the underlying OpenSSL value.
@ -767,7 +767,7 @@ impl SslContextBuilder {
/// Requires OpenSSL 1.0.1 or 1.0.2. /// Requires OpenSSL 1.0.1 or 1.0.2.
/// ///
/// This corresponds to `SSL_CTX_set_tmp_ecdh_callback`. /// This corresponds to `SSL_CTX_set_tmp_ecdh_callback`.
#[cfg(any(ossl101, ossl102))] #[cfg(all(ossl101, not(ossl110)))]
pub fn set_tmp_ecdh_callback<F>(&mut self, callback: F) pub fn set_tmp_ecdh_callback<F>(&mut self, callback: F)
where where
F: Fn(&mut SslRef, bool, u32) -> Result<EcKey<Params>, ErrorStack> + 'static + Sync + Send, F: Fn(&mut SslRef, bool, u32) -> Result<EcKey<Params>, ErrorStack> + 'static + Sync + Send,
@ -976,7 +976,7 @@ impl SslContextBuilder {
/// This corresponds to [`SSL_CTX_set_ecdh_auto`]. /// This corresponds to [`SSL_CTX_set_ecdh_auto`].
/// ///
/// [`SSL_CTX_set_ecdh_auto`]: https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_set_ecdh_auto.html /// [`SSL_CTX_set_ecdh_auto`]: https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_set_ecdh_auto.html
#[cfg(any(ossl102, libressl))] #[cfg(any(libressl, all(ossl102, not(ossl110))))]
pub fn set_ecdh_auto(&mut self, onoff: bool) -> Result<(), ErrorStack> { pub fn set_ecdh_auto(&mut self, onoff: bool) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::SSL_CTX_set_ecdh_auto(self.as_ptr(), onoff as c_int)).map(|_| ()) } unsafe { cvt(ffi::SSL_CTX_set_ecdh_auto(self.as_ptr(), onoff as c_int)).map(|_| ()) }
} }
@ -992,7 +992,7 @@ impl SslContextBuilder {
/// ///
/// [`SSL_CTX_set_options`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_options.html /// [`SSL_CTX_set_options`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_options.html
pub fn set_options(&mut self, option: SslOptions) -> SslOptions { pub fn set_options(&mut self, option: SslOptions) -> SslOptions {
let bits = unsafe { compat::SSL_CTX_set_options(self.as_ptr(), option.bits()) }; let bits = unsafe { ffi::SSL_CTX_set_options(self.as_ptr(), option.bits()) };
SslOptions { bits } SslOptions { bits }
} }
@ -1002,7 +1002,7 @@ impl SslContextBuilder {
/// ///
/// [`SSL_CTX_get_options`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_options.html /// [`SSL_CTX_get_options`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_options.html
pub fn options(&self) -> SslOptions { pub fn options(&self) -> SslOptions {
let bits = unsafe { compat::SSL_CTX_get_options(self.as_ptr()) }; let bits = unsafe { ffi::SSL_CTX_get_options(self.as_ptr()) };
SslOptions { bits } SslOptions { bits }
} }
@ -1012,7 +1012,7 @@ impl SslContextBuilder {
/// ///
/// [`SSL_CTX_clear_options`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_options.html /// [`SSL_CTX_clear_options`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_options.html
pub fn clear_options(&mut self, option: SslOptions) -> SslOptions { pub fn clear_options(&mut self, option: SslOptions) -> SslOptions {
let bits = unsafe { compat::SSL_CTX_clear_options(self.as_ptr(), option.bits()) }; let bits = unsafe { ffi::SSL_CTX_clear_options(self.as_ptr(), option.bits()) };
SslOptions { bits } SslOptions { bits }
} }
@ -1514,7 +1514,7 @@ foreign_type_and_impl_send_sync! {
impl Clone for SslContext { impl Clone for SslContext {
fn clone(&self) -> Self { fn clone(&self) -> Self {
unsafe { unsafe {
compat::SSL_CTX_up_ref(self.as_ptr()); SSL_CTX_up_ref(self.as_ptr());
SslContext::from_ptr(self.as_ptr()) SslContext::from_ptr(self.as_ptr())
} }
} }
@ -1547,7 +1547,7 @@ impl SslContext {
{ {
unsafe { unsafe {
ffi::init(); ffi::init();
let idx = cvt_n(compat::get_new_idx(free_data_box::<T>))?; let idx = cvt_n(get_new_idx(free_data_box::<T>))?;
Ok(Index::from_raw(idx)) Ok(Index::from_raw(idx))
} }
} }
@ -1833,7 +1833,7 @@ impl ToOwned for SslSessionRef {
fn to_owned(&self) -> SslSession { fn to_owned(&self) -> SslSession {
unsafe { unsafe {
compat::SSL_SESSION_up_ref(self.as_ptr()); SSL_SESSION_up_ref(self.as_ptr());
SslSession(self.as_ptr()) SslSession(self.as_ptr())
} }
} }
@ -1859,7 +1859,7 @@ impl SslSessionRef {
/// ///
/// [`SSL_SESSION_get_master_key`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_SESSION_get_master_key.html /// [`SSL_SESSION_get_master_key`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_SESSION_get_master_key.html
pub fn master_key_len(&self) -> usize { pub fn master_key_len(&self) -> usize {
unsafe { compat::SSL_SESSION_get_master_key(self.as_ptr(), ptr::null_mut(), 0) } unsafe { SSL_SESSION_get_master_key(self.as_ptr(), ptr::null_mut(), 0) }
} }
/// Copies the master key into the provided buffer. /// Copies the master key into the provided buffer.
@ -1870,7 +1870,7 @@ impl SslSessionRef {
/// ///
/// [`SSL_SESSION_get_master_key`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_SESSION_get_master_key.html /// [`SSL_SESSION_get_master_key`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_SESSION_get_master_key.html
pub fn master_key(&self, buf: &mut [u8]) -> usize { pub fn master_key(&self, buf: &mut [u8]) -> usize {
unsafe { compat::SSL_SESSION_get_master_key(self.as_ptr(), buf.as_mut_ptr(), buf.len()) } unsafe { SSL_SESSION_get_master_key(self.as_ptr(), buf.as_mut_ptr(), buf.len()) }
} }
to_der! { to_der! {
@ -1926,7 +1926,7 @@ impl Ssl {
{ {
unsafe { unsafe {
ffi::init(); ffi::init();
let idx = cvt_n(compat::get_new_ssl_idx(free_data_box::<T>))?; let idx = cvt_n(get_new_ssl_idx(free_data_box::<T>))?;
Ok(Index::from_raw(idx)) Ok(Index::from_raw(idx))
} }
} }
@ -2091,7 +2091,7 @@ impl SslRef {
/// This corresponds to `SSL_set_tmp_ecdh_callback`. /// This corresponds to `SSL_set_tmp_ecdh_callback`.
/// ///
/// [`SslContextBuilder::set_tmp_ecdh_callback`]: struct.SslContextBuilder.html#method.set_tmp_ecdh_callback /// [`SslContextBuilder::set_tmp_ecdh_callback`]: struct.SslContextBuilder.html#method.set_tmp_ecdh_callback
#[cfg(any(ossl101, ossl102))] #[cfg(any(all(ossl101, not(ossl110))))]
pub fn set_tmp_ecdh_callback<F>(&mut self, callback: F) pub fn set_tmp_ecdh_callback<F>(&mut self, callback: F)
where where
F: Fn(&mut SslRef, bool, u32) -> Result<EcKey<Params>, ErrorStack> + 'static + Sync + Send, F: Fn(&mut SslRef, bool, u32) -> Result<EcKey<Params>, ErrorStack> + 'static + Sync + Send,
@ -2111,7 +2111,7 @@ impl SslRef {
/// ///
/// [`SslContextBuilder::set_tmp_ecdh`]: struct.SslContextBuilder.html#method.set_tmp_ecdh /// [`SslContextBuilder::set_tmp_ecdh`]: struct.SslContextBuilder.html#method.set_tmp_ecdh
/// [`SSL_set_ecdh_auto`]: https://www.openssl.org/docs/man1.0.2/ssl/SSL_set_ecdh_auto.html /// [`SSL_set_ecdh_auto`]: https://www.openssl.org/docs/man1.0.2/ssl/SSL_set_ecdh_auto.html
#[cfg(ossl102)] #[cfg(all(ossl102, not(ossl110)))]
pub fn set_ecdh_auto(&mut self, onoff: bool) -> Result<(), ErrorStack> { pub fn set_ecdh_auto(&mut self, onoff: bool) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::SSL_set_ecdh_auto(self.as_ptr(), onoff as c_int)).map(|_| ()) } unsafe { cvt(ffi::SSL_set_ecdh_auto(self.as_ptr(), onoff as c_int)).map(|_| ()) }
} }
@ -2363,7 +2363,7 @@ impl SslRef {
/// This corresponds to [`SSL_get0_param`]. /// This corresponds to [`SSL_get0_param`].
/// ///
/// [`SSL_get0_param`]: https://www.openssl.org/docs/man1.0.2/ssl/SSL_get0_param.html /// [`SSL_get0_param`]: https://www.openssl.org/docs/man1.0.2/ssl/SSL_get0_param.html
#[cfg(any(ossl102, ossl110))] #[cfg(any(ossl102, libressl261))]
pub fn param_mut(&mut self) -> &mut X509VerifyParamRef { pub fn param_mut(&mut self) -> &mut X509VerifyParamRef {
unsafe { X509VerifyParamRef::from_ptr_mut(ffi::SSL_get0_param(self.as_ptr())) } unsafe { X509VerifyParamRef::from_ptr_mut(ffi::SSL_get0_param(self.as_ptr())) }
} }
@ -2541,7 +2541,7 @@ impl SslRef {
/// ///
/// [`SSL_is_server`]: https://www.openssl.org/docs/manmaster/man3/SSL_is_server.html /// [`SSL_is_server`]: https://www.openssl.org/docs/manmaster/man3/SSL_is_server.html
pub fn is_server(&self) -> bool { pub fn is_server(&self) -> bool {
unsafe { compat::SSL_is_server(self.as_ptr()) != 0 } unsafe { SSL_is_server(self.as_ptr()) != 0 }
} }
/// Sets the extra data at the specified index. /// Sets the extra data at the specified index.
@ -2987,133 +2987,88 @@ pub enum ShutdownResult {
Received, Received,
} }
#[cfg(ossl110)] cfg_if! {
mod compat { if #[cfg(ossl110)] {
use std::ptr; use ffi::{
SSL_CTX_up_ref,
SSL_SESSION_get_master_key, SSL_SESSION_up_ref, SSL_is_server, TLS_method, DTLS_method,
};
use ffi; pub unsafe fn get_new_idx(f: ffi::CRYPTO_EX_free) -> c_int {
use libc::c_int; ffi::CRYPTO_get_ex_new_index(
ffi::CRYPTO_EX_INDEX_SSL_CTX,
0,
ptr::null_mut(),
None,
None,
Some(f),
)
}
pub use ffi::{ pub unsafe fn get_new_ssl_idx(f: ffi::CRYPTO_EX_free) -> c_int {
SSL_CTX_clear_options, SSL_CTX_get_options, SSL_CTX_set_options, SSL_CTX_up_ref, ffi::CRYPTO_get_ex_new_index(
SSL_SESSION_get_master_key, SSL_SESSION_up_ref, SSL_is_server, ffi::CRYPTO_EX_INDEX_SSL,
}; 0,
ptr::null_mut(),
None,
None,
Some(f),
)
}
} else {
use ffi::{SSLv23_method as TLS_method, DTLSv1_method as DTLS_method};
pub unsafe fn get_new_idx(f: ffi::CRYPTO_EX_free) -> c_int { pub unsafe fn get_new_idx(f: ffi::CRYPTO_EX_free) -> c_int {
ffi::CRYPTO_get_ex_new_index( ffi::SSL_CTX_get_ex_new_index(0, ptr::null_mut(), None, None, Some(f))
ffi::CRYPTO_EX_INDEX_SSL_CTX, }
0,
ptr::null_mut(),
None,
None,
Some(f),
)
}
pub unsafe fn get_new_ssl_idx(f: ffi::CRYPTO_EX_free) -> c_int { pub unsafe fn get_new_ssl_idx(f: ffi::CRYPTO_EX_free) -> c_int {
ffi::CRYPTO_get_ex_new_index( ffi::SSL_get_ex_new_index(0, ptr::null_mut(), None, None, Some(f))
ffi::CRYPTO_EX_INDEX_SSL, }
0,
ptr::null_mut(),
None,
None,
Some(f),
)
}
pub fn tls_method() -> *const ffi::SSL_METHOD { #[allow(bad_style)]
unsafe { ffi::TLS_method() } pub unsafe fn SSL_CTX_up_ref(ssl: *mut ffi::SSL_CTX) -> c_int {
} ffi::CRYPTO_add_lock(
&mut (*ssl).references,
1,
ffi::CRYPTO_LOCK_SSL_CTX,
"mod.rs\0".as_ptr() as *const _,
line!() as c_int,
);
0
}
pub fn dtls_method() -> *const ffi::SSL_METHOD { #[allow(bad_style)]
unsafe { ffi::DTLS_method() } pub unsafe fn SSL_SESSION_get_master_key(
} session: *const ffi::SSL_SESSION,
} out: *mut c_uchar,
mut outlen: usize,
#[cfg(ossl10x)] ) -> usize {
#[allow(bad_style)] if outlen == 0 {
mod compat { return (*session).master_key_length as usize;
use std::ptr; }
if outlen > (*session).master_key_length as usize {
use ffi; outlen = (*session).master_key_length as usize;
use libc::{self, c_int, c_long, c_uchar, c_ulong, size_t}; }
ptr::copy_nonoverlapping((*session).master_key.as_ptr(), out, outlen);
pub unsafe fn SSL_CTX_get_options(ctx: *const ffi::SSL_CTX) -> c_ulong { outlen
ffi::SSL_CTX_ctrl(ctx as *mut _, ffi::SSL_CTRL_OPTIONS, 0, ptr::null_mut()) as c_ulong }
}
#[allow(bad_style)]
pub unsafe fn SSL_CTX_set_options(ctx: *const ffi::SSL_CTX, op: c_ulong) -> c_ulong { pub unsafe fn SSL_is_server(s: *mut ffi::SSL) -> c_int {
ffi::SSL_CTX_ctrl( (*s).server
ctx as *mut _, }
ffi::SSL_CTRL_OPTIONS,
op as c_long, #[allow(bad_style)]
ptr::null_mut(), pub unsafe fn SSL_SESSION_up_ref(ses: *mut ffi::SSL_SESSION) -> c_int {
) as c_ulong ffi::CRYPTO_add_lock(
} &mut (*ses).references,
1,
pub unsafe fn SSL_CTX_clear_options(ctx: *const ffi::SSL_CTX, op: c_ulong) -> c_ulong { ffi::CRYPTO_LOCK_SSL_CTX,
ffi::SSL_CTX_ctrl( "mod.rs\0".as_ptr() as *const _,
ctx as *mut _, line!() as c_int,
ffi::SSL_CTRL_CLEAR_OPTIONS, );
op as c_long, 0
ptr::null_mut(), }
) as c_ulong
}
pub unsafe fn get_new_idx(f: ffi::CRYPTO_EX_free) -> c_int {
ffi::SSL_CTX_get_ex_new_index(0, ptr::null_mut(), None, None, Some(f))
}
pub unsafe fn get_new_ssl_idx(f: ffi::CRYPTO_EX_free) -> c_int {
ffi::SSL_get_ex_new_index(0, ptr::null_mut(), None, None, Some(f))
}
pub unsafe fn SSL_CTX_up_ref(ssl: *mut ffi::SSL_CTX) -> libc::c_int {
ffi::CRYPTO_add_lock(
&mut (*ssl).references,
1,
ffi::CRYPTO_LOCK_SSL_CTX,
"mod.rs\0".as_ptr() as *const _,
line!() as libc::c_int,
);
0
}
pub unsafe fn SSL_SESSION_get_master_key(
session: *const ffi::SSL_SESSION,
out: *mut c_uchar,
mut outlen: size_t,
) -> size_t {
if outlen == 0 {
return (*session).master_key_length as size_t;
}
if outlen > (*session).master_key_length as size_t {
outlen = (*session).master_key_length as size_t;
}
ptr::copy_nonoverlapping((*session).master_key.as_ptr(), out, outlen);
outlen
}
pub fn tls_method() -> *const ffi::SSL_METHOD {
unsafe { ffi::SSLv23_method() }
}
pub fn dtls_method() -> *const ffi::SSL_METHOD {
unsafe { ffi::DTLSv1_method() }
}
pub unsafe fn SSL_is_server(s: *mut ffi::SSL) -> c_int {
(*s).server
}
pub unsafe fn SSL_SESSION_up_ref(ses: *mut ffi::SSL_SESSION) -> c_int {
ffi::CRYPTO_add_lock(
&mut (*ses).references,
1,
ffi::CRYPTO_LOCK_SSL_CTX,
"mod.rs\0".as_ptr() as *const _,
line!() as libc::c_int,
);
0
} }
} }

View File

@ -1063,7 +1063,7 @@ fn tmp_dh_callback() {
} }
#[test] #[test]
#[cfg(any(all(ossl101, not(libressl)), ossl102))] #[cfg(all(ossl101, not(ossl110)))]
fn tmp_ecdh_callback() { fn tmp_ecdh_callback() {
use ec::EcKey; use ec::EcKey;
use nid::Nid; use nid::Nid;
@ -1137,7 +1137,7 @@ fn tmp_dh_callback_ssl() {
} }
#[test] #[test]
#[cfg(any(all(ossl101, not(libressl)), ossl102))] #[cfg(all(ossl101, not(ossl110)))]
fn tmp_ecdh_callback_ssl() { fn tmp_ecdh_callback_ssl() {
use ec::EcKey; use ec::EcKey;
use nid::Nid; use nid::Nid;

View File

@ -1,23 +1,30 @@
use foreign_types::{ForeignTypeRef, ForeignType, Opaque}; use ffi;
use foreign_types::{ForeignType, ForeignTypeRef, Opaque};
use libc::c_int; use libc::c_int;
use std::borrow::Borrow; use std::borrow::Borrow;
use std::convert::AsRef; use std::convert::AsRef;
use std::iter; use std::iter;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::mem; use std::mem;
use ffi;
use {cvt, cvt_p};
use error::ErrorStack; use error::ErrorStack;
use std::ops::{Deref, DerefMut, Index, IndexMut}; use std::ops::{Deref, DerefMut, Index, IndexMut};
use {cvt, cvt_p};
#[cfg(ossl10x)] cfg_if! {
use ffi::{sk_pop as OPENSSL_sk_pop, sk_free as OPENSSL_sk_free, sk_num as OPENSSL_sk_num, if #[cfg(ossl110)] {
sk_value as OPENSSL_sk_value, _STACK as OPENSSL_STACK, use ffi::{
sk_new_null as OPENSSL_sk_new_null, sk_push as OPENSSL_sk_push}; OPENSSL_sk_pop, OPENSSL_sk_free, OPENSSL_sk_num, OPENSSL_sk_value, OPENSSL_STACK,
#[cfg(ossl110)] OPENSSL_sk_new_null, OPENSSL_sk_push,
use ffi::{OPENSSL_sk_pop, OPENSSL_sk_free, OPENSSL_sk_num, OPENSSL_sk_value, OPENSSL_STACK, };
OPENSSL_sk_new_null, OPENSSL_sk_push}; } else {
use ffi::{
sk_pop as OPENSSL_sk_pop, sk_free as OPENSSL_sk_free, sk_num as OPENSSL_sk_num,
sk_value as OPENSSL_sk_value, _STACK as OPENSSL_STACK,
sk_new_null as OPENSSL_sk_new_null, sk_push as OPENSSL_sk_push,
};
}
}
/// Trait implemented by types which can be placed in a stack. /// Trait implemented by types which can be placed in a stack.
/// ///
@ -87,7 +94,7 @@ impl<T: Stackable> ForeignType for Stack<T> {
assert!( assert!(
!ptr.is_null(), !ptr.is_null(),
"Must not instantiate a Stack from a null-ptr - use Stack::new() in \ "Must not instantiate a Stack from a null-ptr - use Stack::new() in \
that case" that case"
); );
Stack(ptr) Stack(ptr)
} }
@ -218,9 +225,7 @@ impl<T: Stackable> StackRef<T> {
/// Pushes a value onto the top of the stack. /// Pushes a value onto the top of the stack.
pub fn push(&mut self, data: T) -> Result<(), ErrorStack> { pub fn push(&mut self, data: T) -> Result<(), ErrorStack> {
unsafe { unsafe {
cvt( cvt(OPENSSL_sk_push(self.as_stack(), data.as_ptr() as *mut _))?;
OPENSSL_sk_push(self.as_stack(), data.as_ptr() as *mut _),
)?;
mem::forget(data); mem::forget(data);
Ok(()) Ok(())
} }

View File

@ -52,14 +52,14 @@
//! println!("Decrypted: '{}'", output_string); //! println!("Decrypted: '{}'", output_string);
//! ``` //! ```
use ffi;
use libc::c_int;
use std::cmp; use std::cmp;
use std::ptr; use std::ptr;
use libc::c_int;
use ffi;
use {cvt, cvt_p};
use error::ErrorStack; use error::ErrorStack;
use nid::Nid; use nid::Nid;
use {cvt, cvt_p};
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub enum Mode { pub enum Mode {
@ -718,34 +718,31 @@ pub fn decrypt_aead(
Ok(out) Ok(out)
} }
#[cfg(ossl110)] cfg_if! {
use ffi::{EVP_CIPHER_block_size, EVP_CIPHER_iv_length, EVP_CIPHER_key_length}; if #[cfg(ossl110)] {
use ffi::{EVP_CIPHER_block_size, EVP_CIPHER_iv_length, EVP_CIPHER_key_length};
} else {
#[allow(bad_style)]
pub unsafe fn EVP_CIPHER_iv_length(ptr: *const ffi::EVP_CIPHER) -> c_int {
(*ptr).iv_len
}
#[cfg(ossl10x)] #[allow(bad_style)]
#[allow(bad_style)] pub unsafe fn EVP_CIPHER_block_size(ptr: *const ffi::EVP_CIPHER) -> c_int {
mod compat { (*ptr).block_size
use libc::c_int; }
use ffi::EVP_CIPHER;
pub unsafe fn EVP_CIPHER_iv_length(ptr: *const EVP_CIPHER) -> c_int { #[allow(bad_style)]
(*ptr).iv_len pub unsafe fn EVP_CIPHER_key_length(ptr: *const ffi::EVP_CIPHER) -> c_int {
} (*ptr).key_len
}
pub unsafe fn EVP_CIPHER_block_size(ptr: *const EVP_CIPHER) -> c_int {
(*ptr).block_size
}
pub unsafe fn EVP_CIPHER_key_length(ptr: *const EVP_CIPHER) -> c_int {
(*ptr).key_len
} }
} }
#[cfg(ossl10x)]
use self::compat::*;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use hex::{self, FromHex};
use super::*; use super::*;
use hex::{self, FromHex};
// Test vectors from FIPS-197: // Test vectors from FIPS-197:
// http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf // http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf

View File

@ -13,15 +13,21 @@
use std::ffi::CStr; use std::ffi::CStr;
#[cfg(ossl10x)] cfg_if! {
use ffi::{SSLEAY_VERSION as OPENSSL_VERSION, SSLEAY_CFLAGS as OPENSSL_CFLAGS, if #[cfg(ossl110)] {
SSLEAY_BUILT_ON as OPENSSL_BUILT_ON, SSLEAY_PLATFORM as OPENSSL_PLATFORM, use ffi::{
SSLEAY_DIR as OPENSSL_DIR, SSLeay as OpenSSL_version_num, OPENSSL_VERSION, OPENSSL_CFLAGS, OPENSSL_BUILT_ON, OPENSSL_PLATFORM, OPENSSL_DIR,
SSLeay_version as OpenSSL_version}; OpenSSL_version_num, OpenSSL_version,
};
#[cfg(ossl110)] } else {
use ffi::{OPENSSL_VERSION, OPENSSL_CFLAGS, OPENSSL_BUILT_ON, OPENSSL_PLATFORM, OPENSSL_DIR, use ffi::{
OpenSSL_version_num, OpenSSL_version}; SSLEAY_VERSION as OPENSSL_VERSION, SSLEAY_CFLAGS as OPENSSL_CFLAGS,
SSLEAY_BUILT_ON as OPENSSL_BUILT_ON, SSLEAY_PLATFORM as OPENSSL_PLATFORM,
SSLEAY_DIR as OPENSSL_DIR, SSLeay as OpenSSL_version_num,
SSLeay_version as OpenSSL_version,
};
}
}
/// OPENSSL_VERSION_NUMBER is a numeric release version identifier: /// OPENSSL_VERSION_NUMBER is a numeric release version identifier:
/// ///
@ -51,7 +57,6 @@ pub fn number() -> i64 {
unsafe { OpenSSL_version_num() as i64 } unsafe { OpenSSL_version_num() as i64 }
} }
/// The text variant of the version number and the release date. For example, "OpenSSL 0.9.5a 1 Apr 2000". /// The text variant of the version number and the release date. For example, "OpenSSL 0.9.5a 1 Apr 2000".
pub fn version() -> &'static str { pub fn version() -> &'static str {
unsafe { unsafe {

View File

@ -7,9 +7,9 @@
//! Internet protocols, including SSL/TLS, which is the basis for HTTPS, //! Internet protocols, including SSL/TLS, which is the basis for HTTPS,
//! the secure protocol for browsing the web. //! the secure protocol for browsing the web.
use libc::{c_int, c_long};
use ffi; use ffi;
use foreign_types::{ForeignType, ForeignTypeRef}; use foreign_types::{ForeignType, ForeignTypeRef};
use libc::{c_int, c_long};
use std::error::Error; use std::error::Error;
use std::ffi::{CStr, CString}; use std::ffi::{CStr, CString};
use std::fmt; use std::fmt;
@ -20,7 +20,6 @@ use std::ptr;
use std::slice; use std::slice;
use std::str; use std::str;
use {cvt, cvt_n, cvt_p};
use asn1::{Asn1BitStringRef, Asn1IntegerRef, Asn1ObjectRef, Asn1StringRef, Asn1TimeRef}; use asn1::{Asn1BitStringRef, Asn1IntegerRef, Asn1ObjectRef, Asn1StringRef, Asn1TimeRef};
use bio::MemBioSlice; use bio::MemBioSlice;
use conf::ConfRef; use conf::ConfRef;
@ -29,18 +28,12 @@ use ex_data::Index;
use hash::MessageDigest; use hash::MessageDigest;
use nid::Nid; use nid::Nid;
use pkey::{HasPrivate, HasPublic, PKey, PKeyRef, Public}; use pkey::{HasPrivate, HasPublic, PKey, PKeyRef, Public};
use ssl::SslRef;
use stack::{Stack, StackRef, Stackable}; use stack::{Stack, StackRef, Stackable};
use string::OpensslString; use string::OpensslString;
use ssl::SslRef; use {cvt, cvt_n, cvt_p};
#[cfg(ossl10x)] #[cfg(any(ossl102, libressl261))]
use ffi::{ASN1_STRING_data, X509_STORE_CTX_get_chain, X509_set_notAfter, X509_set_notBefore};
#[cfg(ossl110)]
use ffi::{ASN1_STRING_get0_data as ASN1_STRING_data,
X509_STORE_CTX_get0_chain as X509_STORE_CTX_get_chain,
X509_set1_notAfter as X509_set_notAfter, X509_set1_notBefore as X509_set_notBefore};
#[cfg(any(ossl102, ossl110))]
pub mod verify; pub mod verify;
pub mod extension; pub mod extension;
@ -215,7 +208,7 @@ impl X509StoreContextRef {
/// [`X509_STORE_CTX_get0_chain`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_STORE_CTX_get0_chain.html /// [`X509_STORE_CTX_get0_chain`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_STORE_CTX_get0_chain.html
pub fn chain(&self) -> Option<&StackRef<X509>> { pub fn chain(&self) -> Option<&StackRef<X509>> {
unsafe { unsafe {
let chain = X509_STORE_CTX_get_chain(self.as_ptr()); let chain = X509_STORE_CTX_get0_chain(self.as_ptr());
if chain.is_null() { if chain.is_null() {
None None
@ -240,12 +233,12 @@ impl X509Builder {
/// Sets the notAfter constraint on the certificate. /// Sets the notAfter constraint on the certificate.
pub fn set_not_after(&mut self, not_after: &Asn1TimeRef) -> Result<(), ErrorStack> { pub fn set_not_after(&mut self, not_after: &Asn1TimeRef) -> Result<(), ErrorStack> {
unsafe { cvt(X509_set_notAfter(self.0.as_ptr(), not_after.as_ptr())).map(|_| ()) } unsafe { cvt(X509_set1_notAfter(self.0.as_ptr(), not_after.as_ptr())).map(|_| ()) }
} }
/// Sets the notBefore constraint on the certificate. /// Sets the notBefore constraint on the certificate.
pub fn set_not_before(&mut self, not_before: &Asn1TimeRef) -> Result<(), ErrorStack> { pub fn set_not_before(&mut self, not_before: &Asn1TimeRef) -> Result<(), ErrorStack> {
unsafe { cvt(X509_set_notBefore(self.0.as_ptr(), not_before.as_ptr())).map(|_| ()) } unsafe { cvt(X509_set1_notBefore(self.0.as_ptr(), not_before.as_ptr())).map(|_| ()) }
} }
/// Sets the version of the certificate. /// Sets the version of the certificate.
@ -474,7 +467,7 @@ impl X509Ref {
/// Returns the certificate's Not After validity period. /// Returns the certificate's Not After validity period.
pub fn not_after(&self) -> &Asn1TimeRef { pub fn not_after(&self) -> &Asn1TimeRef {
unsafe { unsafe {
let date = compat::X509_get_notAfter(self.as_ptr()); let date = X509_getm_notAfter(self.as_ptr());
assert!(!date.is_null()); assert!(!date.is_null());
Asn1TimeRef::from_ptr(date) Asn1TimeRef::from_ptr(date)
} }
@ -483,7 +476,7 @@ impl X509Ref {
/// Returns the certificate's Not Before validity period. /// Returns the certificate's Not Before validity period.
pub fn not_before(&self) -> &Asn1TimeRef { pub fn not_before(&self) -> &Asn1TimeRef {
unsafe { unsafe {
let date = compat::X509_get_notBefore(self.as_ptr()); let date = X509_getm_notBefore(self.as_ptr());
assert!(!date.is_null()); assert!(!date.is_null());
Asn1TimeRef::from_ptr(date) Asn1TimeRef::from_ptr(date)
} }
@ -493,7 +486,7 @@ impl X509Ref {
pub fn signature(&self) -> &Asn1BitStringRef { pub fn signature(&self) -> &Asn1BitStringRef {
unsafe { unsafe {
let mut signature = ptr::null(); let mut signature = ptr::null();
compat::X509_get0_signature(&mut signature, ptr::null_mut(), self.as_ptr()); X509_get0_signature(&mut signature, ptr::null_mut(), self.as_ptr());
assert!(!signature.is_null()); assert!(!signature.is_null());
Asn1BitStringRef::from_ptr(signature as *mut _) Asn1BitStringRef::from_ptr(signature as *mut _)
} }
@ -503,7 +496,7 @@ impl X509Ref {
pub fn signature_algorithm(&self) -> &X509AlgorithmRef { pub fn signature_algorithm(&self) -> &X509AlgorithmRef {
unsafe { unsafe {
let mut algor = ptr::null(); let mut algor = ptr::null();
compat::X509_get0_signature(ptr::null_mut(), &mut algor, self.as_ptr()); X509_get0_signature(ptr::null_mut(), &mut algor, self.as_ptr());
assert!(!algor.is_null()); assert!(!algor.is_null());
X509AlgorithmRef::from_ptr(algor as *mut _) X509AlgorithmRef::from_ptr(algor as *mut _)
} }
@ -564,7 +557,7 @@ impl ToOwned for X509Ref {
fn to_owned(&self) -> X509 { fn to_owned(&self) -> X509 {
unsafe { unsafe {
compat::X509_up_ref(self.as_ptr()); X509_up_ref(self.as_ptr());
X509::from_ptr(self.as_ptr()) X509::from_ptr(self.as_ptr())
} }
} }
@ -1054,7 +1047,7 @@ impl X509ReqRef {
/// ///
/// [`X509_REQ_get_version`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_REQ_get_version.html /// [`X509_REQ_get_version`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_REQ_get_version.html
pub fn version(&self) -> i32 { pub fn version(&self) -> i32 {
unsafe { compat::X509_REQ_get_version(self.as_ptr()) as i32 } unsafe { X509_REQ_get_version(self.as_ptr()) as i32 }
} }
/// Returns the subject name of the certificate request. /// Returns the subject name of the certificate request.
@ -1064,7 +1057,7 @@ impl X509ReqRef {
/// [`X509_REQ_get_subject_name`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_REQ_get_subject_name.html /// [`X509_REQ_get_subject_name`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_REQ_get_subject_name.html
pub fn subject_name(&self) -> &X509NameRef { pub fn subject_name(&self) -> &X509NameRef {
unsafe { unsafe {
let name = compat::X509_REQ_get_subject_name(self.as_ptr()); let name = X509_REQ_get_subject_name(self.as_ptr());
assert!(!name.is_null()); assert!(!name.is_null());
X509NameRef::from_ptr(name) X509NameRef::from_ptr(name)
} }
@ -1172,7 +1165,7 @@ impl GeneralNameRef {
return None; return None;
} }
let ptr = ASN1_STRING_data((*self.as_ptr()).d as *mut _); let ptr = ASN1_STRING_get0_data((*self.as_ptr()).d as *mut _);
let len = ffi::ASN1_STRING_length((*self.as_ptr()).d as *mut _); let len = ffi::ASN1_STRING_length((*self.as_ptr()).d as *mut _);
let slice = slice::from_raw_parts(ptr as *const u8, len as usize); let slice = slice::from_raw_parts(ptr as *const u8, len as usize);
@ -1205,7 +1198,7 @@ impl GeneralNameRef {
return None; return None;
} }
let ptr = ASN1_STRING_data((*self.as_ptr()).d as *mut _); let ptr = ASN1_STRING_get0_data((*self.as_ptr()).d as *mut _);
let len = ffi::ASN1_STRING_length((*self.as_ptr()).d as *mut _); let len = ffi::ASN1_STRING_length((*self.as_ptr()).d as *mut _);
Some(slice::from_raw_parts(ptr as *const u8, len as usize)) Some(slice::from_raw_parts(ptr as *const u8, len as usize))
@ -1232,79 +1225,86 @@ impl X509AlgorithmRef {
pub fn object(&self) -> &Asn1ObjectRef { pub fn object(&self) -> &Asn1ObjectRef {
unsafe { unsafe {
let mut oid = ptr::null(); let mut oid = ptr::null();
compat::X509_ALGOR_get0(&mut oid, ptr::null_mut(), ptr::null_mut(), self.as_ptr()); X509_ALGOR_get0(&mut oid, ptr::null_mut(), ptr::null_mut(), self.as_ptr());
assert!(!oid.is_null()); assert!(!oid.is_null());
Asn1ObjectRef::from_ptr(oid as *mut _) Asn1ObjectRef::from_ptr(oid as *mut _)
} }
} }
} }
#[cfg(ossl110)] cfg_if! {
mod compat { if #[cfg(ossl110)] {
pub use ffi::X509_getm_notAfter as X509_get_notAfter; use ffi::{
pub use ffi::X509_getm_notBefore as X509_get_notBefore; X509_ALGOR_get0, X509_REQ_get_subject_name, X509_REQ_get_version,
pub use ffi::X509_up_ref; X509_get0_signature, X509_getm_notAfter, X509_getm_notBefore, X509_up_ref,
pub use ffi::X509_REQ_get_version; ASN1_STRING_get0_data, X509_STORE_CTX_get0_chain, X509_set1_notAfter,
pub use ffi::X509_REQ_get_subject_name; X509_set1_notBefore,
pub use ffi::X509_get0_signature; };
pub use ffi::X509_ALGOR_get0; } else {
} use ffi::{
ASN1_STRING_data as ASN1_STRING_get0_data,
X509_STORE_CTX_get_chain as X509_STORE_CTX_get0_chain,
X509_set_notAfter as X509_set1_notAfter,
X509_set_notBefore as X509_set1_notBefore,
};
#[cfg(ossl10x)] #[allow(bad_style)]
#[allow(bad_style)] unsafe fn X509_getm_notAfter(x: *mut ffi::X509) -> *mut ffi::ASN1_TIME {
mod compat { (*(*(*x).cert_info).validity).notAfter
use libc::{c_int, c_void};
use ffi;
pub unsafe fn X509_get_notAfter(x: *mut ffi::X509) -> *mut ffi::ASN1_TIME {
(*(*(*x).cert_info).validity).notAfter
}
pub unsafe fn X509_get_notBefore(x: *mut ffi::X509) -> *mut ffi::ASN1_TIME {
(*(*(*x).cert_info).validity).notBefore
}
pub unsafe fn X509_up_ref(x: *mut ffi::X509) {
ffi::CRYPTO_add_lock(
&mut (*x).references,
1,
ffi::CRYPTO_LOCK_X509,
"mod.rs\0".as_ptr() as *const _,
line!() as c_int,
);
}
pub unsafe fn X509_REQ_get_version(x: *mut ffi::X509_REQ) -> ::libc::c_long {
::ffi::ASN1_INTEGER_get((*(*x).req_info).version)
}
pub unsafe fn X509_REQ_get_subject_name(x: *mut ffi::X509_REQ) -> *mut ::ffi::X509_NAME {
(*(*x).req_info).subject
}
pub unsafe fn X509_get0_signature(
psig: *mut *const ffi::ASN1_BIT_STRING,
palg: *mut *const ffi::X509_ALGOR,
x: *const ffi::X509,
) {
if !psig.is_null() {
*psig = (*x).signature;
} }
if !palg.is_null() {
*palg = (*x).sig_alg;
}
}
pub unsafe fn X509_ALGOR_get0( #[allow(bad_style)]
paobj: *mut *const ffi::ASN1_OBJECT, unsafe fn X509_getm_notBefore(x: *mut ffi::X509) -> *mut ffi::ASN1_TIME {
pptype: *mut c_int, (*(*(*x).cert_info).validity).notBefore
pval: *mut *mut c_void, }
alg: *const ffi::X509_ALGOR,
) { #[allow(bad_style)]
if !paobj.is_null() { unsafe fn X509_up_ref(x: *mut ffi::X509) {
*paobj = (*alg).algorithm; ffi::CRYPTO_add_lock(
&mut (*x).references,
1,
ffi::CRYPTO_LOCK_X509,
"mod.rs\0".as_ptr() as *const _,
line!() as c_int,
);
}
#[allow(bad_style)]
unsafe fn X509_REQ_get_version(x: *mut ffi::X509_REQ) -> ::libc::c_long {
ffi::ASN1_INTEGER_get((*(*x).req_info).version)
}
#[allow(bad_style)]
unsafe fn X509_REQ_get_subject_name(x: *mut ffi::X509_REQ) -> *mut ::ffi::X509_NAME {
(*(*x).req_info).subject
}
#[allow(bad_style)]
unsafe fn X509_get0_signature(
psig: *mut *const ffi::ASN1_BIT_STRING,
palg: *mut *const ffi::X509_ALGOR,
x: *const ffi::X509,
) {
if !psig.is_null() {
*psig = (*x).signature;
}
if !palg.is_null() {
*palg = (*x).sig_alg;
}
}
#[allow(bad_style)]
unsafe fn X509_ALGOR_get0(
paobj: *mut *const ffi::ASN1_OBJECT,
pptype: *mut c_int,
pval: *mut *mut ::libc::c_void,
alg: *const ffi::X509_ALGOR,
) {
if !paobj.is_null() {
*paobj = (*alg).algorithm;
}
assert!(pptype.is_null());
assert!(pval.is_null());
} }
assert!(pptype.is_null());
assert!(pval.is_null());
} }
} }

View File

@ -1,6 +1,6 @@
use libc::c_uint;
use ffi; use ffi;
use foreign_types::ForeignTypeRef; use foreign_types::ForeignTypeRef;
use libc::c_uint;
use std::net::IpAddr; use std::net::IpAddr;
use cvt; use cvt;