Loading .circleci/config.yml +1 −1 Original line number Diff line number Diff line Loading @@ -91,7 +91,7 @@ macos_job: &MACOS_JOB openssl_111: &OPENSSL_111 LIBRARY: openssl VERSION: 1.1.1-pre3 VERSION: 1.1.1-pre7 openssl_110: &OPENSSL_110 LIBRARY: openssl VERSION: 1.1.0h Loading openssl-sys/src/openssl/v111.rs +72 −43 Original line number Diff line number Diff line use libc::{c_char, c_uchar, c_int, c_uint, c_ulong, size_t, c_void}; use libc::{c_char, c_int, c_uchar, c_uint, c_ulong, c_void, size_t}; pub type SSL_CTX_keylog_cb_func = Option<unsafe extern "C" fn(ssl: *const ::SSL, line: *const c_char)>; pub type SSL_custom_ext_add_cb_ex = Option<unsafe extern "C" fn(ssl: *mut ::SSL, ext_type: c_uint, pub type SSL_custom_ext_add_cb_ex = Option< unsafe extern "C" fn( ssl: *mut ::SSL, ext_type: c_uint, context: c_uint, out: *mut *const c_uchar, outlen: *mut size_t, x: *mut ::X509, chainidx: size_t, al: *mut c_int, add_arg: *mut c_void) -> c_int>; outlen: *mut size_t, x: *mut ::X509, chainidx: size_t, al: *mut c_int, add_arg: *mut c_void, ) -> c_int, >; pub type SSL_custom_ext_free_cb_ex = Option<unsafe extern "C" fn(ssl: *mut ::SSL, ext_type: c_uint, pub type SSL_custom_ext_free_cb_ex = Option< unsafe extern "C" fn( ssl: *mut ::SSL, ext_type: c_uint, context: c_uint, out: *mut *const c_uchar, add_arg: *mut c_void)>; add_arg: *mut c_void, ), >; pub type SSL_custom_ext_parse_cb_ex = Option<unsafe extern "C" fn(ssl: *mut ::SSL, ext_type: c_uint, pub type SSL_custom_ext_parse_cb_ex = Option< unsafe extern "C" fn( ssl: *mut ::SSL, ext_type: c_uint, context: c_uint, input: *const c_uchar, inlen: size_t, x: *mut ::X509, chainidx: size_t, al: *mut c_int, parse_arg: *mut c_void) -> c_int>; inlen: size_t, x: *mut ::X509, chainidx: size_t, al: *mut c_int, parse_arg: *mut c_void, ) -> c_int, >; pub const SSL_COOKIE_LENGTH: c_int = 4096; Loading Loading @@ -61,38 +77,38 @@ pub const SSL_READ_EARLY_DATA_FINISH: c_int = 2; extern "C" { pub fn SSL_CTX_set_keylog_callback(ctx: *mut ::SSL_CTX, cb: SSL_CTX_keylog_cb_func); pub fn SSL_CTX_add_custom_ext(ctx: *mut ::SSL_CTX, ext_type: c_uint, context: c_uint, pub fn SSL_CTX_add_custom_ext( ctx: *mut ::SSL_CTX, ext_type: c_uint, context: c_uint, add_cb: SSL_custom_ext_add_cb_ex, free_cb: SSL_custom_ext_free_cb_ex, add_arg: *mut c_void, parse_cb: SSL_custom_ext_parse_cb_ex, parse_arg: *mut c_void) -> c_int; pub fn SSL_stateless(s: *mut ::SSL) -> c_int; parse_arg: *mut c_void, ) -> c_int; pub fn SSL_CIPHER_get_handshake_digest(cipher: *const ::SSL_CIPHER) -> *const ::EVP_MD; pub fn SSL_CTX_set_stateless_cookie_generate_cb( s: *mut ::SSL_CTX, cb: Option<unsafe extern "C" fn( ssl: *mut ::SSL, cookie: *mut c_uchar, cookie_len: *mut size_t ) -> c_int> cb: Option< unsafe extern "C" fn(ssl: *mut ::SSL, cookie: *mut c_uchar, cookie_len: *mut size_t) -> c_int, >, ); pub fn SSL_CTX_set_stateless_cookie_verify_cb( s: *mut ::SSL_CTX, cb: Option<unsafe extern "C" fn( ssl: *mut ::SSL, cookie: *const c_uchar, cookie_len: size_t ) -> c_int> cb: Option< unsafe extern "C" fn(ssl: *mut ::SSL, cookie: *const c_uchar, cookie_len: size_t) -> c_int, >, ); pub fn SSL_CTX_set_max_early_data(ctx: *mut ::SSL_CTX, max_early_data: u32) -> c_int; pub fn SSL_CTX_get_max_early_data(ctx: *const ::SSL_CTX) -> u32; pub fn SSL_CTX_set_ciphersuites(ctx: *mut ::SSL_CTX, str: *const c_char) -> c_int; pub fn SSL_set_max_early_data(ctx: *mut ::SSL, max_early_data: u32) -> c_int; pub fn SSL_get_max_early_data(ctx: *const ::SSL) -> u32; pub fn SSL_SESSION_set_max_early_data(ctx: *mut ::SSL_SESSION, max_early_data: u32) -> c_int; pub fn SSL_SESSION_get_max_early_data(ctx: *const ::SSL_SESSION) -> u32; pub fn SSL_stateless(s: *mut ::SSL) -> c_int; pub fn SSL_export_keying_material_early( s: *mut ::SSL, out: *mut c_uchar, Loading @@ -102,7 +118,20 @@ extern "C" { context: *const c_uchar, contextlen: size_t, ) -> c_int; pub fn SSL_write_early_data( s: *mut ::SSL, buf: *const c_void, num: size_t, written: *mut size_t, ) -> c_int; pub fn SSL_read_early_data( s: *mut ::SSL, buf: *mut c_void, num: size_t, readbytes: *mut size_t, ) -> c_int; pub fn SSL_set_ciphersuites(ssl: *mut ::SSL, str: *const c_char) -> c_int; pub fn SSL_write_early_data(s: *mut ::SSL, buf: *const c_void, num: size_t, written: *mut size_t) -> c_int; pub fn SSL_read_early_data(s: *mut ::SSL, buf: *mut c_void, num: size_t, readbytes: *mut size_t) -> c_int; pub fn SSL_SESSION_set_max_early_data(ctx: *mut ::SSL_SESSION, max_early_data: u32) -> c_int; pub fn SSL_SESSION_get_max_early_data(ctx: *const ::SSL_SESSION) -> u32; } openssl/src/ssl/mod.rs +26 −1 Original line number Diff line number Diff line Loading @@ -952,7 +952,9 @@ impl SslContextBuilder { unsafe { cvt(ffi::SSL_CTX_use_PrivateKey(self.as_ptr(), key.as_ptr())).map(|_| ()) } } /// Sets the list of supported ciphers. /// Sets the list of supported ciphers for protocols before TLSv1.3. /// /// The `set_ciphersuites` method controls the cipher suites for TLSv1.3. /// /// See [`ciphers`] for details on the format. /// Loading @@ -970,6 +972,29 @@ impl SslContextBuilder { } } /// Sets the list of supported ciphers for the TLSv1.3 protocol. /// /// The `set_cipher_list` method controls lthe cipher suites for protocols before TLSv1.3. /// /// The format consists of TLSv1.3 ciphersuite names separated by `:` characters in order of /// preference. /// /// Requires OpenSSL 1.1.1 or newer. /// /// This corresponds to [`SSL_CTX_set_ciphersuites`]. /// /// [`SSL_CTX_set_ciphersuites`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_ciphersuites.html #[cfg(ossl111)] pub fn set_ciphersuites(&mut self, cipher_list: &str) -> Result<(), ErrorStack> { let cipher_list = CString::new(cipher_list).unwrap(); unsafe { cvt(ffi::SSL_CTX_set_ciphersuites( self.as_ptr(), cipher_list.as_ptr() as *const _, )).map(|_| ()) } } /// Enables ECDHE key exchange with an automatically chosen curve list. /// /// Requires OpenSSL 1.0.2. Loading openssl/src/ssl/test.rs +74 −42 Original line number Diff line number Diff line Loading @@ -567,9 +567,10 @@ fn test_alpn_server_advertise_multiple() { ctx.build() }; // Have the listener wait on the connection in a different thread. thread::spawn(move || { let guard = thread::spawn(move || { let (stream, _) = listener.accept().unwrap(); Ssl::new(&listener_ctx).unwrap().accept(stream).unwrap(); let mut stream = Ssl::new(&listener_ctx).unwrap().accept(stream).unwrap(); stream.write_all(&[0]).unwrap(); }); let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); Loading @@ -581,12 +582,16 @@ fn test_alpn_server_advertise_multiple() { } // Now connect to the socket and make sure the protocol negotiation works... let stream = TcpStream::connect(localhost).unwrap(); let stream = match Ssl::new(&ctx.build()).unwrap().connect(stream) { let mut stream = match Ssl::new(&ctx.build()).unwrap().connect(stream) { Ok(stream) => stream, Err(err) => panic!("Expected success, got {:?}", err), }; // SPDY is selected since that's the only thing the client supports. assert_eq!(b"spdy/3.1", stream.ssl().selected_alpn_protocol().unwrap()); let mut buf = [0]; stream.read_exact(&mut buf).unwrap(); guard.join().unwrap(); } #[test] Loading Loading @@ -643,9 +648,10 @@ fn test_alpn_server_select_none() { ctx.build() }; // Have the listener wait on the connection in a different thread. thread::spawn(move || { let guard = thread::spawn(move || { let (stream, _) = listener.accept().unwrap(); Ssl::new(&listener_ctx).unwrap().accept(stream).unwrap(); let mut stream = Ssl::new(&listener_ctx).unwrap().accept(stream).unwrap(); stream.write_all(&[0]).unwrap(); }); let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); Loading @@ -654,10 +660,15 @@ fn test_alpn_server_select_none() { ctx.set_ca_file(&Path::new("test/root-ca.pem")).unwrap(); // Now connect to the socket and make sure the protocol negotiation works... let stream = TcpStream::connect(localhost).unwrap(); let stream = Ssl::new(&ctx.build()).unwrap().connect(stream).unwrap(); let mut stream = Ssl::new(&ctx.build()).unwrap().connect(stream).unwrap(); // Since the protocols from the server and client don't overlap at all, no protocol is selected assert_eq!(None, stream.ssl().selected_alpn_protocol()); let mut buf = [0]; stream.read_exact(&mut buf).unwrap(); guard.join().unwrap(); } #[test] Loading Loading @@ -972,7 +983,7 @@ fn shutdown() { let listener = TcpListener::bind("127.0.0.1:0").unwrap(); let port = listener.local_addr().unwrap().port(); thread::spawn(move || { 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) Loading @@ -999,6 +1010,8 @@ fn shutdown() { assert_eq!(stream.shutdown().unwrap(), ShutdownResult::Sent); assert_eq!(stream.shutdown().unwrap(), ShutdownResult::Received); guard.join().unwrap(); } #[test] Loading Loading @@ -1030,7 +1043,7 @@ fn tmp_dh_callback() { let listener = TcpListener::bind("127.0.0.1:0").unwrap(); let port = listener.local_addr().unwrap().port(); thread::spawn(move || { 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) Loading @@ -1043,23 +1056,24 @@ fn tmp_dh_callback() { Dh::params_from_pem(dh) }); let ssl = Ssl::new(&ctx.build()).unwrap(); ssl.accept(stream).unwrap(); let mut stream = ssl.accept(stream).unwrap(); stream.write_all(&[0]).unwrap(); }); let stream = TcpStream::connect(("127.0.0.1", port)).unwrap(); let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); // TLS 1.3 has no DH suites, and openssl isn't happy if the max version has no suites :( // TLS 1.3 has no DH suites, so make sure we don't pick that version #[cfg(ossl111)] { ctx.set_options(super::SslOptions { bits: ::ffi::SSL_OP_NO_TLSv1_3, }); } ctx.set_options(super::SslOptions::NO_TLSV1_3); ctx.set_cipher_list("EDH").unwrap(); let ssl = Ssl::new(&ctx.build()).unwrap(); ssl.connect(stream).unwrap(); let mut stream = ssl.connect(stream).unwrap(); stream.read_exact(&mut [0]).unwrap(); assert!(CALLED_BACK.load(Ordering::SeqCst)); guard.join().unwrap(); } #[test] Loading @@ -1073,7 +1087,7 @@ fn tmp_ecdh_callback() { let listener = TcpListener::bind("127.0.0.1:0").unwrap(); let port = listener.local_addr().unwrap().port(); thread::spawn(move || { 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) Loading @@ -1085,16 +1099,20 @@ fn tmp_ecdh_callback() { EcKey::from_curve_name(Nid::X9_62_PRIME256V1) }); let ssl = Ssl::new(&ctx.build()).unwrap(); ssl.accept(stream).unwrap(); let mut stream = ssl.accept(stream).unwrap(); stream.write_all(&[0]).unwrap(); }); let stream = TcpStream::connect(("127.0.0.1", port)).unwrap(); let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); ctx.set_cipher_list("ECDH").unwrap(); let ssl = Ssl::new(&ctx.build()).unwrap(); ssl.connect(stream).unwrap(); let mut stream = ssl.connect(stream).unwrap(); stream.read_exact(&mut [0]).unwrap(); assert!(CALLED_BACK.load(Ordering::SeqCst)); guard.join().unwrap(); } #[test] Loading @@ -1104,7 +1122,7 @@ fn tmp_dh_callback_ssl() { let listener = TcpListener::bind("127.0.0.1:0").unwrap(); let port = listener.local_addr().unwrap().port(); thread::spawn(move || { 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) Loading @@ -1117,23 +1135,23 @@ fn tmp_dh_callback_ssl() { let dh = include_bytes!("../../test/dhparams.pem"); Dh::params_from_pem(dh) }); ssl.accept(stream).unwrap(); let mut stream = ssl.accept(stream).unwrap(); stream.write_all(&[0]).unwrap(); }); let stream = TcpStream::connect(("127.0.0.1", port)).unwrap(); let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); // TLS 1.3 has no DH suites, and openssl isn't happy if the max version has no suites :( // TLS 1.3 has no DH suites, so make sure we don't pick that version #[cfg(ossl111)] { ctx.set_options(super::SslOptions { bits: ::ffi::SSL_OP_NO_TLSv1_3, }); } ctx.set_options(super::SslOptions::NO_TLSV1_3); ctx.set_cipher_list("EDH").unwrap(); let ssl = Ssl::new(&ctx.build()).unwrap(); ssl.connect(stream).unwrap(); let mut stream = ssl.connect(stream).unwrap(); stream.read_exact(&mut [0]).unwrap(); assert!(CALLED_BACK.load(Ordering::SeqCst)); guard.join().unwrap(); } #[test] Loading @@ -1147,7 +1165,7 @@ fn tmp_ecdh_callback_ssl() { let listener = TcpListener::bind("127.0.0.1:0").unwrap(); let port = listener.local_addr().unwrap().port(); thread::spawn(move || { 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) Loading @@ -1159,16 +1177,20 @@ fn tmp_ecdh_callback_ssl() { CALLED_BACK.store(true, Ordering::SeqCst); EcKey::from_curve_name(Nid::X9_62_PRIME256V1) }); ssl.accept(stream).unwrap(); let mut stream = ssl.accept(stream).unwrap(); stream.write_all(&[0]).unwrap(); }); let stream = TcpStream::connect(("127.0.0.1", port)).unwrap(); let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); ctx.set_cipher_list("ECDH").unwrap(); let ssl = Ssl::new(&ctx.build()).unwrap(); ssl.connect(stream).unwrap(); let mut stream = ssl.connect(stream).unwrap(); stream.read_exact(&mut [0]).unwrap(); assert!(CALLED_BACK.load(Ordering::SeqCst)); guard.join().unwrap(); } #[test] Loading Loading @@ -1200,7 +1222,7 @@ fn status_callbacks() { static CALLED_BACK_SERVER: AtomicBool = ATOMIC_BOOL_INIT; static CALLED_BACK_CLIENT: AtomicBool = ATOMIC_BOOL_INIT; let listener = TcpListener::bind("127.0.0.1:0").unwrap(); let listener = TcpListener::bind("127.0.0.1:12345").unwrap(); let port = listener.local_addr().unwrap().port(); let guard = thread::spawn(move || { Loading @@ -1218,7 +1240,8 @@ fn status_callbacks() { Ok(true) }).unwrap(); let ssl = Ssl::new(&ctx.build()).unwrap(); ssl.accept(stream).unwrap(); let mut stream = ssl.accept(stream).unwrap(); stream.write_all(&[0]).unwrap(); }); let stream = TcpStream::connect(("127.0.0.1", port)).unwrap(); Loading @@ -1231,7 +1254,9 @@ fn status_callbacks() { }).unwrap(); let mut ssl = Ssl::new(&ctx.build()).unwrap(); ssl.set_status_type(StatusType::OCSP).unwrap(); ssl.connect(stream).unwrap(); let mut stream = ssl.connect(stream).unwrap(); let mut buf = [0]; stream.read_exact(&mut buf).unwrap(); assert!(CALLED_BACK_SERVER.load(Ordering::SeqCst)); assert!(CALLED_BACK_CLIENT.load(Ordering::SeqCst)); Loading @@ -1246,7 +1271,7 @@ fn new_session_callback() { let listener = TcpListener::bind("127.0.0.1:0").unwrap(); let port = listener.local_addr().unwrap().port(); thread::spawn(move || { 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) Loading @@ -1265,11 +1290,11 @@ fn new_session_callback() { ctx.set_new_session_callback(|_, _| CALLED_BACK.store(true, Ordering::SeqCst)); let ssl = Ssl::new(&ctx.build()).unwrap(); let mut stream = ssl.connect(stream).unwrap(); // read 1 byte to make sure the session is received for TLSv1.3 let mut buf = [0]; stream.read_exact(&mut buf).unwrap(); stream.read_exact(&mut [0]).unwrap(); assert!(CALLED_BACK.load(Ordering::SeqCst)); guard.join().unwrap(); } #[test] Loading @@ -1288,20 +1313,23 @@ fn keying_export() { 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 stream = ssl.accept(stream).unwrap(); let mut buf = [0; 32]; stream .ssl() .export_keying_material(&mut buf, label, Some(context)) .unwrap(); stream.write_all(&[0]).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 stream = ssl.connect(stream).unwrap(); let mut buf = [1; 32]; stream Loading @@ -1309,6 +1337,8 @@ fn keying_export() { .export_keying_material(&mut buf, label, Some(context)) .unwrap(); stream.read_exact(&mut [0]).unwrap(); let buf2 = guard.join().unwrap(); assert_eq!(buf, buf2); Loading Loading @@ -1374,7 +1404,8 @@ fn custom_extensions() { }, ).unwrap(); let ssl = Ssl::new(&ctx.build()).unwrap(); ssl.accept(stream).unwrap(); let mut stream = ssl.accept(stream).unwrap(); stream.write_all(&[0]).unwrap(); }); let stream = TcpStream::connect(addr).unwrap(); Loading @@ -1386,7 +1417,8 @@ fn custom_extensions() { |_, _, _, _| unreachable!(), ).unwrap(); let ssl = Ssl::new(&ctx.build()).unwrap(); ssl.connect(stream).unwrap(); let mut stream = ssl.connect(stream).unwrap(); stream.read_exact(&mut [0]).unwrap(); guard.join().unwrap(); assert!(FOUND_EXTENSION.load(Ordering::SeqCst)); Loading Loading
.circleci/config.yml +1 −1 Original line number Diff line number Diff line Loading @@ -91,7 +91,7 @@ macos_job: &MACOS_JOB openssl_111: &OPENSSL_111 LIBRARY: openssl VERSION: 1.1.1-pre3 VERSION: 1.1.1-pre7 openssl_110: &OPENSSL_110 LIBRARY: openssl VERSION: 1.1.0h Loading
openssl-sys/src/openssl/v111.rs +72 −43 Original line number Diff line number Diff line use libc::{c_char, c_uchar, c_int, c_uint, c_ulong, size_t, c_void}; use libc::{c_char, c_int, c_uchar, c_uint, c_ulong, c_void, size_t}; pub type SSL_CTX_keylog_cb_func = Option<unsafe extern "C" fn(ssl: *const ::SSL, line: *const c_char)>; pub type SSL_custom_ext_add_cb_ex = Option<unsafe extern "C" fn(ssl: *mut ::SSL, ext_type: c_uint, pub type SSL_custom_ext_add_cb_ex = Option< unsafe extern "C" fn( ssl: *mut ::SSL, ext_type: c_uint, context: c_uint, out: *mut *const c_uchar, outlen: *mut size_t, x: *mut ::X509, chainidx: size_t, al: *mut c_int, add_arg: *mut c_void) -> c_int>; outlen: *mut size_t, x: *mut ::X509, chainidx: size_t, al: *mut c_int, add_arg: *mut c_void, ) -> c_int, >; pub type SSL_custom_ext_free_cb_ex = Option<unsafe extern "C" fn(ssl: *mut ::SSL, ext_type: c_uint, pub type SSL_custom_ext_free_cb_ex = Option< unsafe extern "C" fn( ssl: *mut ::SSL, ext_type: c_uint, context: c_uint, out: *mut *const c_uchar, add_arg: *mut c_void)>; add_arg: *mut c_void, ), >; pub type SSL_custom_ext_parse_cb_ex = Option<unsafe extern "C" fn(ssl: *mut ::SSL, ext_type: c_uint, pub type SSL_custom_ext_parse_cb_ex = Option< unsafe extern "C" fn( ssl: *mut ::SSL, ext_type: c_uint, context: c_uint, input: *const c_uchar, inlen: size_t, x: *mut ::X509, chainidx: size_t, al: *mut c_int, parse_arg: *mut c_void) -> c_int>; inlen: size_t, x: *mut ::X509, chainidx: size_t, al: *mut c_int, parse_arg: *mut c_void, ) -> c_int, >; pub const SSL_COOKIE_LENGTH: c_int = 4096; Loading Loading @@ -61,38 +77,38 @@ pub const SSL_READ_EARLY_DATA_FINISH: c_int = 2; extern "C" { pub fn SSL_CTX_set_keylog_callback(ctx: *mut ::SSL_CTX, cb: SSL_CTX_keylog_cb_func); pub fn SSL_CTX_add_custom_ext(ctx: *mut ::SSL_CTX, ext_type: c_uint, context: c_uint, pub fn SSL_CTX_add_custom_ext( ctx: *mut ::SSL_CTX, ext_type: c_uint, context: c_uint, add_cb: SSL_custom_ext_add_cb_ex, free_cb: SSL_custom_ext_free_cb_ex, add_arg: *mut c_void, parse_cb: SSL_custom_ext_parse_cb_ex, parse_arg: *mut c_void) -> c_int; pub fn SSL_stateless(s: *mut ::SSL) -> c_int; parse_arg: *mut c_void, ) -> c_int; pub fn SSL_CIPHER_get_handshake_digest(cipher: *const ::SSL_CIPHER) -> *const ::EVP_MD; pub fn SSL_CTX_set_stateless_cookie_generate_cb( s: *mut ::SSL_CTX, cb: Option<unsafe extern "C" fn( ssl: *mut ::SSL, cookie: *mut c_uchar, cookie_len: *mut size_t ) -> c_int> cb: Option< unsafe extern "C" fn(ssl: *mut ::SSL, cookie: *mut c_uchar, cookie_len: *mut size_t) -> c_int, >, ); pub fn SSL_CTX_set_stateless_cookie_verify_cb( s: *mut ::SSL_CTX, cb: Option<unsafe extern "C" fn( ssl: *mut ::SSL, cookie: *const c_uchar, cookie_len: size_t ) -> c_int> cb: Option< unsafe extern "C" fn(ssl: *mut ::SSL, cookie: *const c_uchar, cookie_len: size_t) -> c_int, >, ); pub fn SSL_CTX_set_max_early_data(ctx: *mut ::SSL_CTX, max_early_data: u32) -> c_int; pub fn SSL_CTX_get_max_early_data(ctx: *const ::SSL_CTX) -> u32; pub fn SSL_CTX_set_ciphersuites(ctx: *mut ::SSL_CTX, str: *const c_char) -> c_int; pub fn SSL_set_max_early_data(ctx: *mut ::SSL, max_early_data: u32) -> c_int; pub fn SSL_get_max_early_data(ctx: *const ::SSL) -> u32; pub fn SSL_SESSION_set_max_early_data(ctx: *mut ::SSL_SESSION, max_early_data: u32) -> c_int; pub fn SSL_SESSION_get_max_early_data(ctx: *const ::SSL_SESSION) -> u32; pub fn SSL_stateless(s: *mut ::SSL) -> c_int; pub fn SSL_export_keying_material_early( s: *mut ::SSL, out: *mut c_uchar, Loading @@ -102,7 +118,20 @@ extern "C" { context: *const c_uchar, contextlen: size_t, ) -> c_int; pub fn SSL_write_early_data( s: *mut ::SSL, buf: *const c_void, num: size_t, written: *mut size_t, ) -> c_int; pub fn SSL_read_early_data( s: *mut ::SSL, buf: *mut c_void, num: size_t, readbytes: *mut size_t, ) -> c_int; pub fn SSL_set_ciphersuites(ssl: *mut ::SSL, str: *const c_char) -> c_int; pub fn SSL_write_early_data(s: *mut ::SSL, buf: *const c_void, num: size_t, written: *mut size_t) -> c_int; pub fn SSL_read_early_data(s: *mut ::SSL, buf: *mut c_void, num: size_t, readbytes: *mut size_t) -> c_int; pub fn SSL_SESSION_set_max_early_data(ctx: *mut ::SSL_SESSION, max_early_data: u32) -> c_int; pub fn SSL_SESSION_get_max_early_data(ctx: *const ::SSL_SESSION) -> u32; }
openssl/src/ssl/mod.rs +26 −1 Original line number Diff line number Diff line Loading @@ -952,7 +952,9 @@ impl SslContextBuilder { unsafe { cvt(ffi::SSL_CTX_use_PrivateKey(self.as_ptr(), key.as_ptr())).map(|_| ()) } } /// Sets the list of supported ciphers. /// Sets the list of supported ciphers for protocols before TLSv1.3. /// /// The `set_ciphersuites` method controls the cipher suites for TLSv1.3. /// /// See [`ciphers`] for details on the format. /// Loading @@ -970,6 +972,29 @@ impl SslContextBuilder { } } /// Sets the list of supported ciphers for the TLSv1.3 protocol. /// /// The `set_cipher_list` method controls lthe cipher suites for protocols before TLSv1.3. /// /// The format consists of TLSv1.3 ciphersuite names separated by `:` characters in order of /// preference. /// /// Requires OpenSSL 1.1.1 or newer. /// /// This corresponds to [`SSL_CTX_set_ciphersuites`]. /// /// [`SSL_CTX_set_ciphersuites`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_ciphersuites.html #[cfg(ossl111)] pub fn set_ciphersuites(&mut self, cipher_list: &str) -> Result<(), ErrorStack> { let cipher_list = CString::new(cipher_list).unwrap(); unsafe { cvt(ffi::SSL_CTX_set_ciphersuites( self.as_ptr(), cipher_list.as_ptr() as *const _, )).map(|_| ()) } } /// Enables ECDHE key exchange with an automatically chosen curve list. /// /// Requires OpenSSL 1.0.2. Loading
openssl/src/ssl/test.rs +74 −42 Original line number Diff line number Diff line Loading @@ -567,9 +567,10 @@ fn test_alpn_server_advertise_multiple() { ctx.build() }; // Have the listener wait on the connection in a different thread. thread::spawn(move || { let guard = thread::spawn(move || { let (stream, _) = listener.accept().unwrap(); Ssl::new(&listener_ctx).unwrap().accept(stream).unwrap(); let mut stream = Ssl::new(&listener_ctx).unwrap().accept(stream).unwrap(); stream.write_all(&[0]).unwrap(); }); let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); Loading @@ -581,12 +582,16 @@ fn test_alpn_server_advertise_multiple() { } // Now connect to the socket and make sure the protocol negotiation works... let stream = TcpStream::connect(localhost).unwrap(); let stream = match Ssl::new(&ctx.build()).unwrap().connect(stream) { let mut stream = match Ssl::new(&ctx.build()).unwrap().connect(stream) { Ok(stream) => stream, Err(err) => panic!("Expected success, got {:?}", err), }; // SPDY is selected since that's the only thing the client supports. assert_eq!(b"spdy/3.1", stream.ssl().selected_alpn_protocol().unwrap()); let mut buf = [0]; stream.read_exact(&mut buf).unwrap(); guard.join().unwrap(); } #[test] Loading Loading @@ -643,9 +648,10 @@ fn test_alpn_server_select_none() { ctx.build() }; // Have the listener wait on the connection in a different thread. thread::spawn(move || { let guard = thread::spawn(move || { let (stream, _) = listener.accept().unwrap(); Ssl::new(&listener_ctx).unwrap().accept(stream).unwrap(); let mut stream = Ssl::new(&listener_ctx).unwrap().accept(stream).unwrap(); stream.write_all(&[0]).unwrap(); }); let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); Loading @@ -654,10 +660,15 @@ fn test_alpn_server_select_none() { ctx.set_ca_file(&Path::new("test/root-ca.pem")).unwrap(); // Now connect to the socket and make sure the protocol negotiation works... let stream = TcpStream::connect(localhost).unwrap(); let stream = Ssl::new(&ctx.build()).unwrap().connect(stream).unwrap(); let mut stream = Ssl::new(&ctx.build()).unwrap().connect(stream).unwrap(); // Since the protocols from the server and client don't overlap at all, no protocol is selected assert_eq!(None, stream.ssl().selected_alpn_protocol()); let mut buf = [0]; stream.read_exact(&mut buf).unwrap(); guard.join().unwrap(); } #[test] Loading Loading @@ -972,7 +983,7 @@ fn shutdown() { let listener = TcpListener::bind("127.0.0.1:0").unwrap(); let port = listener.local_addr().unwrap().port(); thread::spawn(move || { 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) Loading @@ -999,6 +1010,8 @@ fn shutdown() { assert_eq!(stream.shutdown().unwrap(), ShutdownResult::Sent); assert_eq!(stream.shutdown().unwrap(), ShutdownResult::Received); guard.join().unwrap(); } #[test] Loading Loading @@ -1030,7 +1043,7 @@ fn tmp_dh_callback() { let listener = TcpListener::bind("127.0.0.1:0").unwrap(); let port = listener.local_addr().unwrap().port(); thread::spawn(move || { 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) Loading @@ -1043,23 +1056,24 @@ fn tmp_dh_callback() { Dh::params_from_pem(dh) }); let ssl = Ssl::new(&ctx.build()).unwrap(); ssl.accept(stream).unwrap(); let mut stream = ssl.accept(stream).unwrap(); stream.write_all(&[0]).unwrap(); }); let stream = TcpStream::connect(("127.0.0.1", port)).unwrap(); let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); // TLS 1.3 has no DH suites, and openssl isn't happy if the max version has no suites :( // TLS 1.3 has no DH suites, so make sure we don't pick that version #[cfg(ossl111)] { ctx.set_options(super::SslOptions { bits: ::ffi::SSL_OP_NO_TLSv1_3, }); } ctx.set_options(super::SslOptions::NO_TLSV1_3); ctx.set_cipher_list("EDH").unwrap(); let ssl = Ssl::new(&ctx.build()).unwrap(); ssl.connect(stream).unwrap(); let mut stream = ssl.connect(stream).unwrap(); stream.read_exact(&mut [0]).unwrap(); assert!(CALLED_BACK.load(Ordering::SeqCst)); guard.join().unwrap(); } #[test] Loading @@ -1073,7 +1087,7 @@ fn tmp_ecdh_callback() { let listener = TcpListener::bind("127.0.0.1:0").unwrap(); let port = listener.local_addr().unwrap().port(); thread::spawn(move || { 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) Loading @@ -1085,16 +1099,20 @@ fn tmp_ecdh_callback() { EcKey::from_curve_name(Nid::X9_62_PRIME256V1) }); let ssl = Ssl::new(&ctx.build()).unwrap(); ssl.accept(stream).unwrap(); let mut stream = ssl.accept(stream).unwrap(); stream.write_all(&[0]).unwrap(); }); let stream = TcpStream::connect(("127.0.0.1", port)).unwrap(); let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); ctx.set_cipher_list("ECDH").unwrap(); let ssl = Ssl::new(&ctx.build()).unwrap(); ssl.connect(stream).unwrap(); let mut stream = ssl.connect(stream).unwrap(); stream.read_exact(&mut [0]).unwrap(); assert!(CALLED_BACK.load(Ordering::SeqCst)); guard.join().unwrap(); } #[test] Loading @@ -1104,7 +1122,7 @@ fn tmp_dh_callback_ssl() { let listener = TcpListener::bind("127.0.0.1:0").unwrap(); let port = listener.local_addr().unwrap().port(); thread::spawn(move || { 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) Loading @@ -1117,23 +1135,23 @@ fn tmp_dh_callback_ssl() { let dh = include_bytes!("../../test/dhparams.pem"); Dh::params_from_pem(dh) }); ssl.accept(stream).unwrap(); let mut stream = ssl.accept(stream).unwrap(); stream.write_all(&[0]).unwrap(); }); let stream = TcpStream::connect(("127.0.0.1", port)).unwrap(); let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); // TLS 1.3 has no DH suites, and openssl isn't happy if the max version has no suites :( // TLS 1.3 has no DH suites, so make sure we don't pick that version #[cfg(ossl111)] { ctx.set_options(super::SslOptions { bits: ::ffi::SSL_OP_NO_TLSv1_3, }); } ctx.set_options(super::SslOptions::NO_TLSV1_3); ctx.set_cipher_list("EDH").unwrap(); let ssl = Ssl::new(&ctx.build()).unwrap(); ssl.connect(stream).unwrap(); let mut stream = ssl.connect(stream).unwrap(); stream.read_exact(&mut [0]).unwrap(); assert!(CALLED_BACK.load(Ordering::SeqCst)); guard.join().unwrap(); } #[test] Loading @@ -1147,7 +1165,7 @@ fn tmp_ecdh_callback_ssl() { let listener = TcpListener::bind("127.0.0.1:0").unwrap(); let port = listener.local_addr().unwrap().port(); thread::spawn(move || { 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) Loading @@ -1159,16 +1177,20 @@ fn tmp_ecdh_callback_ssl() { CALLED_BACK.store(true, Ordering::SeqCst); EcKey::from_curve_name(Nid::X9_62_PRIME256V1) }); ssl.accept(stream).unwrap(); let mut stream = ssl.accept(stream).unwrap(); stream.write_all(&[0]).unwrap(); }); let stream = TcpStream::connect(("127.0.0.1", port)).unwrap(); let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); ctx.set_cipher_list("ECDH").unwrap(); let ssl = Ssl::new(&ctx.build()).unwrap(); ssl.connect(stream).unwrap(); let mut stream = ssl.connect(stream).unwrap(); stream.read_exact(&mut [0]).unwrap(); assert!(CALLED_BACK.load(Ordering::SeqCst)); guard.join().unwrap(); } #[test] Loading Loading @@ -1200,7 +1222,7 @@ fn status_callbacks() { static CALLED_BACK_SERVER: AtomicBool = ATOMIC_BOOL_INIT; static CALLED_BACK_CLIENT: AtomicBool = ATOMIC_BOOL_INIT; let listener = TcpListener::bind("127.0.0.1:0").unwrap(); let listener = TcpListener::bind("127.0.0.1:12345").unwrap(); let port = listener.local_addr().unwrap().port(); let guard = thread::spawn(move || { Loading @@ -1218,7 +1240,8 @@ fn status_callbacks() { Ok(true) }).unwrap(); let ssl = Ssl::new(&ctx.build()).unwrap(); ssl.accept(stream).unwrap(); let mut stream = ssl.accept(stream).unwrap(); stream.write_all(&[0]).unwrap(); }); let stream = TcpStream::connect(("127.0.0.1", port)).unwrap(); Loading @@ -1231,7 +1254,9 @@ fn status_callbacks() { }).unwrap(); let mut ssl = Ssl::new(&ctx.build()).unwrap(); ssl.set_status_type(StatusType::OCSP).unwrap(); ssl.connect(stream).unwrap(); let mut stream = ssl.connect(stream).unwrap(); let mut buf = [0]; stream.read_exact(&mut buf).unwrap(); assert!(CALLED_BACK_SERVER.load(Ordering::SeqCst)); assert!(CALLED_BACK_CLIENT.load(Ordering::SeqCst)); Loading @@ -1246,7 +1271,7 @@ fn new_session_callback() { let listener = TcpListener::bind("127.0.0.1:0").unwrap(); let port = listener.local_addr().unwrap().port(); thread::spawn(move || { 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) Loading @@ -1265,11 +1290,11 @@ fn new_session_callback() { ctx.set_new_session_callback(|_, _| CALLED_BACK.store(true, Ordering::SeqCst)); let ssl = Ssl::new(&ctx.build()).unwrap(); let mut stream = ssl.connect(stream).unwrap(); // read 1 byte to make sure the session is received for TLSv1.3 let mut buf = [0]; stream.read_exact(&mut buf).unwrap(); stream.read_exact(&mut [0]).unwrap(); assert!(CALLED_BACK.load(Ordering::SeqCst)); guard.join().unwrap(); } #[test] Loading @@ -1288,20 +1313,23 @@ fn keying_export() { 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 stream = ssl.accept(stream).unwrap(); let mut buf = [0; 32]; stream .ssl() .export_keying_material(&mut buf, label, Some(context)) .unwrap(); stream.write_all(&[0]).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 stream = ssl.connect(stream).unwrap(); let mut buf = [1; 32]; stream Loading @@ -1309,6 +1337,8 @@ fn keying_export() { .export_keying_material(&mut buf, label, Some(context)) .unwrap(); stream.read_exact(&mut [0]).unwrap(); let buf2 = guard.join().unwrap(); assert_eq!(buf, buf2); Loading Loading @@ -1374,7 +1404,8 @@ fn custom_extensions() { }, ).unwrap(); let ssl = Ssl::new(&ctx.build()).unwrap(); ssl.accept(stream).unwrap(); let mut stream = ssl.accept(stream).unwrap(); stream.write_all(&[0]).unwrap(); }); let stream = TcpStream::connect(addr).unwrap(); Loading @@ -1386,7 +1417,8 @@ fn custom_extensions() { |_, _, _, _| unreachable!(), ).unwrap(); let ssl = Ssl::new(&ctx.build()).unwrap(); ssl.connect(stream).unwrap(); let mut stream = ssl.connect(stream).unwrap(); stream.read_exact(&mut [0]).unwrap(); guard.join().unwrap(); assert!(FOUND_EXTENSION.load(Ordering::SeqCst)); Loading