Remove unimplemented OSSL111 stuff
This commit is contained in:
parent
1ae3ef578f
commit
8e54554cf8
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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" {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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!(
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
@ -423,152 +392,3 @@ where
|
|||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Reference in New Issue