commit
6a5845c875
|
|
@ -2406,6 +2406,16 @@ extern "C" {
|
|||
ctx: *mut SSL,
|
||||
dh: unsafe extern "C" fn(ssl: *mut SSL, is_export: c_int, keylength: c_int) -> *mut DH,
|
||||
);
|
||||
pub fn SSL_export_keying_material(
|
||||
s: *mut SSL,
|
||||
out: *mut c_uchar,
|
||||
olen: size_t,
|
||||
label: *const c_char,
|
||||
llen: size_t,
|
||||
context: *const c_uchar,
|
||||
contextlen: size_t,
|
||||
use_context: c_int,
|
||||
) -> c_int;
|
||||
|
||||
#[cfg(not(any(osslconf = "OPENSSL_NO_COMP", libressl)))]
|
||||
pub fn SSL_COMP_get_name(comp: *const COMP_METHOD) -> *const c_char;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>() {}
|
||||
|
|
|
|||
Loading…
Reference in New Issue