Add RFC 5705 support
This commit is contained in:
parent
c1a106fc68
commit
f72f35e9bd
|
|
@ -2406,6 +2406,16 @@ extern "C" {
|
||||||
ctx: *mut SSL,
|
ctx: *mut SSL,
|
||||||
dh: unsafe extern "C" fn(ssl: *mut SSL, is_export: c_int, keylength: c_int) -> *mut DH,
|
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)))]
|
#[cfg(not(any(osslconf = "OPENSSL_NO_COMP", libressl)))]
|
||||||
pub fn SSL_COMP_get_name(comp: *const COMP_METHOD) -> *const c_char;
|
pub fn SSL_COMP_get_name(comp: *const COMP_METHOD) -> *const c_char;
|
||||||
|
|
|
||||||
|
|
@ -59,8 +59,7 @@
|
||||||
//! ```
|
//! ```
|
||||||
use ffi;
|
use ffi;
|
||||||
use foreign_types::{ForeignType, ForeignTypeRef, Opaque};
|
use foreign_types::{ForeignType, ForeignTypeRef, Opaque};
|
||||||
use libc::{c_int, c_long, c_ulong, c_void};
|
use libc::{c_char, c_int, c_long, c_uchar, c_uint, c_ulong, c_void};
|
||||||
use libc::{c_uchar, c_uint};
|
|
||||||
use std::any::TypeId;
|
use std::any::TypeId;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::collections::HashMap;
|
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.
|
/// Sets the session to be used.
|
||||||
///
|
///
|
||||||
/// This should be called before the handshake to attempt to reuse a previously established
|
/// 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));
|
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 _check_kinds() {
|
||||||
fn is_send<T: Send>() {}
|
fn is_send<T: Send>() {}
|
||||||
fn is_sync<T: Sync>() {}
|
fn is_sync<T: Sync>() {}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue