Remove unimplemented OSSL111 stuff

This commit is contained in:
Ivan Nikulin 2020-11-11 00:43:27 +00:00
parent 1ae3ef578f
commit 8e54554cf8
13 changed files with 4 additions and 944 deletions

View File

@ -194,6 +194,7 @@ fn main() {
cfgs.push("ossl110");
cfgs.push("ossl110f");
cfgs.push("ossl110g");
cfgs.push("ossl111");
for cfg in cfgs {
println!("cargo:rustc-cfg={}", cfg);

View File

@ -57,8 +57,6 @@ extern "C" {
pub fn ASN1_INTEGER_to_BN(ai: *const ASN1_INTEGER, bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn ASN1_TIME_set_string(s: *mut ASN1_TIME, str: *const c_char) -> c_int;
#[cfg(ossl111)]
pub fn ASN1_TIME_set_string_X509(s: *mut ASN1_TIME, str: *const c_char) -> c_int;
}
extern "C" {

View File

@ -215,18 +215,6 @@ extern "C" {
pub fn EVP_sha256() -> *const EVP_MD;
pub fn EVP_sha384() -> *const EVP_MD;
pub fn EVP_sha512() -> *const EVP_MD;
#[cfg(ossl111)]
pub fn EVP_sha3_224() -> *const EVP_MD;
#[cfg(ossl111)]
pub fn EVP_sha3_256() -> *const EVP_MD;
#[cfg(ossl111)]
pub fn EVP_sha3_384() -> *const EVP_MD;
#[cfg(ossl111)]
pub fn EVP_sha3_512() -> *const EVP_MD;
#[cfg(ossl111)]
pub fn EVP_shake128() -> *const EVP_MD;
#[cfg(ossl111)]
pub fn EVP_shake256() -> *const EVP_MD;
pub fn EVP_des_ecb() -> *const EVP_CIPHER;
pub fn EVP_des_ede3() -> *const EVP_CIPHER;
pub fn EVP_des_ede3_cbc() -> *const EVP_CIPHER;

View File

@ -348,17 +348,6 @@ cfg_if! {
}
extern "C" {
#[cfg(ossl111)]
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,
>,
);
#[cfg(ossl111)]
pub fn SSL_CTX_set_stateless_cookie_verify_cb(
s: *mut SSL_CTX,
@ -459,20 +448,6 @@ extern "C" {
);
}
extern "C" {
#[cfg(ossl111)]
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;
}
#[cfg(ossl111)]
pub type SSL_CTX_keylog_cb_func =
Option<unsafe extern "C" fn(ssl: *const SSL, line: *const c_char)>;
@ -576,16 +551,12 @@ extern "C" {
pub fn SSL_CIPHER_get_name(cipher: *const SSL_CIPHER) -> *const c_char;
#[cfg(ossl111)]
pub fn SSL_CIPHER_standard_name(cipher: *const SSL_CIPHER) -> *const c_char;
#[cfg(ossl111)]
pub fn OPENSSL_cipher_name(rfc_name: *const c_char) -> *const c_char;
pub fn SSL_pending(ssl: *const SSL) -> c_int;
pub fn SSL_set_bio(ssl: *mut SSL, rbio: *mut BIO, wbio: *mut BIO);
pub fn SSL_get_rbio(ssl: *const SSL) -> *mut BIO;
pub fn SSL_get_wbio(ssl: *const SSL) -> *mut BIO;
#[cfg(ossl111)]
pub fn SSL_CTX_set_ciphersuites(ctx: *mut SSL_CTX, str: *const c_char) -> c_int;
#[cfg(ossl111)]
pub fn SSL_set_ciphersuites(ssl: *mut ::SSL, str: *const c_char) -> c_int;
pub fn SSL_set_verify(
ssl: *mut SSL,
@ -677,27 +648,6 @@ pub const SSL_CLIENT_HELLO_RETRY: c_int = -1;
pub type SSL_client_hello_cb_fn =
Option<unsafe extern "C" fn(s: *mut SSL, al: *mut c_int, arg: *mut c_void) -> c_int>;
extern "C" {
#[cfg(ossl111)]
pub fn SSL_CTX_set_client_hello_cb(
c: *mut SSL_CTX,
cb: SSL_client_hello_cb_fn,
arg: *mut c_void,
);
#[cfg(ossl111)]
pub fn SSL_client_hello_isv2(s: *mut SSL) -> c_int;
#[cfg(ossl111)]
pub fn SSL_client_hello_get0_legacy_version(s: *mut SSL) -> c_uint;
#[cfg(ossl111)]
pub fn SSL_client_hello_get0_random(s: *mut SSL, out: *mut *const c_uchar) -> size_t;
#[cfg(ossl111)]
pub fn SSL_client_hello_get0_session_id(s: *mut SSL, out: *mut *const c_uchar) -> size_t;
#[cfg(ossl111)]
pub fn SSL_client_hello_get0_ciphers(s: *mut SSL, out: *mut *const c_uchar) -> size_t;
#[cfg(ossl111)]
pub fn SSL_client_hello_get0_compression_methods(
s: *mut SSL,
out: *mut *const c_uchar,
) -> size_t;
#[cfg(ossl111)]
pub fn SSL_client_hello_get1_extensions_present(
s: *mut SSL,

View File

@ -8,6 +8,7 @@ fn main() {
cfgs.push("ossl110");
cfgs.push("ossl110f");
cfgs.push("ossl110g");
cfgs.push("ossl111");
for cfg in cfgs {
println!("cargo:rustc-cfg={}", cfg);

View File

@ -282,25 +282,6 @@ impl Asn1Time {
Ok(time)
}
}
/// Creates a new time corresponding to the specified X509 time string.
///
/// This corresponds to [`ASN1_TIME_set_string_X509`].
///
/// Requires OpenSSL 1.1.1 or newer.
///
/// [`ASN1_TIME_set_string_X509`]: https://www.openssl.org/docs/manmaster/man3/ASN1_TIME_set_string.html
#[cfg(ossl111)]
pub fn from_str_x509(s: &str) -> Result<Asn1Time, ErrorStack> {
unsafe {
let s = CString::new(s).unwrap();
let time = Asn1Time::new()?;
cvt(ffi::ASN1_TIME_set_string_X509(time.as_ptr(), s.as_ptr()))?;
Ok(time)
}
}
}
#[cfg(ossl102)]
@ -621,8 +602,6 @@ mod tests {
#[test]
fn time_from_str() {
Asn1Time::from_str("99991231235959Z").unwrap();
#[cfg(ossl111)]
Asn1Time::from_str_x509("99991231235959Z").unwrap();
}
#[test]

View File

@ -70,36 +70,6 @@ impl MessageDigest {
unsafe { MessageDigest(ffi::EVP_sha512()) }
}
#[cfg(ossl111)]
pub fn sha3_224() -> MessageDigest {
unsafe { MessageDigest(ffi::EVP_sha3_224()) }
}
#[cfg(ossl111)]
pub fn sha3_256() -> MessageDigest {
unsafe { MessageDigest(ffi::EVP_sha3_256()) }
}
#[cfg(ossl111)]
pub fn sha3_384() -> MessageDigest {
unsafe { MessageDigest(ffi::EVP_sha3_384()) }
}
#[cfg(ossl111)]
pub fn sha3_512() -> MessageDigest {
unsafe { MessageDigest(ffi::EVP_sha3_512()) }
}
#[cfg(ossl111)]
pub fn shake_128() -> MessageDigest {
unsafe { MessageDigest(ffi::EVP_shake128()) }
}
#[cfg(ossl111)]
pub fn shake_256() -> MessageDigest {
unsafe { MessageDigest(ffi::EVP_shake256()) }
}
#[allow(clippy::trivially_copy_pass_by_ref)]
pub fn as_ptr(&self) -> *const ffi::EVP_MD {
self.0
@ -159,21 +129,6 @@ use self::State::*;
/// assert_eq!(&*res, spec);
/// ```
///
/// Use an XOF hasher (OpenSSL 1.1.1+):
///
/// ```
/// #[cfg(ossl111)]
/// {
/// use openssl::hash::{hash_xof, MessageDigest};
///
/// let data = b"\x41\x6c\x6c\x20\x79\x6f\x75\x72\x20\x62\x61\x73\x65\x20\x61\x72\x65\x20\x62\x65\x6c\x6f\x6e\x67\x20\x74\x6f\x20\x75\x73";
/// let spec = b"\x49\xd0\x69\x7f\xf5\x08\x11\x1d\x8b\x84\xf1\x5e\x46\xda\xf1\x35";
/// let mut buf = vec![0; 16];
/// hash_xof(MessageDigest::shake_128(), data, buf.as_mut_slice()).unwrap();
/// assert_eq!(buf, spec);
/// }
/// ```
///
/// # Warning
///
/// Don't actually use MD5 and SHA-1 hashes, they're not secure anymore.
@ -394,19 +349,6 @@ mod tests {
assert_eq!(hex::encode(res), hashtest.1);
}
#[cfg(ossl111)]
fn hash_xof_test(hashtype: MessageDigest, hashtest: &(&str, &str)) {
let expected = Vec::from_hex(hashtest.1).unwrap();
let mut buf = vec![0; expected.len()];
hash_xof(
hashtype,
&Vec::from_hex(hashtest.0).unwrap(),
buf.as_mut_slice(),
)
.unwrap();
assert_eq!(buf, expected);
}
fn hash_recycle_test(h: &mut Hasher, hashtest: &(&str, &str)) {
h.write_all(&Vec::from_hex(hashtest.0).unwrap()).unwrap();
let res = h.finish().unwrap();
@ -511,84 +453,6 @@ mod tests {
}
}
#[cfg(ossl111)]
#[test]
fn test_sha3_224() {
let tests = [(
"416c6c20796f75722062617365206172652062656c6f6e6720746f207573",
"1de092dd9fbcbbf450f26264f4778abd48af851f2832924554c56913",
)];
for test in tests.iter() {
hash_test(MessageDigest::sha3_224(), test);
}
}
#[cfg(ossl111)]
#[test]
fn test_sha3_256() {
let tests = [(
"416c6c20796f75722062617365206172652062656c6f6e6720746f207573",
"b38e38f08bc1c0091ed4b5f060fe13e86aa4179578513ad11a6e3abba0062f61",
)];
for test in tests.iter() {
hash_test(MessageDigest::sha3_256(), test);
}
}
#[cfg(ossl111)]
#[test]
fn test_sha3_384() {
let tests = [("416c6c20796f75722062617365206172652062656c6f6e6720746f207573",
"966ee786ab3482dd811bf7c8fa8db79aa1f52f6c3c369942ef14240ebd857c6ff626ec35d9e131ff64d328\
ef2008ff16"
)];
for test in tests.iter() {
hash_test(MessageDigest::sha3_384(), test);
}
}
#[cfg(ossl111)]
#[test]
fn test_sha3_512() {
let tests = [("416c6c20796f75722062617365206172652062656c6f6e6720746f207573",
"c072288ef728cd53a029c47687960b9225893532f42b923156e37020bdc1eda753aafbf30af859d4f4c3a1\
807caee3a79f8eb02dcd61589fbbdf5f40c8787a72"
)];
for test in tests.iter() {
hash_test(MessageDigest::sha3_512(), test);
}
}
#[cfg(ossl111)]
#[test]
fn test_shake_128() {
let tests = [(
"416c6c20796f75722062617365206172652062656c6f6e6720746f207573",
"49d0697ff508111d8b84f15e46daf135",
)];
for test in tests.iter() {
hash_xof_test(MessageDigest::shake_128(), test);
}
}
#[cfg(ossl111)]
#[test]
fn test_shake_256() {
let tests = [(
"416c6c20796f75722062617365206172652062656c6f6e6720746f207573",
"4e2dfdaa75d1e049d0eaeffe28e76b17cea47b650fb8826fe48b94664326a697",
)];
for test in tests.iter() {
hash_xof_test(MessageDigest::shake_256(), test);
}
}
#[test]
fn from_nid() {
assert_eq!(

View File

@ -353,30 +353,6 @@ impl<T> PKey<T> {
}
impl PKey<Private> {
/// Generates a new private Ed25519 key
#[cfg(ossl111)]
pub fn generate_x25519() -> Result<PKey<Private>, ErrorStack> {
PKey::generate_eddsa(ffi::EVP_PKEY_X25519)
}
/// Generates a new private Ed448 key
#[cfg(ossl111)]
pub fn generate_x448() -> Result<PKey<Private>, ErrorStack> {
PKey::generate_eddsa(ffi::EVP_PKEY_X448)
}
/// Generates a new private Ed25519 key
#[cfg(ossl111)]
pub fn generate_ed25519() -> Result<PKey<Private>, ErrorStack> {
PKey::generate_eddsa(ffi::EVP_PKEY_ED25519)
}
/// Generates a new private Ed448 key
#[cfg(ossl111)]
pub fn generate_ed448() -> Result<PKey<Private>, ErrorStack> {
PKey::generate_eddsa(ffi::EVP_PKEY_ED448)
}
private_key_from_pem! {
/// Deserializes a private key from a PEM-encoded key type specific format.
///

View File

@ -609,6 +609,7 @@ unsafe fn EVP_DigestVerifyFinal(
#[cfg(test)]
mod test {
use super::RsaPssSaltlen;
use hex::{self, FromHex};
use ec::{EcGroup, EcKey};
@ -685,18 +686,6 @@ mod test {
assert!(verifier.verify(&signature).unwrap());
}
#[test]
#[cfg(ossl111)]
fn eddsa() {
let key = PKey::generate_ed25519().unwrap();
let mut signer = Signer::new_without_digest(&key).unwrap();
let signature = signer.sign_oneshot_to_vec(b"hello world").unwrap();
let mut verifier = Verifier::new_without_digest(&key).unwrap();
assert!(verifier.verify_oneshot(&signature, b"hello world").unwrap());
}
#[test]
#[cfg(ossl111)]
fn rsa_sign_verify() {

View File

@ -20,14 +20,10 @@ use ec::EcKey;
use error::ErrorStack;
#[cfg(any(ossl102, libressl261))]
use ssl::AlpnError;
#[cfg(ossl111)]
use ssl::{ClientHelloResponse, ExtensionContext};
use ssl::{
SniError, Ssl, SslAlert, SslContext, SslContextRef, SslRef, SslSession, SslSessionRef,
SESSION_CTX_INDEX,
};
#[cfg(ossl111)]
use x509::X509Ref;
use x509::{X509StoreContext, X509StoreContextRef};
pub extern "C" fn raw_verify<F>(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_CTX) -> c_int
@ -379,33 +375,6 @@ where
callback(ssl, line);
}
#[cfg(ossl111)]
pub unsafe extern "C" fn raw_stateless_cookie_generate<F>(
ssl: *mut ffi::SSL,
cookie: *mut c_uchar,
cookie_len: *mut size_t,
) -> c_int
where
F: Fn(&mut SslRef, &mut [u8]) -> Result<usize, ErrorStack> + 'static + Sync + Send,
{
let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: stateless cookie generate callback missing") as *const F;
let slice = slice::from_raw_parts_mut(cookie as *mut u8, ffi::SSL_COOKIE_LENGTH as usize);
match (*callback)(ssl, slice) {
Ok(len) => {
*cookie_len = len as size_t;
1
}
Err(e) => {
e.put();
0
}
}
}
#[cfg(ossl111)]
pub unsafe extern "C" fn raw_stateless_cookie_verify<F>(
ssl: *mut ffi::SSL,
@ -422,153 +391,4 @@ where
.expect("BUG: stateless cookie verify callback missing") as *const F;
let slice = slice::from_raw_parts(cookie as *const c_uchar as *const u8, cookie_len as usize);
(*callback)(ssl, slice) as c_int
}
#[cfg(ossl111)]
pub struct CustomExtAddState<T>(Option<T>);
#[cfg(ossl111)]
pub extern "C" fn raw_custom_ext_add<F, T>(
ssl: *mut ffi::SSL,
_: c_uint,
context: c_uint,
out: *mut *const c_uchar,
outlen: *mut size_t,
x: *mut ffi::X509,
chainidx: size_t,
al: *mut c_int,
_: *mut c_void,
) -> c_int
where
F: Fn(&mut SslRef, ExtensionContext, Option<(usize, &X509Ref)>) -> Result<Option<T>, SslAlert>
+ 'static
+ Sync
+ Send,
T: AsRef<[u8]> + 'static + Sync + Send,
{
unsafe {
let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: custom ext add callback missing") as *const F;
let ectx = ExtensionContext::from_bits_truncate(context);
let cert = if ectx.contains(ExtensionContext::TLS1_3_CERTIFICATE) {
Some((chainidx, X509Ref::from_ptr(x)))
} else {
None
};
match (*callback)(ssl, ectx, cert) {
Ok(None) => 0,
Ok(Some(buf)) => {
*outlen = buf.as_ref().len();
*out = buf.as_ref().as_ptr();
let idx = Ssl::cached_ex_index::<CustomExtAddState<T>>();
let mut buf = Some(buf);
let new = match ssl.ex_data_mut(idx) {
Some(state) => {
state.0 = buf.take();
false
}
None => true,
};
if new {
ssl.set_ex_data(idx, CustomExtAddState(buf));
}
1
}
Err(alert) => {
*al = alert.0;
-1
}
}
}
}
#[cfg(ossl111)]
pub extern "C" fn raw_custom_ext_free<T>(
ssl: *mut ffi::SSL,
_: c_uint,
_: c_uint,
_: *mut *const c_uchar,
_: *mut c_void,
) where
T: 'static + Sync + Send,
{
unsafe {
let ssl = SslRef::from_ptr_mut(ssl);
let idx = Ssl::cached_ex_index::<CustomExtAddState<T>>();
if let Some(state) = ssl.ex_data_mut(idx) {
state.0 = None;
}
}
}
#[cfg(ossl111)]
pub extern "C" fn raw_custom_ext_parse<F>(
ssl: *mut ffi::SSL,
_: c_uint,
context: c_uint,
input: *const c_uchar,
inlen: size_t,
x: *mut ffi::X509,
chainidx: size_t,
al: *mut c_int,
_: *mut c_void,
) -> c_int
where
F: Fn(&mut SslRef, ExtensionContext, &[u8], Option<(usize, &X509Ref)>) -> Result<(), SslAlert>
+ 'static
+ Sync
+ Send,
{
unsafe {
let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl
.ssl_context()
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: custom ext parse callback missing") as *const F;
let ectx = ExtensionContext::from_bits_truncate(context);
let slice = slice::from_raw_parts(input as *const u8, inlen as usize);
let cert = if ectx.contains(ExtensionContext::TLS1_3_CERTIFICATE) {
Some((chainidx, X509Ref::from_ptr(x)))
} else {
None
};
match (*callback)(ssl, ectx, slice, cert) {
Ok(()) => 1,
Err(alert) => {
*al = alert.0;
0
}
}
}
}
#[cfg(ossl111)]
pub unsafe extern "C" fn raw_client_hello<F>(
ssl: *mut ffi::SSL,
al: *mut c_int,
arg: *mut c_void,
) -> c_int
where
F: Fn(&mut SslRef, &mut SslAlert) -> Result<ClientHelloResponse, ErrorStack>
+ 'static
+ Sync
+ Send,
{
let ssl = SslRef::from_ptr_mut(ssl);
let callback = arg as *const F;
let mut alert = SslAlert(*al);
let r = (*callback)(ssl, &mut alert);
*al = alert.0;
match r {
Ok(c) => c.0,
Err(e) => {
e.put();
ffi::SSL_CLIENT_HELLO_ERROR
}
}
}
}

View File

@ -227,28 +227,6 @@ impl SslAcceptor {
ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:\
DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384"
)?;
#[cfg(ossl111)]
ctx.set_ciphersuites(
"TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256",
)?;
Ok(SslAcceptorBuilder(ctx))
}
/// Creates a new builder configured to connect to modern clients.
///
/// This corresponds to the modern configuration of version 5 of Mozilla's server side TLS recommendations.
/// See its [documentation][docs] for more details on specifics.
///
/// Requires OpenSSL 1.1.1 or newer.
///
/// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS
#[cfg(ossl111)]
pub fn mozilla_modern_v5(method: SslMethod) -> Result<SslAcceptorBuilder, ErrorStack> {
let mut ctx = ctx(method)?;
ctx.set_options(SslOptions::NO_SSL_MASK & !SslOptions::NO_TLSV1_3);
ctx.set_ciphersuites(
"TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256",
)?;
Ok(SslAcceptorBuilder(ctx))
}

View File

@ -112,26 +112,6 @@ mod error;
#[cfg(test)]
mod test;
/// Returns the OpenSSL name of a cipher corresponding to an RFC-standard cipher name.
///
/// If the cipher has no corresponding OpenSSL name, the string `(NONE)` is returned.
///
/// Requires OpenSSL 1.1.1 or newer.
///
/// This corresponds to [`OPENSSL_cipher_name`]
///
/// [`OPENSSL_cipher_name`]: https://www.openssl.org/docs/manmaster/man3/SSL_CIPHER_get_name.html
#[cfg(ossl111)]
pub fn cipher_name(std_name: &str) -> &'static str {
unsafe {
ffi::init();
let s = CString::new(std_name).unwrap();
let ptr = ffi::OPENSSL_cipher_name(s.as_ptr());
CStr::from_ptr(ptr).to_str().unwrap()
}
}
bitflags! {
/// Options controlling the behavior of an `SslContext`.
pub struct SslOptions: c_uint {
@ -1033,30 +1013,6 @@ impl SslContextBuilder {
}
}
/// Sets the list of supported ciphers for the TLSv1.3 protocol.
///
/// The `set_cipher_list` method controls the 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.
@ -1488,27 +1444,6 @@ impl SslContextBuilder {
}
}
/// Sets the callback for generating an application cookie for TLS1.3
/// stateless handshakes.
///
/// The callback will be called with the SSL context and a slice into which the cookie
/// should be written. The callback should return the number of bytes written.
///
/// This corresponds to `SSL_CTX_set_stateless_cookie_generate_cb`.
#[cfg(ossl111)]
pub fn set_stateless_cookie_generate_cb<F>(&mut self, callback: F)
where
F: Fn(&mut SslRef, &mut [u8]) -> Result<usize, ErrorStack> + 'static + Sync + Send,
{
unsafe {
self.set_ex_data(SslContext::cached_ex_index::<F>(), callback);
ffi::SSL_CTX_set_stateless_cookie_generate_cb(
self.as_ptr(),
Some(raw_stateless_cookie_generate::<F>),
);
}
}
/// Sets the callback for verifying an application cookie for TLS1.3
/// stateless handshakes.
///
@ -1553,63 +1488,6 @@ impl SslContextBuilder {
}
}
/// Adds a custom extension for a TLS/DTLS client or server for all supported protocol versions.
///
/// Requires OpenSSL 1.1.1 or newer.
///
/// This corresponds to [`SSL_CTX_add_custom_ext`].
///
/// [`SSL_CTX_add_custom_ext`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_add_custom_ext.html
#[cfg(ossl111)]
pub fn add_custom_ext<AddFn, ParseFn, T>(
&mut self,
ext_type: u16,
context: ExtensionContext,
add_cb: AddFn,
parse_cb: ParseFn,
) -> Result<(), ErrorStack>
where
AddFn: Fn(
&mut SslRef,
ExtensionContext,
Option<(usize, &X509Ref)>,
) -> Result<Option<T>, SslAlert>
+ 'static
+ Sync
+ Send,
T: AsRef<[u8]> + 'static + Sync + Send,
ParseFn: Fn(
&mut SslRef,
ExtensionContext,
&[u8],
Option<(usize, &X509Ref)>,
) -> Result<(), SslAlert>
+ 'static
+ Sync
+ Send,
{
let ret = unsafe {
self.set_ex_data(SslContext::cached_ex_index::<AddFn>(), add_cb);
self.set_ex_data(SslContext::cached_ex_index::<ParseFn>(), parse_cb);
ffi::SSL_CTX_add_custom_ext(
self.as_ptr(),
ext_type as c_uint,
context.bits(),
Some(raw_custom_ext_add::<AddFn, T>),
Some(raw_custom_ext_free::<T>),
ptr::null_mut(),
Some(raw_custom_ext_parse::<ParseFn>),
ptr::null_mut(),
)
};
if ret == 1 {
Ok(())
} else {
Err(ErrorStack::get())
}
}
/// Sets the maximum amount of early data that will be accepted on incoming connections.
///
/// Defaults to 0.
@ -1628,31 +1506,6 @@ impl SslContextBuilder {
}
}
/// Sets a callback which will be invoked just after the client's hello message is received.
///
/// Requires OpenSSL 1.1.1 or newer.
///
/// This corresponds to [`SSL_CTX_set_client_hello_cb`].
///
/// [`SSL_CTX_set_client_hello_cb`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_client_hello_cb.html
#[cfg(ossl111)]
pub fn set_client_hello_callback<F>(&mut self, callback: F)
where
F: Fn(&mut SslRef, &mut SslAlert) -> Result<ClientHelloResponse, ErrorStack>
+ 'static
+ Sync
+ Send,
{
unsafe {
let ptr = self.set_ex_data_inner(SslContext::cached_ex_index::<F>(), callback);
ffi::SSL_CTX_set_client_hello_cb(
self.as_ptr(),
Some(callbacks::raw_client_hello::<F>),
ptr,
);
}
}
/// Sets the context's session cache size limit, returning the previous limit.
///
/// A value of 0 means that the cache size is unbounded.
@ -3109,129 +2962,6 @@ impl SslRef {
unsafe { ffi::SSL_is_init_finished(self.as_ptr()) != 0 }
}
/// Determines if the client's hello message is in the SSLv2 format.
///
/// This can only be used inside of the client hello callback. Otherwise, `false` is returned.
///
/// Requires OpenSSL 1.1.1 or newer.
///
/// This corresponds to [`SSL_client_hello_isv2`].
///
/// [`SSL_client_hello_isv2`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_client_hello_cb.html
#[cfg(ossl111)]
pub fn client_hello_isv2(&self) -> bool {
unsafe { ffi::SSL_client_hello_isv2(self.as_ptr()) != 0 }
}
/// Returns the legacy version field of the client's hello message.
///
/// This can only be used inside of the client hello callback. Otherwise, `None` is returned.
///
/// Requires OpenSSL 1.1.1 or newer.
///
/// This corresponds to [`SSL_client_hello_get0_legacy_version`].
///
/// [`SSL_client_hello_get0_legacy_version`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_client_hello_cb.html
#[cfg(ossl111)]
pub fn client_hello_legacy_version(&self) -> Option<SslVersion> {
unsafe {
let version = ffi::SSL_client_hello_get0_legacy_version(self.as_ptr());
if version == 0 {
None
} else {
Some(SslVersion(version as c_int))
}
}
}
/// Returns the random field of the client's hello message.
///
/// This can only be used inside of the client hello callback. Otherwise, `None` is returend.
///
/// Requires OpenSSL 1.1.1 or newer.
///
/// This corresponds to [`SSL_client_hello_get0_random`].
///
/// [`SSL_client_hello_get0_random`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_client_hello_cb.html
#[cfg(ossl111)]
pub fn client_hello_random(&self) -> Option<&[u8]> {
unsafe {
let mut ptr = ptr::null();
let len = ffi::SSL_client_hello_get0_random(self.as_ptr(), &mut ptr);
if len == 0 {
None
} else {
Some(slice::from_raw_parts(ptr, len))
}
}
}
/// Returns the session ID field of the client's hello message.
///
/// This can only be used inside of the client hello callback. Otherwise, `None` is returend.
///
/// Requires OpenSSL 1.1.1 or newer.
///
/// This corresponds to [`SSL_client_hello_get0_session_id`].
///
/// [`SSL_client_hello_get0_session_id`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_client_hello_cb.html
#[cfg(ossl111)]
pub fn client_hello_session_id(&self) -> Option<&[u8]> {
unsafe {
let mut ptr = ptr::null();
let len = ffi::SSL_client_hello_get0_session_id(self.as_ptr(), &mut ptr);
if len == 0 {
None
} else {
Some(slice::from_raw_parts(ptr, len))
}
}
}
/// Returns the ciphers field of the client's hello message.
///
/// This can only be used inside of the client hello callback. Otherwise, `None` is returend.
///
/// Requires OpenSSL 1.1.1 or newer.
///
/// This corresponds to [`SSL_client_hello_get0_ciphers`].
///
/// [`SSL_client_hello_get0_ciphers`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_client_hello_cb.html
#[cfg(ossl111)]
pub fn client_hello_ciphers(&self) -> Option<&[u8]> {
unsafe {
let mut ptr = ptr::null();
let len = ffi::SSL_client_hello_get0_ciphers(self.as_ptr(), &mut ptr);
if len == 0 {
None
} else {
Some(slice::from_raw_parts(ptr, len))
}
}
}
/// Returns the compression methods field of the client's hello message.
///
/// This can only be used inside of the client hello callback. Otherwise, `None` is returend.
///
/// Requires OpenSSL 1.1.1 or newer.
///
/// This corresponds to [`SSL_client_hello_get0_compression_methods`].
///
/// [`SSL_client_hello_get0_compression_methods`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_client_hello_cb.html
#[cfg(ossl111)]
pub fn client_hello_compression_methods(&self) -> Option<&[u8]> {
unsafe {
let mut ptr = ptr::null();
let len = ffi::SSL_client_hello_get0_compression_methods(self.as_ptr(), &mut ptr);
if len == 0 {
None
} else {
Some(slice::from_raw_parts(ptr, len))
}
}
}
/// Sets the MTU used for DTLS connections.
///
/// This corresponds to `SSL_set_mtu`.

View File

@ -793,11 +793,6 @@ fn connector_client_server_mozilla_intermediate_v5() {
test_mozilla_server(SslAcceptor::mozilla_intermediate_v5);
}
#[test]
#[cfg(ossl111)]
fn connector_client_server_mozilla_modern_v5() {
test_mozilla_server(SslAcceptor::mozilla_modern_v5);
}
#[test]
fn shutdown() {
@ -1037,43 +1032,6 @@ fn no_version_overlap() {
client.connect_err();
}
#[test]
#[cfg(ossl111)]
fn custom_extensions() {
static FOUND_EXTENSION: AtomicBool = AtomicBool::new(false);
let mut server = Server::builder();
server
.ctx()
.add_custom_ext(
12345,
ExtensionContext::CLIENT_HELLO,
|_, _, _| -> Result<Option<&'static [u8]>, _> { unreachable!() },
|_, _, data, _| {
FOUND_EXTENSION.store(data == b"hello", Ordering::SeqCst);
Ok(())
},
)
.unwrap();
let server = server.build();
let mut client = server.client();
client
.ctx()
.add_custom_ext(
12345,
ssl::ExtensionContext::CLIENT_HELLO,
|_, _, _| Ok(Some(b"hello")),
|_, _, _, _| unreachable!(),
)
.unwrap();
client.connect();
assert!(FOUND_EXTENSION.load(Ordering::SeqCst));
}
fn _check_kinds() {
fn is_send<T: Send>() {}
fn is_sync<T: Sync>() {}
@ -1082,143 +1040,6 @@ fn _check_kinds() {
is_sync::<SslStream<TcpStream>>();
}
#[test]
#[cfg(ossl111)]
fn stateless() {
use super::SslOptions;
#[derive(Debug)]
struct MemoryStream {
incoming: io::Cursor<Vec<u8>>,
outgoing: Vec<u8>,
}
impl MemoryStream {
pub fn new() -> Self {
Self {
incoming: io::Cursor::new(Vec::new()),
outgoing: Vec::new(),
}
}
pub fn extend_incoming(&mut self, data: &[u8]) {
self.incoming.get_mut().extend_from_slice(data);
}
pub fn take_outgoing(&mut self) -> Outgoing {
Outgoing(&mut self.outgoing)
}
}
impl Read for MemoryStream {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let n = self.incoming.read(buf)?;
if self.incoming.position() == self.incoming.get_ref().len() as u64 {
self.incoming.set_position(0);
self.incoming.get_mut().clear();
}
if n == 0 {
return Err(io::Error::new(
io::ErrorKind::WouldBlock,
"no data available",
));
}
Ok(n)
}
}
impl Write for MemoryStream {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.outgoing.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
pub struct Outgoing<'a>(&'a mut Vec<u8>);
impl<'a> Drop for Outgoing<'a> {
fn drop(&mut self) {
self.0.clear();
}
}
impl<'a> ::std::ops::Deref for Outgoing<'a> {
type Target = [u8];
fn deref(&self) -> &[u8] {
&self.0
}
}
impl<'a> AsRef<[u8]> for Outgoing<'a> {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
fn send(from: &mut MemoryStream, to: &mut MemoryStream) {
to.extend_incoming(&from.take_outgoing());
}
fn hs<S: ::std::fmt::Debug>(
stream: Result<SslStream<S>, HandshakeError<S>>,
) -> Result<SslStream<S>, MidHandshakeSslStream<S>> {
match stream {
Ok(stream) => Ok(stream),
Err(HandshakeError::WouldBlock(stream)) => Err(stream),
Err(e) => panic!("unexpected error: {:?}", e),
}
}
//
// Setup
//
let mut client_ctx = SslContext::builder(SslMethod::tls()).unwrap();
client_ctx.clear_options(SslOptions::ENABLE_MIDDLEBOX_COMPAT);
let client_stream = Ssl::new(&client_ctx.build()).unwrap();
let mut server_ctx = SslContext::builder(SslMethod::tls()).unwrap();
server_ctx
.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM)
.unwrap();
server_ctx
.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM)
.unwrap();
const COOKIE: &[u8] = b"chocolate chip";
server_ctx.set_stateless_cookie_generate_cb(|_tls, buf| {
buf[0..COOKIE.len()].copy_from_slice(COOKIE);
Ok(COOKIE.len())
});
server_ctx.set_stateless_cookie_verify_cb(|_tls, buf| buf == COOKIE);
let mut server_stream =
ssl::SslStreamBuilder::new(Ssl::new(&server_ctx.build()).unwrap(), MemoryStream::new());
//
// Handshake
//
// Initial ClientHello
let mut client_stream = hs(client_stream.connect(MemoryStream::new())).unwrap_err();
send(client_stream.get_mut(), server_stream.get_mut());
// HelloRetryRequest
assert!(!server_stream.stateless().unwrap());
send(server_stream.get_mut(), client_stream.get_mut());
// Second ClientHello
let mut client_stream = hs(client_stream.handshake()).unwrap_err();
send(client_stream.get_mut(), server_stream.get_mut());
// OldServerHello
assert!(server_stream.stateless().unwrap());
let mut server_stream = hs(server_stream.accept()).unwrap_err();
send(server_stream.get_mut(), client_stream.get_mut());
// Finished
let mut client_stream = hs(client_stream.handshake()).unwrap();
send(client_stream.get_mut(), server_stream.get_mut());
hs(server_stream.handshake()).unwrap();
}
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
#[test]
fn psk_ciphers() {
@ -1280,41 +1101,6 @@ fn sni_callback_swapped_ctx() {
assert!(CALLED_BACK.load(Ordering::SeqCst));
}
#[test]
#[cfg(ossl111)]
fn client_hello() {
static CALLED_BACK: AtomicBool = AtomicBool::new(false);
let mut server = Server::builder();
server.ctx().set_client_hello_callback(|ssl, _| {
assert!(!ssl.client_hello_isv2());
assert_eq!(ssl.client_hello_legacy_version(), Some(SslVersion::TLS1_2));
assert!(ssl.client_hello_random().is_some());
assert!(ssl.client_hello_session_id().is_some());
assert!(ssl.client_hello_ciphers().is_some());
assert!(ssl.client_hello_compression_methods().is_some());
CALLED_BACK.store(true, Ordering::SeqCst);
Ok(ClientHelloResponse::SUCCESS)
});
let server = server.build();
server.client().connect();
assert!(CALLED_BACK.load(Ordering::SeqCst));
}
#[test]
#[cfg(ossl111)]
fn openssl_cipher_name() {
assert_eq!(
super::cipher_name("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"),
"ECDHE-RSA-AES256-SHA384",
);
assert_eq!(super::cipher_name("asdf"), "(NONE)");
}
#[test]
fn session_cache_size() {
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();