aboutsummaryrefslogtreecommitdiff
path: root/openssl/src
diff options
context:
space:
mode:
authorSteven Fackler <[email protected]>2018-02-23 22:04:57 -0800
committerSteven Fackler <[email protected]>2018-02-23 22:04:57 -0800
commitf72f35e9bd8292325ed9bca15d21accf4790fbba (patch)
tree218acd687283da7aed5053fc332fbe7a54cc4324 /openssl/src
parentMerge pull request #847 from sfackler/version2 (diff)
downloadrust-openssl-f72f35e9bd8292325ed9bca15d21accf4790fbba.tar.xz
rust-openssl-f72f35e9bd8292325ed9bca15d21accf4790fbba.zip
Add RFC 5705 support
Diffstat (limited to 'openssl/src')
-rw-r--r--openssl/src/ssl/mod.rs32
-rw-r--r--openssl/src/ssl/test.rs42
2 files changed, 72 insertions, 2 deletions
diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs
index e4796df0..fb7db988 100644
--- a/openssl/src/ssl/mod.rs
+++ b/openssl/src/ssl/mod.rs
@@ -59,8 +59,7 @@
//! ```
use ffi;
use foreign_types::{ForeignType, ForeignTypeRef, Opaque};
-use libc::{c_int, c_long, c_ulong, c_void};
-use libc::{c_uchar, c_uint};
+use libc::{c_char, c_int, c_long, c_uchar, c_uint, c_ulong, c_void};
use std::any::TypeId;
use std::cmp;
use std::collections::HashMap;
@@ -2141,6 +2140,35 @@ impl SslRef {
}
}
+ /// Derives keying material for application use in accordance to RFC 5705.
+ ///
+ /// This corresponds to [`SSL_export_keying_material`].
+ ///
+ /// [`SSL_export_keying_material`]: https://www.openssl.org/docs/manmaster/man3/SSL_export_keying_material.html
+ pub fn export_keying_material(
+ &self,
+ out: &mut [u8],
+ label: &str,
+ context: Option<&[u8]>,
+ ) -> Result<(), ErrorStack> {
+ unsafe {
+ let (context, contextlen, use_context) = match context {
+ Some(context) => (context.as_ptr() as *const c_uchar, context.len(), 1),
+ None => (ptr::null(), 0, 0),
+ };
+ cvt(ffi::SSL_export_keying_material(
+ self.as_ptr(),
+ out.as_mut_ptr() as *mut c_uchar,
+ out.len(),
+ label.as_ptr() as *const c_char,
+ label.len(),
+ context,
+ contextlen,
+ use_context,
+ )).map(|_| ())
+ }
+ }
+
/// Sets the session to be used.
///
/// This should be called before the handshake to attempt to reuse a previously established
diff --git a/openssl/src/ssl/test.rs b/openssl/src/ssl/test.rs
index 1913d835..b8e9b8c2 100644
--- a/openssl/src/ssl/test.rs
+++ b/openssl/src/ssl/test.rs
@@ -1278,6 +1278,48 @@ fn new_session_callback() {
assert!(CALLED_BACK.load(Ordering::SeqCst));
}
+#[test]
+fn keying_export() {
+ let listener = TcpListener::bind("127.0.0.1:0").unwrap();
+ let addr = listener.local_addr().unwrap();
+
+ let label = "EXPERIMENTAL test";
+ let context = b"my context";
+
+ let guard = thread::spawn(move || {
+ let stream = listener.accept().unwrap().0;
+ let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
+ ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM)
+ .unwrap();
+ ctx.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM)
+ .unwrap();
+ let ssl = Ssl::new(&ctx.build()).unwrap();
+ let stream = ssl.accept(stream).unwrap();
+
+ let mut buf = [0; 32];
+ stream
+ .ssl()
+ .export_keying_material(&mut buf, label, Some(context))
+ .unwrap();
+ buf
+ });
+
+ let stream = TcpStream::connect(addr).unwrap();
+ let ctx = SslContext::builder(SslMethod::tls()).unwrap();
+ let ssl = Ssl::new(&ctx.build()).unwrap();
+ let stream = ssl.connect(stream).unwrap();
+
+ let mut buf = [1; 32];
+ stream
+ .ssl()
+ .export_keying_material(&mut buf, label, Some(context))
+ .unwrap();
+
+ let buf2 = guard.join().unwrap();
+
+ assert_eq!(buf, buf2);
+}
+
fn _check_kinds() {
fn is_send<T: Send>() {}
fn is_sync<T: Sync>() {}