commit
58c4688031
|
|
@ -1748,6 +1748,10 @@ extern {
|
|||
inbuf: *const c_uchar, inlen: c_uint,
|
||||
client: *const c_uchar, client_len: c_uint) -> c_int;
|
||||
pub fn SSL_get0_next_proto_negotiated(s: *const SSL, data: *mut *const c_uchar, len: *mut c_uint);
|
||||
pub fn SSL_get_session(s: *const SSL) -> *mut SSL_SESSION;
|
||||
|
||||
pub fn SSL_SESSION_free(s: *mut SSL_SESSION);
|
||||
pub fn SSL_SESSION_get_id(s: *const SSL_SESSION, len: *mut c_uint) -> *const c_uchar;
|
||||
|
||||
#[cfg(not(ossl101))]
|
||||
pub fn SSL_CTX_set_alpn_protos(s: *mut SSL_CTX, data: *const c_uchar, len: c_uint) -> c_int;
|
||||
|
|
|
|||
|
|
@ -358,6 +358,38 @@ pub struct SSL_CTX {
|
|||
srtp_profiles: *mut c_void,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct SSL_SESSION {
|
||||
ssl_version: c_int,
|
||||
pub master_key_length: c_int,
|
||||
pub master_key: [c_uchar; 48],
|
||||
session_id_length: c_uint,
|
||||
session_id: [c_uchar; SSL_MAX_SSL_SESSION_ID_LENGTH as usize],
|
||||
sid_ctx_length: c_uint,
|
||||
sid_ctx: [c_uchar; SSL_MAX_SID_CTX_LENGTH as usize],
|
||||
not_resumable: c_int,
|
||||
sess_cert: *mut c_void,
|
||||
peer: *mut X509,
|
||||
verify_result: c_long,
|
||||
timeout: c_long,
|
||||
time: time_t,
|
||||
references: c_int,
|
||||
cipher: *const c_void,
|
||||
cipher_id: c_ulong,
|
||||
ciphers: *mut c_void,
|
||||
ex_data: ::CRYPTO_EX_DATA,
|
||||
prev: *mut c_void,
|
||||
next: *mut c_void,
|
||||
tlsext_hostname: *mut c_char,
|
||||
tlsext_ecpointformatlist_length: size_t,
|
||||
tlsext_ecpointformatlist: *mut u8,
|
||||
tlsext_ellipticcurvelist_length: size_t,
|
||||
tlsext_ellipticcurvelist: *mut u16,
|
||||
tlsext_tick: *mut c_uchar,
|
||||
tlsext_ticklen: size_t,
|
||||
tlsext_tick_lifetime_hint: c_long,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct X509_VERIFY_PARAM {
|
||||
pub name: *mut c_char,
|
||||
|
|
@ -393,6 +425,10 @@ pub const SSL_OP_SINGLE_ECDH_USE: c_ulong = 0x00080000;
|
|||
pub const SSL_OP_SINGLE_DH_USE: c_ulong = 0x00100000;
|
||||
pub const SSL_OP_NO_SSLv2: c_ulong = 0x0;
|
||||
|
||||
pub const SSL_MAX_SSL_SESSION_ID_LENGTH: c_int = 32;
|
||||
pub const SSL_MAX_SID_CTX_LENGTH: c_int = 32;
|
||||
pub const SSL_MAX_MASTER_KEY_LENGTH: c_int = 48;
|
||||
|
||||
pub const SSLEAY_VERSION : c_int = 0;
|
||||
pub const SSLEAY_CFLAGS : c_int = 2;
|
||||
pub const SSLEAY_BUILT_ON : c_int = 3;
|
||||
|
|
|
|||
|
|
@ -417,6 +417,59 @@ pub struct SSL_CTX {
|
|||
tlsext_ellipticcurvelist: *mut c_uchar,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct SSL_SESSION {
|
||||
ssl_version: c_int,
|
||||
key_arg_length: c_uint,
|
||||
key_arg: [c_uchar; SSL_MAX_KEY_ARG_LENGTH as usize],
|
||||
pub master_key_length: c_int,
|
||||
pub master_key: [c_uchar; 48],
|
||||
session_id_length: c_uint,
|
||||
session_id: [c_uchar; SSL_MAX_SSL_SESSION_ID_LENGTH as usize],
|
||||
sid_ctx_length: c_uint,
|
||||
sid_ctx: [c_uchar; SSL_MAX_SID_CTX_LENGTH as usize],
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_KRB5"))]
|
||||
krb5_client_princ_len: c_uint,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_KRB5"))]
|
||||
krb5_client_princ: [c_uchar; SSL_MAX_KRB5_PRINCIPAL_LENGTH as usize],
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
|
||||
psk_identity_hint: *mut c_char,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
|
||||
psk_identity: *mut c_char,
|
||||
not_resumable: c_int,
|
||||
sess_cert: *mut c_void,
|
||||
peer: *mut X509,
|
||||
verify_result: c_long,
|
||||
references: c_int,
|
||||
timeout: c_long,
|
||||
time: c_long,
|
||||
compress_meth: c_uint,
|
||||
cipher: *const c_void,
|
||||
cipher_id: c_ulong,
|
||||
ciphers: *mut c_void,
|
||||
ex_data: ::CRYPTO_EX_DATA,
|
||||
prev: *mut c_void,
|
||||
next: *mut c_void,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_hostname: *mut c_char,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC")))]
|
||||
tlsext_ecpointformatlist_length: size_t,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC")))]
|
||||
tlsext_ecpointformatlist: *mut c_uchar,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC")))]
|
||||
tlsext_ellipticcurvelist_length: size_t,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC")))]
|
||||
tlsext_ellipticcurvelist: *mut c_uchar,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_tick: *mut c_uchar,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_ticklen: size_t,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))]
|
||||
tlsext_tick_lifetime_hint: c_long,
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_SRP"))]
|
||||
srp_username: *mut c_char,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct SRP_CTX {
|
||||
SRP_cb_arg: *mut c_void,
|
||||
|
|
@ -470,6 +523,12 @@ pub const SSL_OP_SINGLE_ECDH_USE: c_ulong = 0x00080000;
|
|||
pub const SSL_OP_SINGLE_DH_USE: c_ulong = 0x00100000;
|
||||
pub const SSL_OP_NO_SSLv2: c_ulong = 0x01000000;
|
||||
|
||||
pub const SSL_MAX_SSL_SESSION_ID_LENGTH: c_int = 32;
|
||||
pub const SSL_MAX_SID_CTX_LENGTH: c_int = 32;
|
||||
pub const SSL_MAX_KEY_ARG_LENGTH: c_int = 8;
|
||||
pub const SSL_MAX_MASTER_KEY_LENGTH: c_int = 48;
|
||||
pub const SSL_MAX_KRB5_PRINCIPAL_LENGTH: c_int = 256;
|
||||
|
||||
pub const SSLEAY_VERSION : c_int = 0;
|
||||
pub const SSLEAY_CFLAGS : c_int = 2;
|
||||
pub const SSLEAY_BUILT_ON : c_int = 3;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use libc::{c_int, c_void, c_char, c_uchar, c_ulong, c_long, c_uint};
|
||||
use libc::{c_int, c_void, c_char, c_uchar, c_ulong, c_long, c_uint, size_t};
|
||||
|
||||
pub enum BIGNUM {}
|
||||
pub enum BIO {}
|
||||
|
|
@ -13,6 +13,7 @@ pub enum HMAC_CTX {}
|
|||
pub enum OPENSSL_STACK {}
|
||||
pub enum RSA {}
|
||||
pub enum SSL_CTX {}
|
||||
pub enum SSL_SESSION {}
|
||||
pub enum stack_st_ASN1_OBJECT {}
|
||||
pub enum stack_st_GENERAL_NAME {}
|
||||
pub enum stack_st_OPENSSL_STRING {}
|
||||
|
|
@ -155,6 +156,10 @@ extern {
|
|||
-> c_int;
|
||||
pub fn X509_up_ref(x: *mut X509) -> c_int;
|
||||
pub fn SSL_CTX_up_ref(x: *mut SSL_CTX) -> c_int;
|
||||
pub fn SSL_SESSION_get_master_key(session: *const SSL_SESSION,
|
||||
out: *mut c_uchar,
|
||||
outlen: size_t)
|
||||
-> size_t;
|
||||
pub fn X509_get0_extensions(req: *const ::X509) -> *const stack_st_X509_EXTENSION;
|
||||
pub fn X509_STORE_CTX_get0_chain(ctx: *mut ::X509_STORE_CTX) -> *mut stack_st_X509;
|
||||
pub fn EVP_MD_CTX_new() -> *mut EVP_MD_CTX;
|
||||
|
|
|
|||
|
|
@ -1029,6 +1029,31 @@ impl SslCipherRef {
|
|||
}
|
||||
}
|
||||
|
||||
type_!(SslSession, SslSessionRef, ffi::SSL_SESSION, ffi::SSL_SESSION_free);
|
||||
|
||||
impl SslSessionRef {
|
||||
/// Returns the SSL session ID.
|
||||
pub fn id(&self) -> &[u8] {
|
||||
unsafe {
|
||||
let mut len = 0;
|
||||
let p = ffi::SSL_SESSION_get_id(self.as_ptr(), &mut len);
|
||||
slice::from_raw_parts(p as *const u8, len as usize)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the length of the master key.
|
||||
pub fn master_key_len(&self) -> usize {
|
||||
unsafe { compat::SSL_SESSION_get_master_key(self.as_ptr(), ptr::null_mut(), 0) }
|
||||
}
|
||||
|
||||
/// Copies the master key into the provided buffer.
|
||||
///
|
||||
/// Returns the number of bytes written.
|
||||
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()) }
|
||||
}
|
||||
}
|
||||
|
||||
type_!(Ssl, SslRef, ffi::SSL, ffi::SSL_free);
|
||||
|
||||
impl fmt::Debug for SslRef {
|
||||
|
|
@ -1334,6 +1359,18 @@ impl SslRef {
|
|||
pub fn verify_result(&self) -> Option<X509VerifyError> {
|
||||
unsafe { X509VerifyError::from_raw(ffi::SSL_get_verify_result(self.as_ptr())) }
|
||||
}
|
||||
|
||||
/// Returns the SSL session.
|
||||
pub fn session(&self) -> Option<&SslSessionRef> {
|
||||
unsafe {
|
||||
let p = ffi::SSL_get_session(self.as_ptr());
|
||||
if p.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(SslSessionRef::from_ptr(p))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Sync for Ssl {}
|
||||
|
|
@ -1703,6 +1740,7 @@ mod compat {
|
|||
|
||||
pub use ffi::{SSL_CTX_get_options, SSL_CTX_set_options};
|
||||
pub use ffi::{SSL_CTX_clear_options, SSL_CTX_up_ref};
|
||||
pub use ffi::SSL_SESSION_get_master_key;
|
||||
|
||||
pub unsafe fn get_new_idx(f: ffi::CRYPTO_EX_free) -> c_int {
|
||||
ffi::CRYPTO_get_ex_new_index(ffi::CRYPTO_EX_INDEX_SSL_CTX,
|
||||
|
|
@ -1737,7 +1775,7 @@ mod compat {
|
|||
use std::ptr;
|
||||
|
||||
use ffi;
|
||||
use libc::{self, c_long, c_ulong, c_int};
|
||||
use libc::{self, c_long, c_ulong, c_int, size_t, c_uchar};
|
||||
|
||||
pub unsafe fn SSL_CTX_get_options(ctx: *const ffi::SSL_CTX) -> c_ulong {
|
||||
ffi::SSL_CTX_ctrl(ctx as *mut _, ffi::SSL_CTRL_OPTIONS, 0, ptr::null_mut()) as c_ulong
|
||||
|
|
@ -1774,6 +1812,19 @@ mod compat {
|
|||
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() }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1372,6 +1372,30 @@ fn tmp_ecdh_callback_ssl() {
|
|||
assert!(CALLED_BACK.load(Ordering::SeqCst));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn idle_session() {
|
||||
let ctx = SslContext::builder(SslMethod::tls()).unwrap().build();
|
||||
let ssl = Ssl::new(&ctx).unwrap();
|
||||
assert!(ssl.session().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn active_session() {
|
||||
let connector = SslConnectorBuilder::new(SslMethod::tls()).unwrap().build();
|
||||
|
||||
let s = TcpStream::connect("google.com:443").unwrap();
|
||||
let socket = connector.connect("google.com", s).unwrap();
|
||||
let session = socket.ssl().session().unwrap();
|
||||
let len = session.master_key_len();
|
||||
let mut buf = vec![0; len - 1];
|
||||
let copied = session.master_key(&mut buf);
|
||||
assert_eq!(copied, buf.len());
|
||||
let mut buf = vec![0; len + 1];
|
||||
let copied = session.master_key(&mut buf);
|
||||
assert_eq!(copied, len);
|
||||
|
||||
}
|
||||
|
||||
fn _check_kinds() {
|
||||
fn is_send<T: Send>() {}
|
||||
fn is_sync<T: Sync>() {}
|
||||
|
|
|
|||
Loading…
Reference in New Issue