aboutsummaryrefslogtreecommitdiff
path: root/openssl/src
diff options
context:
space:
mode:
authorSteven Fackler <[email protected]>2017-01-05 12:56:14 -0800
committerGitHub <[email protected]>2017-01-05 12:56:14 -0800
commit58c468803160f6f0d78c80c846dbf4622bb43df9 (patch)
tree20205314f7c3ce878a76b41e794e818caaa5e5c2 /openssl/src
parentRelease v0.9.5 (diff)
parentFix time type (diff)
downloadrust-openssl-58c468803160f6f0d78c80c846dbf4622bb43df9.tar.xz
rust-openssl-58c468803160f6f0d78c80c846dbf4622bb43df9.zip
Merge pull request #549 from sfackler/ssl-session
Ssl session
Diffstat (limited to 'openssl/src')
-rw-r--r--openssl/src/ssl/mod.rs53
-rw-r--r--openssl/src/ssl/tests/mod.rs24
2 files changed, 76 insertions, 1 deletions
diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs
index 3eead8f2..6d49f2b1 100644
--- a/openssl/src/ssl/mod.rs
+++ b/openssl/src/ssl/mod.rs
@@ -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() }
}
diff --git a/openssl/src/ssl/tests/mod.rs b/openssl/src/ssl/tests/mod.rs
index e685d658..14bb2f71 100644
--- a/openssl/src/ssl/tests/mod.rs
+++ b/openssl/src/ssl/tests/mod.rs
@@ -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>() {}