192f3ab15Sopenharmony_ci#![allow(unused_imports)]
292f3ab15Sopenharmony_ci
392f3ab15Sopenharmony_ciuse std::env;
492f3ab15Sopenharmony_ciuse std::fs::File;
592f3ab15Sopenharmony_ciuse std::io::prelude::*;
692f3ab15Sopenharmony_ciuse std::io::{self, BufReader};
792f3ab15Sopenharmony_ciuse std::iter;
892f3ab15Sopenharmony_ciuse std::mem;
992f3ab15Sopenharmony_ciuse std::net::UdpSocket;
1092f3ab15Sopenharmony_ciuse std::net::{SocketAddr, TcpListener, TcpStream};
1192f3ab15Sopenharmony_ciuse std::path::Path;
1292f3ab15Sopenharmony_ciuse std::process::{Child, ChildStdin, Command, Stdio};
1392f3ab15Sopenharmony_ciuse std::sync::atomic::{AtomicBool, Ordering};
1492f3ab15Sopenharmony_ciuse std::thread;
1592f3ab15Sopenharmony_ciuse std::time::Duration;
1692f3ab15Sopenharmony_ci
1792f3ab15Sopenharmony_ciuse crate::dh::Dh;
1892f3ab15Sopenharmony_ciuse crate::error::ErrorStack;
1992f3ab15Sopenharmony_ciuse crate::hash::MessageDigest;
2092f3ab15Sopenharmony_ci#[cfg(not(boringssl))]
2192f3ab15Sopenharmony_ciuse crate::ocsp::{OcspResponse, OcspResponseStatus};
2292f3ab15Sopenharmony_ciuse crate::pkey::PKey;
2392f3ab15Sopenharmony_ciuse crate::srtp::SrtpProfileId;
2492f3ab15Sopenharmony_ciuse crate::ssl::test::server::Server;
2592f3ab15Sopenharmony_ci#[cfg(any(ossl110, ossl111, libressl261))]
2692f3ab15Sopenharmony_ciuse crate::ssl::SslVersion;
2792f3ab15Sopenharmony_ciuse crate::ssl::{self, NameType, SslConnectorBuilder};
2892f3ab15Sopenharmony_ci#[cfg(ossl111)]
2992f3ab15Sopenharmony_ciuse crate::ssl::{ClientHelloResponse, ExtensionContext};
3092f3ab15Sopenharmony_ciuse crate::ssl::{
3192f3ab15Sopenharmony_ci    Error, HandshakeError, MidHandshakeSslStream, ShutdownResult, ShutdownState, Ssl, SslAcceptor,
3292f3ab15Sopenharmony_ci    SslAcceptorBuilder, SslConnector, SslContext, SslContextBuilder, SslFiletype, SslMethod,
3392f3ab15Sopenharmony_ci    SslOptions, SslSessionCacheMode, SslStream, SslVerifyMode, StatusType,
3492f3ab15Sopenharmony_ci};
3592f3ab15Sopenharmony_ci#[cfg(ossl102)]
3692f3ab15Sopenharmony_ciuse crate::x509::store::X509StoreBuilder;
3792f3ab15Sopenharmony_ci#[cfg(ossl102)]
3892f3ab15Sopenharmony_ciuse crate::x509::verify::X509CheckFlags;
3992f3ab15Sopenharmony_ciuse crate::x509::{X509Name, X509StoreContext, X509VerifyResult, X509};
4092f3ab15Sopenharmony_ci
4192f3ab15Sopenharmony_cimod server;
4292f3ab15Sopenharmony_ci
4392f3ab15Sopenharmony_cistatic ROOT_CERT: &[u8] = include_bytes!("../../../test/root-ca.pem");
4492f3ab15Sopenharmony_cistatic CERT: &[u8] = include_bytes!("../../../test/cert.pem");
4592f3ab15Sopenharmony_cistatic KEY: &[u8] = include_bytes!("../../../test/key.pem");
4692f3ab15Sopenharmony_ci
4792f3ab15Sopenharmony_ci#[test]
4892f3ab15Sopenharmony_cifn verify_untrusted() {
4992f3ab15Sopenharmony_ci    let mut server = Server::builder();
5092f3ab15Sopenharmony_ci    server.should_error();
5192f3ab15Sopenharmony_ci    let server = server.build();
5292f3ab15Sopenharmony_ci
5392f3ab15Sopenharmony_ci    let mut client = server.client();
5492f3ab15Sopenharmony_ci    client.ctx().set_verify(SslVerifyMode::PEER);
5592f3ab15Sopenharmony_ci
5692f3ab15Sopenharmony_ci    client.connect_err();
5792f3ab15Sopenharmony_ci}
5892f3ab15Sopenharmony_ci
5992f3ab15Sopenharmony_ci#[test]
6092f3ab15Sopenharmony_cifn verify_trusted() {
6192f3ab15Sopenharmony_ci    let server = Server::builder().build();
6292f3ab15Sopenharmony_ci
6392f3ab15Sopenharmony_ci    let mut client = server.client();
6492f3ab15Sopenharmony_ci    client.ctx().set_ca_file("test/root-ca.pem").unwrap();
6592f3ab15Sopenharmony_ci
6692f3ab15Sopenharmony_ci    client.connect();
6792f3ab15Sopenharmony_ci}
6892f3ab15Sopenharmony_ci
6992f3ab15Sopenharmony_ci#[test]
7092f3ab15Sopenharmony_ci#[cfg(ossl102)]
7192f3ab15Sopenharmony_cifn verify_trusted_with_set_cert() {
7292f3ab15Sopenharmony_ci    let server = Server::builder().build();
7392f3ab15Sopenharmony_ci
7492f3ab15Sopenharmony_ci    let mut store = X509StoreBuilder::new().unwrap();
7592f3ab15Sopenharmony_ci    let x509 = X509::from_pem(ROOT_CERT).unwrap();
7692f3ab15Sopenharmony_ci    store.add_cert(x509).unwrap();
7792f3ab15Sopenharmony_ci
7892f3ab15Sopenharmony_ci    let mut client = server.client();
7992f3ab15Sopenharmony_ci    client.ctx().set_verify(SslVerifyMode::PEER);
8092f3ab15Sopenharmony_ci    client.ctx().set_verify_cert_store(store.build()).unwrap();
8192f3ab15Sopenharmony_ci
8292f3ab15Sopenharmony_ci    client.connect();
8392f3ab15Sopenharmony_ci}
8492f3ab15Sopenharmony_ci
8592f3ab15Sopenharmony_ci#[test]
8692f3ab15Sopenharmony_cifn verify_untrusted_callback_override_ok() {
8792f3ab15Sopenharmony_ci    static CALLED_BACK: AtomicBool = AtomicBool::new(false);
8892f3ab15Sopenharmony_ci
8992f3ab15Sopenharmony_ci    let server = Server::builder().build();
9092f3ab15Sopenharmony_ci
9192f3ab15Sopenharmony_ci    let mut client = server.client();
9292f3ab15Sopenharmony_ci    client
9392f3ab15Sopenharmony_ci        .ctx()
9492f3ab15Sopenharmony_ci        .set_verify_callback(SslVerifyMode::PEER, |_, x509| {
9592f3ab15Sopenharmony_ci            CALLED_BACK.store(true, Ordering::SeqCst);
9692f3ab15Sopenharmony_ci            assert!(x509.current_cert().is_some());
9792f3ab15Sopenharmony_ci            true
9892f3ab15Sopenharmony_ci        });
9992f3ab15Sopenharmony_ci
10092f3ab15Sopenharmony_ci    client.connect();
10192f3ab15Sopenharmony_ci    assert!(CALLED_BACK.load(Ordering::SeqCst));
10292f3ab15Sopenharmony_ci}
10392f3ab15Sopenharmony_ci
10492f3ab15Sopenharmony_ci#[test]
10592f3ab15Sopenharmony_cifn verify_untrusted_callback_override_bad() {
10692f3ab15Sopenharmony_ci    let mut server = Server::builder();
10792f3ab15Sopenharmony_ci    server.should_error();
10892f3ab15Sopenharmony_ci    let server = server.build();
10992f3ab15Sopenharmony_ci
11092f3ab15Sopenharmony_ci    let mut client = server.client();
11192f3ab15Sopenharmony_ci    client
11292f3ab15Sopenharmony_ci        .ctx()
11392f3ab15Sopenharmony_ci        .set_verify_callback(SslVerifyMode::PEER, |_, _| false);
11492f3ab15Sopenharmony_ci
11592f3ab15Sopenharmony_ci    client.connect_err();
11692f3ab15Sopenharmony_ci}
11792f3ab15Sopenharmony_ci
11892f3ab15Sopenharmony_ci#[test]
11992f3ab15Sopenharmony_cifn verify_trusted_callback_override_ok() {
12092f3ab15Sopenharmony_ci    static CALLED_BACK: AtomicBool = AtomicBool::new(false);
12192f3ab15Sopenharmony_ci
12292f3ab15Sopenharmony_ci    let server = Server::builder().build();
12392f3ab15Sopenharmony_ci
12492f3ab15Sopenharmony_ci    let mut client = server.client();
12592f3ab15Sopenharmony_ci    client.ctx().set_ca_file("test/root-ca.pem").unwrap();
12692f3ab15Sopenharmony_ci    client
12792f3ab15Sopenharmony_ci        .ctx()
12892f3ab15Sopenharmony_ci        .set_verify_callback(SslVerifyMode::PEER, |_, x509| {
12992f3ab15Sopenharmony_ci            CALLED_BACK.store(true, Ordering::SeqCst);
13092f3ab15Sopenharmony_ci            assert!(x509.current_cert().is_some());
13192f3ab15Sopenharmony_ci            true
13292f3ab15Sopenharmony_ci        });
13392f3ab15Sopenharmony_ci
13492f3ab15Sopenharmony_ci    client.connect();
13592f3ab15Sopenharmony_ci    assert!(CALLED_BACK.load(Ordering::SeqCst));
13692f3ab15Sopenharmony_ci}
13792f3ab15Sopenharmony_ci
13892f3ab15Sopenharmony_ci#[test]
13992f3ab15Sopenharmony_cifn verify_trusted_callback_override_bad() {
14092f3ab15Sopenharmony_ci    let mut server = Server::builder();
14192f3ab15Sopenharmony_ci    server.should_error();
14292f3ab15Sopenharmony_ci    let server = server.build();
14392f3ab15Sopenharmony_ci
14492f3ab15Sopenharmony_ci    let mut client = server.client();
14592f3ab15Sopenharmony_ci    client.ctx().set_ca_file("test/root-ca.pem").unwrap();
14692f3ab15Sopenharmony_ci    client
14792f3ab15Sopenharmony_ci        .ctx()
14892f3ab15Sopenharmony_ci        .set_verify_callback(SslVerifyMode::PEER, |_, _| false);
14992f3ab15Sopenharmony_ci
15092f3ab15Sopenharmony_ci    client.connect_err();
15192f3ab15Sopenharmony_ci}
15292f3ab15Sopenharmony_ci
15392f3ab15Sopenharmony_ci#[test]
15492f3ab15Sopenharmony_cifn verify_callback_load_certs() {
15592f3ab15Sopenharmony_ci    static CALLED_BACK: AtomicBool = AtomicBool::new(false);
15692f3ab15Sopenharmony_ci
15792f3ab15Sopenharmony_ci    let server = Server::builder().build();
15892f3ab15Sopenharmony_ci
15992f3ab15Sopenharmony_ci    let mut client = server.client();
16092f3ab15Sopenharmony_ci    client
16192f3ab15Sopenharmony_ci        .ctx()
16292f3ab15Sopenharmony_ci        .set_verify_callback(SslVerifyMode::PEER, |_, x509| {
16392f3ab15Sopenharmony_ci            CALLED_BACK.store(true, Ordering::SeqCst);
16492f3ab15Sopenharmony_ci            assert!(x509.current_cert().is_some());
16592f3ab15Sopenharmony_ci            true
16692f3ab15Sopenharmony_ci        });
16792f3ab15Sopenharmony_ci
16892f3ab15Sopenharmony_ci    client.connect();
16992f3ab15Sopenharmony_ci    assert!(CALLED_BACK.load(Ordering::SeqCst));
17092f3ab15Sopenharmony_ci}
17192f3ab15Sopenharmony_ci
17292f3ab15Sopenharmony_ci#[test]
17392f3ab15Sopenharmony_cifn verify_trusted_get_error_ok() {
17492f3ab15Sopenharmony_ci    static CALLED_BACK: AtomicBool = AtomicBool::new(false);
17592f3ab15Sopenharmony_ci
17692f3ab15Sopenharmony_ci    let server = Server::builder().build();
17792f3ab15Sopenharmony_ci
17892f3ab15Sopenharmony_ci    let mut client = server.client();
17992f3ab15Sopenharmony_ci    client.ctx().set_ca_file("test/root-ca.pem").unwrap();
18092f3ab15Sopenharmony_ci    client
18192f3ab15Sopenharmony_ci        .ctx()
18292f3ab15Sopenharmony_ci        .set_verify_callback(SslVerifyMode::PEER, |_, x509| {
18392f3ab15Sopenharmony_ci            CALLED_BACK.store(true, Ordering::SeqCst);
18492f3ab15Sopenharmony_ci            assert_eq!(x509.error(), X509VerifyResult::OK);
18592f3ab15Sopenharmony_ci            true
18692f3ab15Sopenharmony_ci        });
18792f3ab15Sopenharmony_ci
18892f3ab15Sopenharmony_ci    client.connect();
18992f3ab15Sopenharmony_ci    assert!(CALLED_BACK.load(Ordering::SeqCst));
19092f3ab15Sopenharmony_ci}
19192f3ab15Sopenharmony_ci
19292f3ab15Sopenharmony_ci#[test]
19392f3ab15Sopenharmony_cifn verify_trusted_get_error_err() {
19492f3ab15Sopenharmony_ci    let mut server = Server::builder();
19592f3ab15Sopenharmony_ci    server.should_error();
19692f3ab15Sopenharmony_ci    let server = server.build();
19792f3ab15Sopenharmony_ci
19892f3ab15Sopenharmony_ci    let mut client = server.client();
19992f3ab15Sopenharmony_ci    client
20092f3ab15Sopenharmony_ci        .ctx()
20192f3ab15Sopenharmony_ci        .set_verify_callback(SslVerifyMode::PEER, |_, x509| {
20292f3ab15Sopenharmony_ci            assert_ne!(x509.error(), X509VerifyResult::OK);
20392f3ab15Sopenharmony_ci            false
20492f3ab15Sopenharmony_ci        });
20592f3ab15Sopenharmony_ci
20692f3ab15Sopenharmony_ci    client.connect_err();
20792f3ab15Sopenharmony_ci}
20892f3ab15Sopenharmony_ci
20992f3ab15Sopenharmony_ci#[test]
21092f3ab15Sopenharmony_cifn verify_callback() {
21192f3ab15Sopenharmony_ci    static CALLED_BACK: AtomicBool = AtomicBool::new(false);
21292f3ab15Sopenharmony_ci
21392f3ab15Sopenharmony_ci    let server = Server::builder().build();
21492f3ab15Sopenharmony_ci
21592f3ab15Sopenharmony_ci    let mut client = server.client();
21692f3ab15Sopenharmony_ci    let expected = "59172d9313e84459bcff27f967e79e6e9217e584";
21792f3ab15Sopenharmony_ci    client
21892f3ab15Sopenharmony_ci        .ctx()
21992f3ab15Sopenharmony_ci        .set_verify_callback(SslVerifyMode::PEER, move |_, x509| {
22092f3ab15Sopenharmony_ci            CALLED_BACK.store(true, Ordering::SeqCst);
22192f3ab15Sopenharmony_ci            let cert = x509.current_cert().unwrap();
22292f3ab15Sopenharmony_ci            let digest = cert.digest(MessageDigest::sha1()).unwrap();
22392f3ab15Sopenharmony_ci            assert_eq!(hex::encode(digest), expected);
22492f3ab15Sopenharmony_ci            true
22592f3ab15Sopenharmony_ci        });
22692f3ab15Sopenharmony_ci
22792f3ab15Sopenharmony_ci    client.connect();
22892f3ab15Sopenharmony_ci    assert!(CALLED_BACK.load(Ordering::SeqCst));
22992f3ab15Sopenharmony_ci}
23092f3ab15Sopenharmony_ci
23192f3ab15Sopenharmony_ci#[test]
23292f3ab15Sopenharmony_cifn ssl_verify_callback() {
23392f3ab15Sopenharmony_ci    static CALLED_BACK: AtomicBool = AtomicBool::new(false);
23492f3ab15Sopenharmony_ci
23592f3ab15Sopenharmony_ci    let server = Server::builder().build();
23692f3ab15Sopenharmony_ci
23792f3ab15Sopenharmony_ci    let mut client = server.client().build().builder();
23892f3ab15Sopenharmony_ci    let expected = "59172d9313e84459bcff27f967e79e6e9217e584";
23992f3ab15Sopenharmony_ci    client
24092f3ab15Sopenharmony_ci        .ssl()
24192f3ab15Sopenharmony_ci        .set_verify_callback(SslVerifyMode::PEER, move |_, x509| {
24292f3ab15Sopenharmony_ci            CALLED_BACK.store(true, Ordering::SeqCst);
24392f3ab15Sopenharmony_ci            let cert = x509.current_cert().unwrap();
24492f3ab15Sopenharmony_ci            let digest = cert.digest(MessageDigest::sha1()).unwrap();
24592f3ab15Sopenharmony_ci            assert_eq!(hex::encode(digest), expected);
24692f3ab15Sopenharmony_ci            true
24792f3ab15Sopenharmony_ci        });
24892f3ab15Sopenharmony_ci
24992f3ab15Sopenharmony_ci    client.connect();
25092f3ab15Sopenharmony_ci    assert!(CALLED_BACK.load(Ordering::SeqCst));
25192f3ab15Sopenharmony_ci}
25292f3ab15Sopenharmony_ci
25392f3ab15Sopenharmony_ci#[test]
25492f3ab15Sopenharmony_cifn get_ctx_options() {
25592f3ab15Sopenharmony_ci    let ctx = SslContext::builder(SslMethod::tls()).unwrap();
25692f3ab15Sopenharmony_ci    ctx.options();
25792f3ab15Sopenharmony_ci}
25892f3ab15Sopenharmony_ci
25992f3ab15Sopenharmony_ci#[test]
26092f3ab15Sopenharmony_cifn set_ctx_options() {
26192f3ab15Sopenharmony_ci    let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
26292f3ab15Sopenharmony_ci    let opts = ctx.set_options(SslOptions::NO_TICKET);
26392f3ab15Sopenharmony_ci    assert!(opts.contains(SslOptions::NO_TICKET));
26492f3ab15Sopenharmony_ci}
26592f3ab15Sopenharmony_ci
26692f3ab15Sopenharmony_ci#[test]
26792f3ab15Sopenharmony_ci#[cfg(not(boringssl))]
26892f3ab15Sopenharmony_cifn clear_ctx_options() {
26992f3ab15Sopenharmony_ci    let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
27092f3ab15Sopenharmony_ci    ctx.set_options(SslOptions::ALL);
27192f3ab15Sopenharmony_ci    let opts = ctx.clear_options(SslOptions::ALL);
27292f3ab15Sopenharmony_ci    assert!(!opts.contains(SslOptions::ALL));
27392f3ab15Sopenharmony_ci}
27492f3ab15Sopenharmony_ci
27592f3ab15Sopenharmony_ci#[test]
27692f3ab15Sopenharmony_cifn zero_length_buffers() {
27792f3ab15Sopenharmony_ci    let server = Server::builder().build();
27892f3ab15Sopenharmony_ci
27992f3ab15Sopenharmony_ci    let mut s = server.client().connect();
28092f3ab15Sopenharmony_ci    assert_eq!(s.write(&[]).unwrap(), 0);
28192f3ab15Sopenharmony_ci    assert_eq!(s.read(&mut []).unwrap(), 0);
28292f3ab15Sopenharmony_ci}
28392f3ab15Sopenharmony_ci
28492f3ab15Sopenharmony_ci#[test]
28592f3ab15Sopenharmony_cifn peer_certificate() {
28692f3ab15Sopenharmony_ci    let server = Server::builder().build();
28792f3ab15Sopenharmony_ci
28892f3ab15Sopenharmony_ci    let s = server.client().connect();
28992f3ab15Sopenharmony_ci    let cert = s.ssl().peer_certificate().unwrap();
29092f3ab15Sopenharmony_ci    let fingerprint = cert.digest(MessageDigest::sha1()).unwrap();
29192f3ab15Sopenharmony_ci    assert_eq!(
29292f3ab15Sopenharmony_ci        hex::encode(fingerprint),
29392f3ab15Sopenharmony_ci        "59172d9313e84459bcff27f967e79e6e9217e584"
29492f3ab15Sopenharmony_ci    );
29592f3ab15Sopenharmony_ci}
29692f3ab15Sopenharmony_ci
29792f3ab15Sopenharmony_ci#[test]
29892f3ab15Sopenharmony_cifn pending() {
29992f3ab15Sopenharmony_ci    let mut server = Server::builder();
30092f3ab15Sopenharmony_ci    server.io_cb(|mut s| s.write_all(&[0; 10]).unwrap());
30192f3ab15Sopenharmony_ci    let server = server.build();
30292f3ab15Sopenharmony_ci
30392f3ab15Sopenharmony_ci    let mut s = server.client().connect();
30492f3ab15Sopenharmony_ci    s.read_exact(&mut [0]).unwrap();
30592f3ab15Sopenharmony_ci
30692f3ab15Sopenharmony_ci    assert_eq!(s.ssl().pending(), 9);
30792f3ab15Sopenharmony_ci    assert_eq!(s.read(&mut [0; 10]).unwrap(), 9);
30892f3ab15Sopenharmony_ci}
30992f3ab15Sopenharmony_ci
31092f3ab15Sopenharmony_ci#[test]
31192f3ab15Sopenharmony_cifn state() {
31292f3ab15Sopenharmony_ci    let server = Server::builder().build();
31392f3ab15Sopenharmony_ci
31492f3ab15Sopenharmony_ci    let s = server.client().connect();
31592f3ab15Sopenharmony_ci    #[cfg(not(boringssl))]
31692f3ab15Sopenharmony_ci    assert_eq!(s.ssl().state_string().trim(), "SSLOK");
31792f3ab15Sopenharmony_ci    #[cfg(boringssl)]
31892f3ab15Sopenharmony_ci    assert_eq!(s.ssl().state_string(), "!!!!!!");
31992f3ab15Sopenharmony_ci    assert_eq!(
32092f3ab15Sopenharmony_ci        s.ssl().state_string_long(),
32192f3ab15Sopenharmony_ci        "SSL negotiation finished successfully"
32292f3ab15Sopenharmony_ci    );
32392f3ab15Sopenharmony_ci}
32492f3ab15Sopenharmony_ci
32592f3ab15Sopenharmony_ci/// Tests that when both the client as well as the server use SRTP and their
32692f3ab15Sopenharmony_ci/// lists of supported protocols have an overlap -- with only ONE protocol
32792f3ab15Sopenharmony_ci/// being valid for both.
32892f3ab15Sopenharmony_ci#[test]
32992f3ab15Sopenharmony_cifn test_connect_with_srtp_ctx() {
33092f3ab15Sopenharmony_ci    let listener = TcpListener::bind("127.0.0.1:0").unwrap();
33192f3ab15Sopenharmony_ci    let addr = listener.local_addr().unwrap();
33292f3ab15Sopenharmony_ci
33392f3ab15Sopenharmony_ci    let guard = thread::spawn(move || {
33492f3ab15Sopenharmony_ci        let stream = listener.accept().unwrap().0;
33592f3ab15Sopenharmony_ci        let mut ctx = SslContext::builder(SslMethod::dtls()).unwrap();
33692f3ab15Sopenharmony_ci        ctx.set_tlsext_use_srtp("SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32")
33792f3ab15Sopenharmony_ci            .unwrap();
33892f3ab15Sopenharmony_ci        ctx.set_certificate_file(Path::new("test/cert.pem"), SslFiletype::PEM)
33992f3ab15Sopenharmony_ci            .unwrap();
34092f3ab15Sopenharmony_ci        ctx.set_private_key_file(Path::new("test/key.pem"), SslFiletype::PEM)
34192f3ab15Sopenharmony_ci            .unwrap();
34292f3ab15Sopenharmony_ci        let mut ssl = Ssl::new(&ctx.build()).unwrap();
34392f3ab15Sopenharmony_ci        ssl.set_mtu(1500).unwrap();
34492f3ab15Sopenharmony_ci        let mut stream = ssl.accept(stream).unwrap();
34592f3ab15Sopenharmony_ci
34692f3ab15Sopenharmony_ci        let mut buf = [0; 60];
34792f3ab15Sopenharmony_ci        stream
34892f3ab15Sopenharmony_ci            .ssl()
34992f3ab15Sopenharmony_ci            .export_keying_material(&mut buf, "EXTRACTOR-dtls_srtp", None)
35092f3ab15Sopenharmony_ci            .unwrap();
35192f3ab15Sopenharmony_ci
35292f3ab15Sopenharmony_ci        stream.write_all(&[0]).unwrap();
35392f3ab15Sopenharmony_ci
35492f3ab15Sopenharmony_ci        buf
35592f3ab15Sopenharmony_ci    });
35692f3ab15Sopenharmony_ci
35792f3ab15Sopenharmony_ci    let stream = TcpStream::connect(addr).unwrap();
35892f3ab15Sopenharmony_ci    let mut ctx = SslContext::builder(SslMethod::dtls()).unwrap();
35992f3ab15Sopenharmony_ci    ctx.set_tlsext_use_srtp("SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32")
36092f3ab15Sopenharmony_ci        .unwrap();
36192f3ab15Sopenharmony_ci    let mut ssl = Ssl::new(&ctx.build()).unwrap();
36292f3ab15Sopenharmony_ci    ssl.set_mtu(1500).unwrap();
36392f3ab15Sopenharmony_ci    let mut stream = ssl.connect(stream).unwrap();
36492f3ab15Sopenharmony_ci
36592f3ab15Sopenharmony_ci    let mut buf = [1; 60];
36692f3ab15Sopenharmony_ci    {
36792f3ab15Sopenharmony_ci        let srtp_profile = stream.ssl().selected_srtp_profile().unwrap();
36892f3ab15Sopenharmony_ci        assert_eq!("SRTP_AES128_CM_SHA1_80", srtp_profile.name());
36992f3ab15Sopenharmony_ci        assert_eq!(SrtpProfileId::SRTP_AES128_CM_SHA1_80, srtp_profile.id());
37092f3ab15Sopenharmony_ci    }
37192f3ab15Sopenharmony_ci    stream
37292f3ab15Sopenharmony_ci        .ssl()
37392f3ab15Sopenharmony_ci        .export_keying_material(&mut buf, "EXTRACTOR-dtls_srtp", None)
37492f3ab15Sopenharmony_ci        .expect("extract");
37592f3ab15Sopenharmony_ci
37692f3ab15Sopenharmony_ci    stream.read_exact(&mut [0]).unwrap();
37792f3ab15Sopenharmony_ci
37892f3ab15Sopenharmony_ci    let buf2 = guard.join().unwrap();
37992f3ab15Sopenharmony_ci
38092f3ab15Sopenharmony_ci    assert_eq!(buf[..], buf2[..]);
38192f3ab15Sopenharmony_ci}
38292f3ab15Sopenharmony_ci
38392f3ab15Sopenharmony_ci/// Tests that when both the client as well as the server use SRTP and their
38492f3ab15Sopenharmony_ci/// lists of supported protocols have an overlap -- with only ONE protocol
38592f3ab15Sopenharmony_ci/// being valid for both.
38692f3ab15Sopenharmony_ci#[test]
38792f3ab15Sopenharmony_cifn test_connect_with_srtp_ssl() {
38892f3ab15Sopenharmony_ci    let listener = TcpListener::bind("127.0.0.1:0").unwrap();
38992f3ab15Sopenharmony_ci    let addr = listener.local_addr().unwrap();
39092f3ab15Sopenharmony_ci
39192f3ab15Sopenharmony_ci    let guard = thread::spawn(move || {
39292f3ab15Sopenharmony_ci        let stream = listener.accept().unwrap().0;
39392f3ab15Sopenharmony_ci        let mut ctx = SslContext::builder(SslMethod::dtls()).unwrap();
39492f3ab15Sopenharmony_ci        ctx.set_certificate_file(Path::new("test/cert.pem"), SslFiletype::PEM)
39592f3ab15Sopenharmony_ci            .unwrap();
39692f3ab15Sopenharmony_ci        ctx.set_private_key_file(Path::new("test/key.pem"), SslFiletype::PEM)
39792f3ab15Sopenharmony_ci            .unwrap();
39892f3ab15Sopenharmony_ci        let mut ssl = Ssl::new(&ctx.build()).unwrap();
39992f3ab15Sopenharmony_ci        ssl.set_tlsext_use_srtp("SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32")
40092f3ab15Sopenharmony_ci            .unwrap();
40192f3ab15Sopenharmony_ci        let mut profilenames = String::new();
40292f3ab15Sopenharmony_ci        for profile in ssl.srtp_profiles().unwrap() {
40392f3ab15Sopenharmony_ci            if !profilenames.is_empty() {
40492f3ab15Sopenharmony_ci                profilenames.push(':');
40592f3ab15Sopenharmony_ci            }
40692f3ab15Sopenharmony_ci            profilenames += profile.name();
40792f3ab15Sopenharmony_ci        }
40892f3ab15Sopenharmony_ci        assert_eq!(
40992f3ab15Sopenharmony_ci            "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32",
41092f3ab15Sopenharmony_ci            profilenames
41192f3ab15Sopenharmony_ci        );
41292f3ab15Sopenharmony_ci        ssl.set_mtu(1500).unwrap();
41392f3ab15Sopenharmony_ci        let mut stream = ssl.accept(stream).unwrap();
41492f3ab15Sopenharmony_ci
41592f3ab15Sopenharmony_ci        let mut buf = [0; 60];
41692f3ab15Sopenharmony_ci        stream
41792f3ab15Sopenharmony_ci            .ssl()
41892f3ab15Sopenharmony_ci            .export_keying_material(&mut buf, "EXTRACTOR-dtls_srtp", None)
41992f3ab15Sopenharmony_ci            .unwrap();
42092f3ab15Sopenharmony_ci
42192f3ab15Sopenharmony_ci        stream.write_all(&[0]).unwrap();
42292f3ab15Sopenharmony_ci
42392f3ab15Sopenharmony_ci        buf
42492f3ab15Sopenharmony_ci    });
42592f3ab15Sopenharmony_ci
42692f3ab15Sopenharmony_ci    let stream = TcpStream::connect(addr).unwrap();
42792f3ab15Sopenharmony_ci    let ctx = SslContext::builder(SslMethod::dtls()).unwrap();
42892f3ab15Sopenharmony_ci    let mut ssl = Ssl::new(&ctx.build()).unwrap();
42992f3ab15Sopenharmony_ci    ssl.set_tlsext_use_srtp("SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32")
43092f3ab15Sopenharmony_ci        .unwrap();
43192f3ab15Sopenharmony_ci    ssl.set_mtu(1500).unwrap();
43292f3ab15Sopenharmony_ci    let mut stream = ssl.connect(stream).unwrap();
43392f3ab15Sopenharmony_ci
43492f3ab15Sopenharmony_ci    let mut buf = [1; 60];
43592f3ab15Sopenharmony_ci    {
43692f3ab15Sopenharmony_ci        let srtp_profile = stream.ssl().selected_srtp_profile().unwrap();
43792f3ab15Sopenharmony_ci        assert_eq!("SRTP_AES128_CM_SHA1_80", srtp_profile.name());
43892f3ab15Sopenharmony_ci        assert_eq!(SrtpProfileId::SRTP_AES128_CM_SHA1_80, srtp_profile.id());
43992f3ab15Sopenharmony_ci    }
44092f3ab15Sopenharmony_ci    stream
44192f3ab15Sopenharmony_ci        .ssl()
44292f3ab15Sopenharmony_ci        .export_keying_material(&mut buf, "EXTRACTOR-dtls_srtp", None)
44392f3ab15Sopenharmony_ci        .expect("extract");
44492f3ab15Sopenharmony_ci
44592f3ab15Sopenharmony_ci    stream.read_exact(&mut [0]).unwrap();
44692f3ab15Sopenharmony_ci
44792f3ab15Sopenharmony_ci    let buf2 = guard.join().unwrap();
44892f3ab15Sopenharmony_ci
44992f3ab15Sopenharmony_ci    assert_eq!(buf[..], buf2[..]);
45092f3ab15Sopenharmony_ci}
45192f3ab15Sopenharmony_ci
45292f3ab15Sopenharmony_ci/// Tests that when the `SslStream` is created as a server stream, the protocols
45392f3ab15Sopenharmony_ci/// are correctly advertised to the client.
45492f3ab15Sopenharmony_ci#[test]
45592f3ab15Sopenharmony_ci#[cfg(any(ossl102, libressl261))]
45692f3ab15Sopenharmony_cifn test_alpn_server_advertise_multiple() {
45792f3ab15Sopenharmony_ci    let mut server = Server::builder();
45892f3ab15Sopenharmony_ci    server.ctx().set_alpn_select_callback(|_, client| {
45992f3ab15Sopenharmony_ci        ssl::select_next_proto(b"\x08http/1.1\x08spdy/3.1", client).ok_or(ssl::AlpnError::NOACK)
46092f3ab15Sopenharmony_ci    });
46192f3ab15Sopenharmony_ci    let server = server.build();
46292f3ab15Sopenharmony_ci
46392f3ab15Sopenharmony_ci    let mut client = server.client();
46492f3ab15Sopenharmony_ci    client.ctx().set_alpn_protos(b"\x08spdy/3.1").unwrap();
46592f3ab15Sopenharmony_ci    let s = client.connect();
46692f3ab15Sopenharmony_ci    assert_eq!(s.ssl().selected_alpn_protocol(), Some(&b"spdy/3.1"[..]));
46792f3ab15Sopenharmony_ci}
46892f3ab15Sopenharmony_ci
46992f3ab15Sopenharmony_ci#[test]
47092f3ab15Sopenharmony_ci#[cfg(ossl110)]
47192f3ab15Sopenharmony_cifn test_alpn_server_select_none_fatal() {
47292f3ab15Sopenharmony_ci    let mut server = Server::builder();
47392f3ab15Sopenharmony_ci    server.ctx().set_alpn_select_callback(|_, client| {
47492f3ab15Sopenharmony_ci        ssl::select_next_proto(b"\x08http/1.1\x08spdy/3.1", client)
47592f3ab15Sopenharmony_ci            .ok_or(ssl::AlpnError::ALERT_FATAL)
47692f3ab15Sopenharmony_ci    });
47792f3ab15Sopenharmony_ci    server.should_error();
47892f3ab15Sopenharmony_ci    let server = server.build();
47992f3ab15Sopenharmony_ci
48092f3ab15Sopenharmony_ci    let mut client = server.client();
48192f3ab15Sopenharmony_ci    client.ctx().set_alpn_protos(b"\x06http/2").unwrap();
48292f3ab15Sopenharmony_ci    client.connect_err();
48392f3ab15Sopenharmony_ci}
48492f3ab15Sopenharmony_ci
48592f3ab15Sopenharmony_ci#[test]
48692f3ab15Sopenharmony_ci#[cfg(any(ossl102, libressl261))]
48792f3ab15Sopenharmony_cifn test_alpn_server_select_none() {
48892f3ab15Sopenharmony_ci    static CALLED_BACK: AtomicBool = AtomicBool::new(false);
48992f3ab15Sopenharmony_ci
49092f3ab15Sopenharmony_ci    let mut server = Server::builder();
49192f3ab15Sopenharmony_ci    server.ctx().set_alpn_select_callback(|_, client| {
49292f3ab15Sopenharmony_ci        CALLED_BACK.store(true, Ordering::SeqCst);
49392f3ab15Sopenharmony_ci        ssl::select_next_proto(b"\x08http/1.1\x08spdy/3.1", client).ok_or(ssl::AlpnError::NOACK)
49492f3ab15Sopenharmony_ci    });
49592f3ab15Sopenharmony_ci    let server = server.build();
49692f3ab15Sopenharmony_ci
49792f3ab15Sopenharmony_ci    let mut client = server.client();
49892f3ab15Sopenharmony_ci    client.ctx().set_alpn_protos(b"\x06http/2").unwrap();
49992f3ab15Sopenharmony_ci    let s = client.connect();
50092f3ab15Sopenharmony_ci    assert_eq!(None, s.ssl().selected_alpn_protocol());
50192f3ab15Sopenharmony_ci    assert!(CALLED_BACK.load(Ordering::SeqCst));
50292f3ab15Sopenharmony_ci}
50392f3ab15Sopenharmony_ci
50492f3ab15Sopenharmony_ci#[test]
50592f3ab15Sopenharmony_ci#[cfg(any(ossl102, libressl261))]
50692f3ab15Sopenharmony_cifn test_alpn_server_unilateral() {
50792f3ab15Sopenharmony_ci    let server = Server::builder().build();
50892f3ab15Sopenharmony_ci
50992f3ab15Sopenharmony_ci    let mut client = server.client();
51092f3ab15Sopenharmony_ci    client.ctx().set_alpn_protos(b"\x06http/2").unwrap();
51192f3ab15Sopenharmony_ci    let s = client.connect();
51292f3ab15Sopenharmony_ci    assert_eq!(None, s.ssl().selected_alpn_protocol());
51392f3ab15Sopenharmony_ci}
51492f3ab15Sopenharmony_ci
51592f3ab15Sopenharmony_ci#[test]
51692f3ab15Sopenharmony_ci#[should_panic(expected = "blammo")]
51792f3ab15Sopenharmony_cifn write_panic() {
51892f3ab15Sopenharmony_ci    struct ExplodingStream(TcpStream);
51992f3ab15Sopenharmony_ci
52092f3ab15Sopenharmony_ci    impl Read for ExplodingStream {
52192f3ab15Sopenharmony_ci        fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
52292f3ab15Sopenharmony_ci            self.0.read(buf)
52392f3ab15Sopenharmony_ci        }
52492f3ab15Sopenharmony_ci    }
52592f3ab15Sopenharmony_ci
52692f3ab15Sopenharmony_ci    impl Write for ExplodingStream {
52792f3ab15Sopenharmony_ci        fn write(&mut self, _: &[u8]) -> io::Result<usize> {
52892f3ab15Sopenharmony_ci            panic!("blammo");
52992f3ab15Sopenharmony_ci        }
53092f3ab15Sopenharmony_ci
53192f3ab15Sopenharmony_ci        fn flush(&mut self) -> io::Result<()> {
53292f3ab15Sopenharmony_ci            self.0.flush()
53392f3ab15Sopenharmony_ci        }
53492f3ab15Sopenharmony_ci    }
53592f3ab15Sopenharmony_ci
53692f3ab15Sopenharmony_ci    let mut server = Server::builder();
53792f3ab15Sopenharmony_ci    server.should_error();
53892f3ab15Sopenharmony_ci    let server = server.build();
53992f3ab15Sopenharmony_ci
54092f3ab15Sopenharmony_ci    let stream = ExplodingStream(server.connect_tcp());
54192f3ab15Sopenharmony_ci
54292f3ab15Sopenharmony_ci    let ctx = SslContext::builder(SslMethod::tls()).unwrap();
54392f3ab15Sopenharmony_ci    let _ = Ssl::new(&ctx.build()).unwrap().connect(stream);
54492f3ab15Sopenharmony_ci}
54592f3ab15Sopenharmony_ci
54692f3ab15Sopenharmony_ci#[test]
54792f3ab15Sopenharmony_ci#[should_panic(expected = "blammo")]
54892f3ab15Sopenharmony_cifn read_panic() {
54992f3ab15Sopenharmony_ci    struct ExplodingStream(TcpStream);
55092f3ab15Sopenharmony_ci
55192f3ab15Sopenharmony_ci    impl Read for ExplodingStream {
55292f3ab15Sopenharmony_ci        fn read(&mut self, _: &mut [u8]) -> io::Result<usize> {
55392f3ab15Sopenharmony_ci            panic!("blammo");
55492f3ab15Sopenharmony_ci        }
55592f3ab15Sopenharmony_ci    }
55692f3ab15Sopenharmony_ci
55792f3ab15Sopenharmony_ci    impl Write for ExplodingStream {
55892f3ab15Sopenharmony_ci        fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
55992f3ab15Sopenharmony_ci            self.0.write(buf)
56092f3ab15Sopenharmony_ci        }
56192f3ab15Sopenharmony_ci
56292f3ab15Sopenharmony_ci        fn flush(&mut self) -> io::Result<()> {
56392f3ab15Sopenharmony_ci            self.0.flush()
56492f3ab15Sopenharmony_ci        }
56592f3ab15Sopenharmony_ci    }
56692f3ab15Sopenharmony_ci
56792f3ab15Sopenharmony_ci    let mut server = Server::builder();
56892f3ab15Sopenharmony_ci    server.should_error();
56992f3ab15Sopenharmony_ci    let server = server.build();
57092f3ab15Sopenharmony_ci
57192f3ab15Sopenharmony_ci    let stream = ExplodingStream(server.connect_tcp());
57292f3ab15Sopenharmony_ci
57392f3ab15Sopenharmony_ci    let ctx = SslContext::builder(SslMethod::tls()).unwrap();
57492f3ab15Sopenharmony_ci    let _ = Ssl::new(&ctx.build()).unwrap().connect(stream);
57592f3ab15Sopenharmony_ci}
57692f3ab15Sopenharmony_ci
57792f3ab15Sopenharmony_ci#[test]
57892f3ab15Sopenharmony_ci#[cfg_attr(all(libressl321, not(libressl340)), ignore)]
57992f3ab15Sopenharmony_ci#[should_panic(expected = "blammo")]
58092f3ab15Sopenharmony_cifn flush_panic() {
58192f3ab15Sopenharmony_ci    struct ExplodingStream(TcpStream);
58292f3ab15Sopenharmony_ci
58392f3ab15Sopenharmony_ci    impl Read for ExplodingStream {
58492f3ab15Sopenharmony_ci        fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
58592f3ab15Sopenharmony_ci            self.0.read(buf)
58692f3ab15Sopenharmony_ci        }
58792f3ab15Sopenharmony_ci    }
58892f3ab15Sopenharmony_ci
58992f3ab15Sopenharmony_ci    impl Write for ExplodingStream {
59092f3ab15Sopenharmony_ci        fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
59192f3ab15Sopenharmony_ci            self.0.write(buf)
59292f3ab15Sopenharmony_ci        }
59392f3ab15Sopenharmony_ci
59492f3ab15Sopenharmony_ci        fn flush(&mut self) -> io::Result<()> {
59592f3ab15Sopenharmony_ci            panic!("blammo");
59692f3ab15Sopenharmony_ci        }
59792f3ab15Sopenharmony_ci    }
59892f3ab15Sopenharmony_ci
59992f3ab15Sopenharmony_ci    let mut server = Server::builder();
60092f3ab15Sopenharmony_ci    server.should_error();
60192f3ab15Sopenharmony_ci    let server = server.build();
60292f3ab15Sopenharmony_ci
60392f3ab15Sopenharmony_ci    let stream = ExplodingStream(server.connect_tcp());
60492f3ab15Sopenharmony_ci
60592f3ab15Sopenharmony_ci    let ctx = SslContext::builder(SslMethod::tls()).unwrap();
60692f3ab15Sopenharmony_ci    let _ = Ssl::new(&ctx.build()).unwrap().connect(stream);
60792f3ab15Sopenharmony_ci}
60892f3ab15Sopenharmony_ci
60992f3ab15Sopenharmony_ci#[test]
61092f3ab15Sopenharmony_cifn refcount_ssl_context() {
61192f3ab15Sopenharmony_ci    let mut ssl = {
61292f3ab15Sopenharmony_ci        let ctx = SslContext::builder(SslMethod::tls()).unwrap();
61392f3ab15Sopenharmony_ci        ssl::Ssl::new(&ctx.build()).unwrap()
61492f3ab15Sopenharmony_ci    };
61592f3ab15Sopenharmony_ci
61692f3ab15Sopenharmony_ci    {
61792f3ab15Sopenharmony_ci        let new_ctx_a = SslContext::builder(SslMethod::tls()).unwrap().build();
61892f3ab15Sopenharmony_ci        ssl.set_ssl_context(&new_ctx_a).unwrap();
61992f3ab15Sopenharmony_ci    }
62092f3ab15Sopenharmony_ci}
62192f3ab15Sopenharmony_ci
62292f3ab15Sopenharmony_ci#[test]
62392f3ab15Sopenharmony_ci#[cfg_attr(libressl250, ignore)]
62492f3ab15Sopenharmony_ci#[cfg_attr(target_os = "windows", ignore)]
62592f3ab15Sopenharmony_ci#[cfg_attr(all(target_os = "macos", feature = "vendored"), ignore)]
62692f3ab15Sopenharmony_cifn default_verify_paths() {
62792f3ab15Sopenharmony_ci    let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
62892f3ab15Sopenharmony_ci    ctx.set_default_verify_paths().unwrap();
62992f3ab15Sopenharmony_ci    ctx.set_verify(SslVerifyMode::PEER);
63092f3ab15Sopenharmony_ci    let ctx = ctx.build();
63192f3ab15Sopenharmony_ci    let s = match TcpStream::connect("google.com:443") {
63292f3ab15Sopenharmony_ci        Ok(s) => s,
63392f3ab15Sopenharmony_ci        Err(_) => return,
63492f3ab15Sopenharmony_ci    };
63592f3ab15Sopenharmony_ci    let mut ssl = Ssl::new(&ctx).unwrap();
63692f3ab15Sopenharmony_ci    ssl.set_hostname("google.com").unwrap();
63792f3ab15Sopenharmony_ci    let mut socket = ssl.connect(s).unwrap();
63892f3ab15Sopenharmony_ci
63992f3ab15Sopenharmony_ci    socket.write_all(b"GET / HTTP/1.0\r\n\r\n").unwrap();
64092f3ab15Sopenharmony_ci    let mut result = vec![];
64192f3ab15Sopenharmony_ci    socket.read_to_end(&mut result).unwrap();
64292f3ab15Sopenharmony_ci
64392f3ab15Sopenharmony_ci    println!("{}", String::from_utf8_lossy(&result));
64492f3ab15Sopenharmony_ci    assert!(result.starts_with(b"HTTP/1.0"));
64592f3ab15Sopenharmony_ci    assert!(result.ends_with(b"</HTML>\r\n") || result.ends_with(b"</html>"));
64692f3ab15Sopenharmony_ci}
64792f3ab15Sopenharmony_ci
64892f3ab15Sopenharmony_ci#[test]
64992f3ab15Sopenharmony_cifn add_extra_chain_cert() {
65092f3ab15Sopenharmony_ci    let cert = X509::from_pem(CERT).unwrap();
65192f3ab15Sopenharmony_ci    let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
65292f3ab15Sopenharmony_ci    ctx.add_extra_chain_cert(cert).unwrap();
65392f3ab15Sopenharmony_ci}
65492f3ab15Sopenharmony_ci
65592f3ab15Sopenharmony_ci#[test]
65692f3ab15Sopenharmony_ci#[cfg(ossl102)]
65792f3ab15Sopenharmony_cifn verify_valid_hostname() {
65892f3ab15Sopenharmony_ci    let server = Server::builder().build();
65992f3ab15Sopenharmony_ci
66092f3ab15Sopenharmony_ci    let mut client = server.client();
66192f3ab15Sopenharmony_ci    client.ctx().set_ca_file("test/root-ca.pem").unwrap();
66292f3ab15Sopenharmony_ci    client.ctx().set_verify(SslVerifyMode::PEER);
66392f3ab15Sopenharmony_ci
66492f3ab15Sopenharmony_ci    let mut client = client.build().builder();
66592f3ab15Sopenharmony_ci    client
66692f3ab15Sopenharmony_ci        .ssl()
66792f3ab15Sopenharmony_ci        .param_mut()
66892f3ab15Sopenharmony_ci        .set_hostflags(X509CheckFlags::NO_PARTIAL_WILDCARDS);
66992f3ab15Sopenharmony_ci    client.ssl().param_mut().set_host("foobar.com").unwrap();
67092f3ab15Sopenharmony_ci    client.connect();
67192f3ab15Sopenharmony_ci}
67292f3ab15Sopenharmony_ci
67392f3ab15Sopenharmony_ci#[test]
67492f3ab15Sopenharmony_ci#[cfg(ossl102)]
67592f3ab15Sopenharmony_cifn verify_invalid_hostname() {
67692f3ab15Sopenharmony_ci    let mut server = Server::builder();
67792f3ab15Sopenharmony_ci    server.should_error();
67892f3ab15Sopenharmony_ci    let server = server.build();
67992f3ab15Sopenharmony_ci
68092f3ab15Sopenharmony_ci    let mut client = server.client();
68192f3ab15Sopenharmony_ci    client.ctx().set_ca_file("test/root-ca.pem").unwrap();
68292f3ab15Sopenharmony_ci    client.ctx().set_verify(SslVerifyMode::PEER);
68392f3ab15Sopenharmony_ci
68492f3ab15Sopenharmony_ci    let mut client = client.build().builder();
68592f3ab15Sopenharmony_ci    client
68692f3ab15Sopenharmony_ci        .ssl()
68792f3ab15Sopenharmony_ci        .param_mut()
68892f3ab15Sopenharmony_ci        .set_hostflags(X509CheckFlags::NO_PARTIAL_WILDCARDS);
68992f3ab15Sopenharmony_ci    client.ssl().param_mut().set_host("bogus.com").unwrap();
69092f3ab15Sopenharmony_ci    client.connect_err();
69192f3ab15Sopenharmony_ci}
69292f3ab15Sopenharmony_ci
69392f3ab15Sopenharmony_ci#[test]
69492f3ab15Sopenharmony_cifn connector_valid_hostname() {
69592f3ab15Sopenharmony_ci    let server = Server::builder().build();
69692f3ab15Sopenharmony_ci
69792f3ab15Sopenharmony_ci    let mut connector = SslConnector::builder(SslMethod::tls()).unwrap();
69892f3ab15Sopenharmony_ci    connector.set_ca_file("test/root-ca.pem").unwrap();
69992f3ab15Sopenharmony_ci
70092f3ab15Sopenharmony_ci    let s = server.connect_tcp();
70192f3ab15Sopenharmony_ci    let mut s = connector.build().connect("foobar.com", s).unwrap();
70292f3ab15Sopenharmony_ci    s.read_exact(&mut [0]).unwrap();
70392f3ab15Sopenharmony_ci}
70492f3ab15Sopenharmony_ci
70592f3ab15Sopenharmony_ci#[test]
70692f3ab15Sopenharmony_cifn connector_invalid_hostname() {
70792f3ab15Sopenharmony_ci    let mut server = Server::builder();
70892f3ab15Sopenharmony_ci    server.should_error();
70992f3ab15Sopenharmony_ci    let server = server.build();
71092f3ab15Sopenharmony_ci
71192f3ab15Sopenharmony_ci    let mut connector = SslConnector::builder(SslMethod::tls()).unwrap();
71292f3ab15Sopenharmony_ci    connector.set_ca_file("test/root-ca.pem").unwrap();
71392f3ab15Sopenharmony_ci
71492f3ab15Sopenharmony_ci    let s = server.connect_tcp();
71592f3ab15Sopenharmony_ci    connector.build().connect("bogus.com", s).unwrap_err();
71692f3ab15Sopenharmony_ci}
71792f3ab15Sopenharmony_ci
71892f3ab15Sopenharmony_ci#[test]
71992f3ab15Sopenharmony_cifn connector_invalid_no_hostname_verification() {
72092f3ab15Sopenharmony_ci    let server = Server::builder().build();
72192f3ab15Sopenharmony_ci
72292f3ab15Sopenharmony_ci    let mut connector = SslConnector::builder(SslMethod::tls()).unwrap();
72392f3ab15Sopenharmony_ci    connector.set_ca_file("test/root-ca.pem").unwrap();
72492f3ab15Sopenharmony_ci
72592f3ab15Sopenharmony_ci    let s = server.connect_tcp();
72692f3ab15Sopenharmony_ci    let mut s = connector
72792f3ab15Sopenharmony_ci        .build()
72892f3ab15Sopenharmony_ci        .configure()
72992f3ab15Sopenharmony_ci        .unwrap()
73092f3ab15Sopenharmony_ci        .verify_hostname(false)
73192f3ab15Sopenharmony_ci        .connect("bogus.com", s)
73292f3ab15Sopenharmony_ci        .unwrap();
73392f3ab15Sopenharmony_ci    s.read_exact(&mut [0]).unwrap();
73492f3ab15Sopenharmony_ci}
73592f3ab15Sopenharmony_ci
73692f3ab15Sopenharmony_ci#[test]
73792f3ab15Sopenharmony_cifn connector_no_hostname_still_verifies() {
73892f3ab15Sopenharmony_ci    let mut server = Server::builder();
73992f3ab15Sopenharmony_ci    server.should_error();
74092f3ab15Sopenharmony_ci    let server = server.build();
74192f3ab15Sopenharmony_ci
74292f3ab15Sopenharmony_ci    let connector = SslConnector::builder(SslMethod::tls()).unwrap().build();
74392f3ab15Sopenharmony_ci
74492f3ab15Sopenharmony_ci    let s = server.connect_tcp();
74592f3ab15Sopenharmony_ci    assert!(connector
74692f3ab15Sopenharmony_ci        .configure()
74792f3ab15Sopenharmony_ci        .unwrap()
74892f3ab15Sopenharmony_ci        .verify_hostname(false)
74992f3ab15Sopenharmony_ci        .connect("fizzbuzz.com", s)
75092f3ab15Sopenharmony_ci        .is_err());
75192f3ab15Sopenharmony_ci}
75292f3ab15Sopenharmony_ci
75392f3ab15Sopenharmony_ci#[test]
75492f3ab15Sopenharmony_cifn connector_can_disable_verify() {
75592f3ab15Sopenharmony_ci    let server = Server::builder().build();
75692f3ab15Sopenharmony_ci
75792f3ab15Sopenharmony_ci    let mut connector = SslConnector::builder(SslMethod::tls()).unwrap();
75892f3ab15Sopenharmony_ci    connector.set_verify(SslVerifyMode::NONE);
75992f3ab15Sopenharmony_ci    let connector = connector.build();
76092f3ab15Sopenharmony_ci
76192f3ab15Sopenharmony_ci    let s = server.connect_tcp();
76292f3ab15Sopenharmony_ci    let mut s = connector
76392f3ab15Sopenharmony_ci        .configure()
76492f3ab15Sopenharmony_ci        .unwrap()
76592f3ab15Sopenharmony_ci        .connect("fizzbuzz.com", s)
76692f3ab15Sopenharmony_ci        .unwrap();
76792f3ab15Sopenharmony_ci    s.read_exact(&mut [0]).unwrap();
76892f3ab15Sopenharmony_ci}
76992f3ab15Sopenharmony_ci
77092f3ab15Sopenharmony_ci#[test]
77192f3ab15Sopenharmony_cifn connector_does_use_sni_with_dnsnames() {
77292f3ab15Sopenharmony_ci    static CALLED_BACK: AtomicBool = AtomicBool::new(false);
77392f3ab15Sopenharmony_ci
77492f3ab15Sopenharmony_ci    let mut builder = Server::builder();
77592f3ab15Sopenharmony_ci    builder.ctx().set_servername_callback(|ssl, _| {
77692f3ab15Sopenharmony_ci        assert_eq!(ssl.servername(NameType::HOST_NAME), Some("foobar.com"));
77792f3ab15Sopenharmony_ci        CALLED_BACK.store(true, Ordering::SeqCst);
77892f3ab15Sopenharmony_ci        Ok(())
77992f3ab15Sopenharmony_ci    });
78092f3ab15Sopenharmony_ci    let server = builder.build();
78192f3ab15Sopenharmony_ci
78292f3ab15Sopenharmony_ci    let mut connector = SslConnector::builder(SslMethod::tls()).unwrap();
78392f3ab15Sopenharmony_ci    connector.set_ca_file("test/root-ca.pem").unwrap();
78492f3ab15Sopenharmony_ci
78592f3ab15Sopenharmony_ci    let s = server.connect_tcp();
78692f3ab15Sopenharmony_ci    let mut s = connector
78792f3ab15Sopenharmony_ci        .build()
78892f3ab15Sopenharmony_ci        .configure()
78992f3ab15Sopenharmony_ci        .unwrap()
79092f3ab15Sopenharmony_ci        .connect("foobar.com", s)
79192f3ab15Sopenharmony_ci        .unwrap();
79292f3ab15Sopenharmony_ci    s.read_exact(&mut [0]).unwrap();
79392f3ab15Sopenharmony_ci
79492f3ab15Sopenharmony_ci    assert!(CALLED_BACK.load(Ordering::SeqCst));
79592f3ab15Sopenharmony_ci}
79692f3ab15Sopenharmony_ci
79792f3ab15Sopenharmony_ci#[test]
79892f3ab15Sopenharmony_cifn connector_doesnt_use_sni_with_ips() {
79992f3ab15Sopenharmony_ci    static CALLED_BACK: AtomicBool = AtomicBool::new(false);
80092f3ab15Sopenharmony_ci
80192f3ab15Sopenharmony_ci    let mut builder = Server::builder();
80292f3ab15Sopenharmony_ci    builder.ctx().set_servername_callback(|ssl, _| {
80392f3ab15Sopenharmony_ci        assert_eq!(ssl.servername(NameType::HOST_NAME), None);
80492f3ab15Sopenharmony_ci        CALLED_BACK.store(true, Ordering::SeqCst);
80592f3ab15Sopenharmony_ci        Ok(())
80692f3ab15Sopenharmony_ci    });
80792f3ab15Sopenharmony_ci    let server = builder.build();
80892f3ab15Sopenharmony_ci
80992f3ab15Sopenharmony_ci    let mut connector = SslConnector::builder(SslMethod::tls()).unwrap();
81092f3ab15Sopenharmony_ci    // The server's cert isn't issued for 127.0.0.1 but we don't care for this test.
81192f3ab15Sopenharmony_ci    connector.set_verify(SslVerifyMode::NONE);
81292f3ab15Sopenharmony_ci
81392f3ab15Sopenharmony_ci    let s = server.connect_tcp();
81492f3ab15Sopenharmony_ci    let mut s = connector
81592f3ab15Sopenharmony_ci        .build()
81692f3ab15Sopenharmony_ci        .configure()
81792f3ab15Sopenharmony_ci        .unwrap()
81892f3ab15Sopenharmony_ci        .connect("127.0.0.1", s)
81992f3ab15Sopenharmony_ci        .unwrap();
82092f3ab15Sopenharmony_ci    s.read_exact(&mut [0]).unwrap();
82192f3ab15Sopenharmony_ci
82292f3ab15Sopenharmony_ci    assert!(CALLED_BACK.load(Ordering::SeqCst));
82392f3ab15Sopenharmony_ci}
82492f3ab15Sopenharmony_ci
82592f3ab15Sopenharmony_cifn test_mozilla_server(new: fn(SslMethod) -> Result<SslAcceptorBuilder, ErrorStack>) {
82692f3ab15Sopenharmony_ci    let listener = TcpListener::bind("127.0.0.1:0").unwrap();
82792f3ab15Sopenharmony_ci    let port = listener.local_addr().unwrap().port();
82892f3ab15Sopenharmony_ci
82992f3ab15Sopenharmony_ci    let t = thread::spawn(move || {
83092f3ab15Sopenharmony_ci        let key = PKey::private_key_from_pem(KEY).unwrap();
83192f3ab15Sopenharmony_ci        let cert = X509::from_pem(CERT).unwrap();
83292f3ab15Sopenharmony_ci        let mut acceptor = new(SslMethod::tls()).unwrap();
83392f3ab15Sopenharmony_ci        acceptor.set_private_key(&key).unwrap();
83492f3ab15Sopenharmony_ci        acceptor.set_certificate(&cert).unwrap();
83592f3ab15Sopenharmony_ci        let acceptor = acceptor.build();
83692f3ab15Sopenharmony_ci        let stream = listener.accept().unwrap().0;
83792f3ab15Sopenharmony_ci        let mut stream = acceptor.accept(stream).unwrap();
83892f3ab15Sopenharmony_ci
83992f3ab15Sopenharmony_ci        stream.write_all(b"hello").unwrap();
84092f3ab15Sopenharmony_ci    });
84192f3ab15Sopenharmony_ci
84292f3ab15Sopenharmony_ci    let mut connector = SslConnector::builder(SslMethod::tls()).unwrap();
84392f3ab15Sopenharmony_ci    connector.set_ca_file("test/root-ca.pem").unwrap();
84492f3ab15Sopenharmony_ci    let connector = connector.build();
84592f3ab15Sopenharmony_ci
84692f3ab15Sopenharmony_ci    let stream = TcpStream::connect(("127.0.0.1", port)).unwrap();
84792f3ab15Sopenharmony_ci    let mut stream = connector.connect("foobar.com", stream).unwrap();
84892f3ab15Sopenharmony_ci
84992f3ab15Sopenharmony_ci    let mut buf = [0; 5];
85092f3ab15Sopenharmony_ci    stream.read_exact(&mut buf).unwrap();
85192f3ab15Sopenharmony_ci    assert_eq!(b"hello", &buf);
85292f3ab15Sopenharmony_ci
85392f3ab15Sopenharmony_ci    t.join().unwrap();
85492f3ab15Sopenharmony_ci}
85592f3ab15Sopenharmony_ci
85692f3ab15Sopenharmony_ci#[test]
85792f3ab15Sopenharmony_cifn connector_client_server_mozilla_intermediate() {
85892f3ab15Sopenharmony_ci    test_mozilla_server(SslAcceptor::mozilla_intermediate);
85992f3ab15Sopenharmony_ci}
86092f3ab15Sopenharmony_ci
86192f3ab15Sopenharmony_ci#[test]
86292f3ab15Sopenharmony_cifn connector_client_server_mozilla_modern() {
86392f3ab15Sopenharmony_ci    test_mozilla_server(SslAcceptor::mozilla_modern);
86492f3ab15Sopenharmony_ci}
86592f3ab15Sopenharmony_ci
86692f3ab15Sopenharmony_ci#[test]
86792f3ab15Sopenharmony_cifn connector_client_server_mozilla_intermediate_v5() {
86892f3ab15Sopenharmony_ci    test_mozilla_server(SslAcceptor::mozilla_intermediate_v5);
86992f3ab15Sopenharmony_ci}
87092f3ab15Sopenharmony_ci
87192f3ab15Sopenharmony_ci#[test]
87292f3ab15Sopenharmony_ci#[cfg(any(ossl111, libressl340))]
87392f3ab15Sopenharmony_cifn connector_client_server_mozilla_modern_v5() {
87492f3ab15Sopenharmony_ci    test_mozilla_server(SslAcceptor::mozilla_modern_v5);
87592f3ab15Sopenharmony_ci}
87692f3ab15Sopenharmony_ci
87792f3ab15Sopenharmony_ci#[test]
87892f3ab15Sopenharmony_cifn shutdown() {
87992f3ab15Sopenharmony_ci    let mut server = Server::builder();
88092f3ab15Sopenharmony_ci    server.io_cb(|mut s| {
88192f3ab15Sopenharmony_ci        assert_eq!(s.read(&mut [0]).unwrap(), 0);
88292f3ab15Sopenharmony_ci        assert_eq!(s.shutdown().unwrap(), ShutdownResult::Received);
88392f3ab15Sopenharmony_ci    });
88492f3ab15Sopenharmony_ci    let server = server.build();
88592f3ab15Sopenharmony_ci
88692f3ab15Sopenharmony_ci    let mut s = server.client().connect();
88792f3ab15Sopenharmony_ci
88892f3ab15Sopenharmony_ci    assert_eq!(s.get_shutdown(), ShutdownState::empty());
88992f3ab15Sopenharmony_ci    assert_eq!(s.shutdown().unwrap(), ShutdownResult::Sent);
89092f3ab15Sopenharmony_ci    assert_eq!(s.get_shutdown(), ShutdownState::SENT);
89192f3ab15Sopenharmony_ci    assert_eq!(s.shutdown().unwrap(), ShutdownResult::Received);
89292f3ab15Sopenharmony_ci    assert_eq!(
89392f3ab15Sopenharmony_ci        s.get_shutdown(),
89492f3ab15Sopenharmony_ci        ShutdownState::SENT | ShutdownState::RECEIVED
89592f3ab15Sopenharmony_ci    );
89692f3ab15Sopenharmony_ci}
89792f3ab15Sopenharmony_ci
89892f3ab15Sopenharmony_ci#[test]
89992f3ab15Sopenharmony_cifn client_ca_list() {
90092f3ab15Sopenharmony_ci    let names = X509Name::load_client_ca_file("test/root-ca.pem").unwrap();
90192f3ab15Sopenharmony_ci    assert_eq!(names.len(), 1);
90292f3ab15Sopenharmony_ci
90392f3ab15Sopenharmony_ci    let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
90492f3ab15Sopenharmony_ci    ctx.set_client_ca_list(names);
90592f3ab15Sopenharmony_ci}
90692f3ab15Sopenharmony_ci
90792f3ab15Sopenharmony_ci#[test]
90892f3ab15Sopenharmony_cifn cert_store() {
90992f3ab15Sopenharmony_ci    let server = Server::builder().build();
91092f3ab15Sopenharmony_ci
91192f3ab15Sopenharmony_ci    let mut client = server.client();
91292f3ab15Sopenharmony_ci    let cert = X509::from_pem(ROOT_CERT).unwrap();
91392f3ab15Sopenharmony_ci    client.ctx().cert_store_mut().add_cert(cert).unwrap();
91492f3ab15Sopenharmony_ci    client.ctx().set_verify(SslVerifyMode::PEER);
91592f3ab15Sopenharmony_ci
91692f3ab15Sopenharmony_ci    client.connect();
91792f3ab15Sopenharmony_ci}
91892f3ab15Sopenharmony_ci
91992f3ab15Sopenharmony_ci#[test]
92092f3ab15Sopenharmony_ci#[cfg_attr(any(all(libressl321, not(libressl340)), boringssl), ignore)]
92192f3ab15Sopenharmony_cifn tmp_dh_callback() {
92292f3ab15Sopenharmony_ci    static CALLED_BACK: AtomicBool = AtomicBool::new(false);
92392f3ab15Sopenharmony_ci
92492f3ab15Sopenharmony_ci    let mut server = Server::builder();
92592f3ab15Sopenharmony_ci    server.ctx().set_tmp_dh_callback(|_, _, _| {
92692f3ab15Sopenharmony_ci        CALLED_BACK.store(true, Ordering::SeqCst);
92792f3ab15Sopenharmony_ci        let dh = include_bytes!("../../../test/dhparams.pem");
92892f3ab15Sopenharmony_ci        Dh::params_from_pem(dh)
92992f3ab15Sopenharmony_ci    });
93092f3ab15Sopenharmony_ci
93192f3ab15Sopenharmony_ci    let server = server.build();
93292f3ab15Sopenharmony_ci
93392f3ab15Sopenharmony_ci    let mut client = server.client();
93492f3ab15Sopenharmony_ci    // TLS 1.3 has no DH suites, so make sure we don't pick that version
93592f3ab15Sopenharmony_ci    #[cfg(any(ossl111, libressl340))]
93692f3ab15Sopenharmony_ci    client.ctx().set_options(super::SslOptions::NO_TLSV1_3);
93792f3ab15Sopenharmony_ci    client.ctx().set_cipher_list("EDH").unwrap();
93892f3ab15Sopenharmony_ci    client.connect();
93992f3ab15Sopenharmony_ci
94092f3ab15Sopenharmony_ci    assert!(CALLED_BACK.load(Ordering::SeqCst));
94192f3ab15Sopenharmony_ci}
94292f3ab15Sopenharmony_ci
94392f3ab15Sopenharmony_ci#[test]
94492f3ab15Sopenharmony_ci#[cfg(all(ossl101, not(ossl110)))]
94592f3ab15Sopenharmony_ci#[allow(deprecated)]
94692f3ab15Sopenharmony_cifn tmp_ecdh_callback() {
94792f3ab15Sopenharmony_ci    use crate::ec::EcKey;
94892f3ab15Sopenharmony_ci    use crate::nid::Nid;
94992f3ab15Sopenharmony_ci
95092f3ab15Sopenharmony_ci    static CALLED_BACK: AtomicBool = AtomicBool::new(false);
95192f3ab15Sopenharmony_ci
95292f3ab15Sopenharmony_ci    let mut server = Server::builder();
95392f3ab15Sopenharmony_ci    server.ctx().set_tmp_ecdh_callback(|_, _, _| {
95492f3ab15Sopenharmony_ci        CALLED_BACK.store(true, Ordering::SeqCst);
95592f3ab15Sopenharmony_ci        EcKey::from_curve_name(Nid::X9_62_PRIME256V1)
95692f3ab15Sopenharmony_ci    });
95792f3ab15Sopenharmony_ci
95892f3ab15Sopenharmony_ci    let server = server.build();
95992f3ab15Sopenharmony_ci
96092f3ab15Sopenharmony_ci    let mut client = server.client();
96192f3ab15Sopenharmony_ci    client.ctx().set_cipher_list("ECDH").unwrap();
96292f3ab15Sopenharmony_ci    client.connect();
96392f3ab15Sopenharmony_ci
96492f3ab15Sopenharmony_ci    assert!(CALLED_BACK.load(Ordering::SeqCst));
96592f3ab15Sopenharmony_ci}
96692f3ab15Sopenharmony_ci
96792f3ab15Sopenharmony_ci#[test]
96892f3ab15Sopenharmony_ci#[cfg_attr(any(all(libressl321, not(libressl340)), boringssl), ignore)]
96992f3ab15Sopenharmony_cifn tmp_dh_callback_ssl() {
97092f3ab15Sopenharmony_ci    static CALLED_BACK: AtomicBool = AtomicBool::new(false);
97192f3ab15Sopenharmony_ci
97292f3ab15Sopenharmony_ci    let mut server = Server::builder();
97392f3ab15Sopenharmony_ci    server.ssl_cb(|ssl| {
97492f3ab15Sopenharmony_ci        ssl.set_tmp_dh_callback(|_, _, _| {
97592f3ab15Sopenharmony_ci            CALLED_BACK.store(true, Ordering::SeqCst);
97692f3ab15Sopenharmony_ci            let dh = include_bytes!("../../../test/dhparams.pem");
97792f3ab15Sopenharmony_ci            Dh::params_from_pem(dh)
97892f3ab15Sopenharmony_ci        });
97992f3ab15Sopenharmony_ci    });
98092f3ab15Sopenharmony_ci
98192f3ab15Sopenharmony_ci    let server = server.build();
98292f3ab15Sopenharmony_ci
98392f3ab15Sopenharmony_ci    let mut client = server.client();
98492f3ab15Sopenharmony_ci    // TLS 1.3 has no DH suites, so make sure we don't pick that version
98592f3ab15Sopenharmony_ci    #[cfg(any(ossl111, libressl340))]
98692f3ab15Sopenharmony_ci    client.ctx().set_options(super::SslOptions::NO_TLSV1_3);
98792f3ab15Sopenharmony_ci    client.ctx().set_cipher_list("EDH").unwrap();
98892f3ab15Sopenharmony_ci    client.connect();
98992f3ab15Sopenharmony_ci
99092f3ab15Sopenharmony_ci    assert!(CALLED_BACK.load(Ordering::SeqCst));
99192f3ab15Sopenharmony_ci}
99292f3ab15Sopenharmony_ci
99392f3ab15Sopenharmony_ci#[test]
99492f3ab15Sopenharmony_ci#[cfg(all(ossl101, not(ossl110)))]
99592f3ab15Sopenharmony_ci#[allow(deprecated)]
99692f3ab15Sopenharmony_cifn tmp_ecdh_callback_ssl() {
99792f3ab15Sopenharmony_ci    use crate::ec::EcKey;
99892f3ab15Sopenharmony_ci    use crate::nid::Nid;
99992f3ab15Sopenharmony_ci
100092f3ab15Sopenharmony_ci    static CALLED_BACK: AtomicBool = AtomicBool::new(false);
100192f3ab15Sopenharmony_ci
100292f3ab15Sopenharmony_ci    let mut server = Server::builder();
100392f3ab15Sopenharmony_ci    server.ssl_cb(|ssl| {
100492f3ab15Sopenharmony_ci        ssl.set_tmp_ecdh_callback(|_, _, _| {
100592f3ab15Sopenharmony_ci            CALLED_BACK.store(true, Ordering::SeqCst);
100692f3ab15Sopenharmony_ci            EcKey::from_curve_name(Nid::X9_62_PRIME256V1)
100792f3ab15Sopenharmony_ci        });
100892f3ab15Sopenharmony_ci    });
100992f3ab15Sopenharmony_ci
101092f3ab15Sopenharmony_ci    let server = server.build();
101192f3ab15Sopenharmony_ci
101292f3ab15Sopenharmony_ci    let mut client = server.client();
101392f3ab15Sopenharmony_ci    client.ctx().set_cipher_list("ECDH").unwrap();
101492f3ab15Sopenharmony_ci    client.connect();
101592f3ab15Sopenharmony_ci
101692f3ab15Sopenharmony_ci    assert!(CALLED_BACK.load(Ordering::SeqCst));
101792f3ab15Sopenharmony_ci}
101892f3ab15Sopenharmony_ci
101992f3ab15Sopenharmony_ci#[test]
102092f3ab15Sopenharmony_cifn idle_session() {
102192f3ab15Sopenharmony_ci    let ctx = SslContext::builder(SslMethod::tls()).unwrap().build();
102292f3ab15Sopenharmony_ci    let ssl = Ssl::new(&ctx).unwrap();
102392f3ab15Sopenharmony_ci    assert!(ssl.session().is_none());
102492f3ab15Sopenharmony_ci}
102592f3ab15Sopenharmony_ci
102692f3ab15Sopenharmony_ci/// possible LibreSSL bug since 3.2.1
102792f3ab15Sopenharmony_ci#[test]
102892f3ab15Sopenharmony_ci#[cfg_attr(libressl321, ignore)]
102992f3ab15Sopenharmony_cifn active_session() {
103092f3ab15Sopenharmony_ci    let server = Server::builder().build();
103192f3ab15Sopenharmony_ci
103292f3ab15Sopenharmony_ci    let s = server.client().connect();
103392f3ab15Sopenharmony_ci
103492f3ab15Sopenharmony_ci    let session = s.ssl().session().unwrap();
103592f3ab15Sopenharmony_ci    let len = session.master_key_len();
103692f3ab15Sopenharmony_ci    let mut buf = vec![0; len - 1];
103792f3ab15Sopenharmony_ci    let copied = session.master_key(&mut buf);
103892f3ab15Sopenharmony_ci    assert_eq!(copied, buf.len());
103992f3ab15Sopenharmony_ci    let mut buf = vec![0; len + 1];
104092f3ab15Sopenharmony_ci    let copied = session.master_key(&mut buf);
104192f3ab15Sopenharmony_ci    assert_eq!(copied, len);
104292f3ab15Sopenharmony_ci}
104392f3ab15Sopenharmony_ci
104492f3ab15Sopenharmony_ci#[test]
104592f3ab15Sopenharmony_ci#[cfg(not(boringssl))]
104692f3ab15Sopenharmony_cifn status_callbacks() {
104792f3ab15Sopenharmony_ci    static CALLED_BACK_SERVER: AtomicBool = AtomicBool::new(false);
104892f3ab15Sopenharmony_ci    static CALLED_BACK_CLIENT: AtomicBool = AtomicBool::new(false);
104992f3ab15Sopenharmony_ci
105092f3ab15Sopenharmony_ci    let mut server = Server::builder();
105192f3ab15Sopenharmony_ci    server
105292f3ab15Sopenharmony_ci        .ctx()
105392f3ab15Sopenharmony_ci        .set_status_callback(|ssl| {
105492f3ab15Sopenharmony_ci            CALLED_BACK_SERVER.store(true, Ordering::SeqCst);
105592f3ab15Sopenharmony_ci            let response = OcspResponse::create(OcspResponseStatus::UNAUTHORIZED, None).unwrap();
105692f3ab15Sopenharmony_ci            let response = response.to_der().unwrap();
105792f3ab15Sopenharmony_ci            ssl.set_ocsp_status(&response).unwrap();
105892f3ab15Sopenharmony_ci            Ok(true)
105992f3ab15Sopenharmony_ci        })
106092f3ab15Sopenharmony_ci        .unwrap();
106192f3ab15Sopenharmony_ci
106292f3ab15Sopenharmony_ci    let server = server.build();
106392f3ab15Sopenharmony_ci
106492f3ab15Sopenharmony_ci    let mut client = server.client();
106592f3ab15Sopenharmony_ci    client
106692f3ab15Sopenharmony_ci        .ctx()
106792f3ab15Sopenharmony_ci        .set_status_callback(|ssl| {
106892f3ab15Sopenharmony_ci            CALLED_BACK_CLIENT.store(true, Ordering::SeqCst);
106992f3ab15Sopenharmony_ci            let response = OcspResponse::from_der(ssl.ocsp_status().unwrap()).unwrap();
107092f3ab15Sopenharmony_ci            assert_eq!(response.status(), OcspResponseStatus::UNAUTHORIZED);
107192f3ab15Sopenharmony_ci            Ok(true)
107292f3ab15Sopenharmony_ci        })
107392f3ab15Sopenharmony_ci        .unwrap();
107492f3ab15Sopenharmony_ci
107592f3ab15Sopenharmony_ci    let mut client = client.build().builder();
107692f3ab15Sopenharmony_ci    client.ssl().set_status_type(StatusType::OCSP).unwrap();
107792f3ab15Sopenharmony_ci
107892f3ab15Sopenharmony_ci    client.connect();
107992f3ab15Sopenharmony_ci
108092f3ab15Sopenharmony_ci    assert!(CALLED_BACK_SERVER.load(Ordering::SeqCst));
108192f3ab15Sopenharmony_ci    assert!(CALLED_BACK_CLIENT.load(Ordering::SeqCst));
108292f3ab15Sopenharmony_ci}
108392f3ab15Sopenharmony_ci
108492f3ab15Sopenharmony_ci/// possible LibreSSL bug since 3.2.1
108592f3ab15Sopenharmony_ci#[test]
108692f3ab15Sopenharmony_ci#[cfg_attr(libressl321, ignore)]
108792f3ab15Sopenharmony_cifn new_session_callback() {
108892f3ab15Sopenharmony_ci    static CALLED_BACK: AtomicBool = AtomicBool::new(false);
108992f3ab15Sopenharmony_ci
109092f3ab15Sopenharmony_ci    let mut server = Server::builder();
109192f3ab15Sopenharmony_ci    server.ctx().set_session_id_context(b"foo").unwrap();
109292f3ab15Sopenharmony_ci
109392f3ab15Sopenharmony_ci    let server = server.build();
109492f3ab15Sopenharmony_ci
109592f3ab15Sopenharmony_ci    let mut client = server.client();
109692f3ab15Sopenharmony_ci
109792f3ab15Sopenharmony_ci    client
109892f3ab15Sopenharmony_ci        .ctx()
109992f3ab15Sopenharmony_ci        .set_session_cache_mode(SslSessionCacheMode::CLIENT | SslSessionCacheMode::NO_INTERNAL);
110092f3ab15Sopenharmony_ci    client
110192f3ab15Sopenharmony_ci        .ctx()
110292f3ab15Sopenharmony_ci        .set_new_session_callback(|_, _| CALLED_BACK.store(true, Ordering::SeqCst));
110392f3ab15Sopenharmony_ci
110492f3ab15Sopenharmony_ci    client.connect();
110592f3ab15Sopenharmony_ci
110692f3ab15Sopenharmony_ci    assert!(CALLED_BACK.load(Ordering::SeqCst));
110792f3ab15Sopenharmony_ci}
110892f3ab15Sopenharmony_ci
110992f3ab15Sopenharmony_ci/// possible LibreSSL bug since 3.2.1
111092f3ab15Sopenharmony_ci#[test]
111192f3ab15Sopenharmony_ci#[cfg_attr(libressl321, ignore)]
111292f3ab15Sopenharmony_cifn new_session_callback_swapped_ctx() {
111392f3ab15Sopenharmony_ci    static CALLED_BACK: AtomicBool = AtomicBool::new(false);
111492f3ab15Sopenharmony_ci
111592f3ab15Sopenharmony_ci    let mut server = Server::builder();
111692f3ab15Sopenharmony_ci    server.ctx().set_session_id_context(b"foo").unwrap();
111792f3ab15Sopenharmony_ci
111892f3ab15Sopenharmony_ci    let server = server.build();
111992f3ab15Sopenharmony_ci
112092f3ab15Sopenharmony_ci    let mut client = server.client();
112192f3ab15Sopenharmony_ci
112292f3ab15Sopenharmony_ci    client
112392f3ab15Sopenharmony_ci        .ctx()
112492f3ab15Sopenharmony_ci        .set_session_cache_mode(SslSessionCacheMode::CLIENT | SslSessionCacheMode::NO_INTERNAL);
112592f3ab15Sopenharmony_ci    client
112692f3ab15Sopenharmony_ci        .ctx()
112792f3ab15Sopenharmony_ci        .set_new_session_callback(|_, _| CALLED_BACK.store(true, Ordering::SeqCst));
112892f3ab15Sopenharmony_ci
112992f3ab15Sopenharmony_ci    let mut client = client.build().builder();
113092f3ab15Sopenharmony_ci
113192f3ab15Sopenharmony_ci    let ctx = SslContextBuilder::new(SslMethod::tls()).unwrap().build();
113292f3ab15Sopenharmony_ci    client.ssl().set_ssl_context(&ctx).unwrap();
113392f3ab15Sopenharmony_ci
113492f3ab15Sopenharmony_ci    client.connect();
113592f3ab15Sopenharmony_ci
113692f3ab15Sopenharmony_ci    assert!(CALLED_BACK.load(Ordering::SeqCst));
113792f3ab15Sopenharmony_ci}
113892f3ab15Sopenharmony_ci
113992f3ab15Sopenharmony_ci#[test]
114092f3ab15Sopenharmony_cifn keying_export() {
114192f3ab15Sopenharmony_ci    let listener = TcpListener::bind("127.0.0.1:0").unwrap();
114292f3ab15Sopenharmony_ci    let addr = listener.local_addr().unwrap();
114392f3ab15Sopenharmony_ci
114492f3ab15Sopenharmony_ci    let label = "EXPERIMENTAL test";
114592f3ab15Sopenharmony_ci    let context = b"my context";
114692f3ab15Sopenharmony_ci
114792f3ab15Sopenharmony_ci    let guard = thread::spawn(move || {
114892f3ab15Sopenharmony_ci        let stream = listener.accept().unwrap().0;
114992f3ab15Sopenharmony_ci        let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
115092f3ab15Sopenharmony_ci        ctx.set_certificate_file(Path::new("test/cert.pem"), SslFiletype::PEM)
115192f3ab15Sopenharmony_ci            .unwrap();
115292f3ab15Sopenharmony_ci        ctx.set_private_key_file(Path::new("test/key.pem"), SslFiletype::PEM)
115392f3ab15Sopenharmony_ci            .unwrap();
115492f3ab15Sopenharmony_ci        let ssl = Ssl::new(&ctx.build()).unwrap();
115592f3ab15Sopenharmony_ci        let mut stream = ssl.accept(stream).unwrap();
115692f3ab15Sopenharmony_ci
115792f3ab15Sopenharmony_ci        let mut buf = [0; 32];
115892f3ab15Sopenharmony_ci        stream
115992f3ab15Sopenharmony_ci            .ssl()
116092f3ab15Sopenharmony_ci            .export_keying_material(&mut buf, label, Some(context))
116192f3ab15Sopenharmony_ci            .unwrap();
116292f3ab15Sopenharmony_ci
116392f3ab15Sopenharmony_ci        stream.write_all(&[0]).unwrap();
116492f3ab15Sopenharmony_ci
116592f3ab15Sopenharmony_ci        buf
116692f3ab15Sopenharmony_ci    });
116792f3ab15Sopenharmony_ci
116892f3ab15Sopenharmony_ci    let stream = TcpStream::connect(addr).unwrap();
116992f3ab15Sopenharmony_ci    let ctx = SslContext::builder(SslMethod::tls()).unwrap();
117092f3ab15Sopenharmony_ci    let ssl = Ssl::new(&ctx.build()).unwrap();
117192f3ab15Sopenharmony_ci    let mut stream = ssl.connect(stream).unwrap();
117292f3ab15Sopenharmony_ci
117392f3ab15Sopenharmony_ci    let mut buf = [1; 32];
117492f3ab15Sopenharmony_ci    stream
117592f3ab15Sopenharmony_ci        .ssl()
117692f3ab15Sopenharmony_ci        .export_keying_material(&mut buf, label, Some(context))
117792f3ab15Sopenharmony_ci        .unwrap();
117892f3ab15Sopenharmony_ci
117992f3ab15Sopenharmony_ci    stream.read_exact(&mut [0]).unwrap();
118092f3ab15Sopenharmony_ci
118192f3ab15Sopenharmony_ci    let buf2 = guard.join().unwrap();
118292f3ab15Sopenharmony_ci
118392f3ab15Sopenharmony_ci    assert_eq!(buf, buf2);
118492f3ab15Sopenharmony_ci}
118592f3ab15Sopenharmony_ci
118692f3ab15Sopenharmony_ci#[test]
118792f3ab15Sopenharmony_ci#[cfg(any(ossl110, libressl261))]
118892f3ab15Sopenharmony_cifn no_version_overlap() {
118992f3ab15Sopenharmony_ci    let mut server = Server::builder();
119092f3ab15Sopenharmony_ci    server.ctx().set_min_proto_version(None).unwrap();
119192f3ab15Sopenharmony_ci    server
119292f3ab15Sopenharmony_ci        .ctx()
119392f3ab15Sopenharmony_ci        .set_max_proto_version(Some(SslVersion::TLS1_1))
119492f3ab15Sopenharmony_ci        .unwrap();
119592f3ab15Sopenharmony_ci    #[cfg(any(ossl110g, libressl270))]
119692f3ab15Sopenharmony_ci    assert_eq!(server.ctx().max_proto_version(), Some(SslVersion::TLS1_1));
119792f3ab15Sopenharmony_ci    server.should_error();
119892f3ab15Sopenharmony_ci    let server = server.build();
119992f3ab15Sopenharmony_ci
120092f3ab15Sopenharmony_ci    let mut client = server.client();
120192f3ab15Sopenharmony_ci    client
120292f3ab15Sopenharmony_ci        .ctx()
120392f3ab15Sopenharmony_ci        .set_min_proto_version(Some(SslVersion::TLS1_2))
120492f3ab15Sopenharmony_ci        .unwrap();
120592f3ab15Sopenharmony_ci    #[cfg(ossl110g)]
120692f3ab15Sopenharmony_ci    assert_eq!(client.ctx().min_proto_version(), Some(SslVersion::TLS1_2));
120792f3ab15Sopenharmony_ci    client.ctx().set_max_proto_version(None).unwrap();
120892f3ab15Sopenharmony_ci
120992f3ab15Sopenharmony_ci    client.connect_err();
121092f3ab15Sopenharmony_ci}
121192f3ab15Sopenharmony_ci
121292f3ab15Sopenharmony_ci#[test]
121392f3ab15Sopenharmony_ci#[cfg(ossl111)]
121492f3ab15Sopenharmony_cifn custom_extensions() {
121592f3ab15Sopenharmony_ci    static FOUND_EXTENSION: AtomicBool = AtomicBool::new(false);
121692f3ab15Sopenharmony_ci
121792f3ab15Sopenharmony_ci    let mut server = Server::builder();
121892f3ab15Sopenharmony_ci    server
121992f3ab15Sopenharmony_ci        .ctx()
122092f3ab15Sopenharmony_ci        .add_custom_ext(
122192f3ab15Sopenharmony_ci            12345,
122292f3ab15Sopenharmony_ci            ExtensionContext::CLIENT_HELLO,
122392f3ab15Sopenharmony_ci            |_, _, _| -> Result<Option<&'static [u8]>, _> { unreachable!() },
122492f3ab15Sopenharmony_ci            |_, _, data, _| {
122592f3ab15Sopenharmony_ci                FOUND_EXTENSION.store(data == b"hello", Ordering::SeqCst);
122692f3ab15Sopenharmony_ci                Ok(())
122792f3ab15Sopenharmony_ci            },
122892f3ab15Sopenharmony_ci        )
122992f3ab15Sopenharmony_ci        .unwrap();
123092f3ab15Sopenharmony_ci
123192f3ab15Sopenharmony_ci    let server = server.build();
123292f3ab15Sopenharmony_ci
123392f3ab15Sopenharmony_ci    let mut client = server.client();
123492f3ab15Sopenharmony_ci    client
123592f3ab15Sopenharmony_ci        .ctx()
123692f3ab15Sopenharmony_ci        .add_custom_ext(
123792f3ab15Sopenharmony_ci            12345,
123892f3ab15Sopenharmony_ci            ssl::ExtensionContext::CLIENT_HELLO,
123992f3ab15Sopenharmony_ci            |_, _, _| Ok(Some(b"hello")),
124092f3ab15Sopenharmony_ci            |_, _, _, _| unreachable!(),
124192f3ab15Sopenharmony_ci        )
124292f3ab15Sopenharmony_ci        .unwrap();
124392f3ab15Sopenharmony_ci
124492f3ab15Sopenharmony_ci    client.connect();
124592f3ab15Sopenharmony_ci
124692f3ab15Sopenharmony_ci    assert!(FOUND_EXTENSION.load(Ordering::SeqCst));
124792f3ab15Sopenharmony_ci}
124892f3ab15Sopenharmony_ci
124992f3ab15Sopenharmony_cifn _check_kinds() {
125092f3ab15Sopenharmony_ci    fn is_send<T: Send>() {}
125192f3ab15Sopenharmony_ci    fn is_sync<T: Sync>() {}
125292f3ab15Sopenharmony_ci
125392f3ab15Sopenharmony_ci    is_send::<SslStream<TcpStream>>();
125492f3ab15Sopenharmony_ci    is_sync::<SslStream<TcpStream>>();
125592f3ab15Sopenharmony_ci}
125692f3ab15Sopenharmony_ci
125792f3ab15Sopenharmony_ci#[test]
125892f3ab15Sopenharmony_ci#[cfg(ossl111)]
125992f3ab15Sopenharmony_cifn stateless() {
126092f3ab15Sopenharmony_ci    use super::SslOptions;
126192f3ab15Sopenharmony_ci
126292f3ab15Sopenharmony_ci    #[derive(Debug)]
126392f3ab15Sopenharmony_ci    struct MemoryStream {
126492f3ab15Sopenharmony_ci        incoming: io::Cursor<Vec<u8>>,
126592f3ab15Sopenharmony_ci        outgoing: Vec<u8>,
126692f3ab15Sopenharmony_ci    }
126792f3ab15Sopenharmony_ci
126892f3ab15Sopenharmony_ci    impl MemoryStream {
126992f3ab15Sopenharmony_ci        pub fn new() -> Self {
127092f3ab15Sopenharmony_ci            Self {
127192f3ab15Sopenharmony_ci                incoming: io::Cursor::new(Vec::new()),
127292f3ab15Sopenharmony_ci                outgoing: Vec::new(),
127392f3ab15Sopenharmony_ci            }
127492f3ab15Sopenharmony_ci        }
127592f3ab15Sopenharmony_ci
127692f3ab15Sopenharmony_ci        pub fn extend_incoming(&mut self, data: &[u8]) {
127792f3ab15Sopenharmony_ci            self.incoming.get_mut().extend_from_slice(data);
127892f3ab15Sopenharmony_ci        }
127992f3ab15Sopenharmony_ci
128092f3ab15Sopenharmony_ci        pub fn take_outgoing(&mut self) -> Outgoing<'_> {
128192f3ab15Sopenharmony_ci            Outgoing(&mut self.outgoing)
128292f3ab15Sopenharmony_ci        }
128392f3ab15Sopenharmony_ci    }
128492f3ab15Sopenharmony_ci
128592f3ab15Sopenharmony_ci    impl Read for MemoryStream {
128692f3ab15Sopenharmony_ci        fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
128792f3ab15Sopenharmony_ci            let n = self.incoming.read(buf)?;
128892f3ab15Sopenharmony_ci            if self.incoming.position() == self.incoming.get_ref().len() as u64 {
128992f3ab15Sopenharmony_ci                self.incoming.set_position(0);
129092f3ab15Sopenharmony_ci                self.incoming.get_mut().clear();
129192f3ab15Sopenharmony_ci            }
129292f3ab15Sopenharmony_ci            if n == 0 {
129392f3ab15Sopenharmony_ci                return Err(io::Error::new(
129492f3ab15Sopenharmony_ci                    io::ErrorKind::WouldBlock,
129592f3ab15Sopenharmony_ci                    "no data available",
129692f3ab15Sopenharmony_ci                ));
129792f3ab15Sopenharmony_ci            }
129892f3ab15Sopenharmony_ci            Ok(n)
129992f3ab15Sopenharmony_ci        }
130092f3ab15Sopenharmony_ci    }
130192f3ab15Sopenharmony_ci
130292f3ab15Sopenharmony_ci    impl Write for MemoryStream {
130392f3ab15Sopenharmony_ci        fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
130492f3ab15Sopenharmony_ci            self.outgoing.write(buf)
130592f3ab15Sopenharmony_ci        }
130692f3ab15Sopenharmony_ci
130792f3ab15Sopenharmony_ci        fn flush(&mut self) -> io::Result<()> {
130892f3ab15Sopenharmony_ci            Ok(())
130992f3ab15Sopenharmony_ci        }
131092f3ab15Sopenharmony_ci    }
131192f3ab15Sopenharmony_ci
131292f3ab15Sopenharmony_ci    pub struct Outgoing<'a>(&'a mut Vec<u8>);
131392f3ab15Sopenharmony_ci
131492f3ab15Sopenharmony_ci    impl<'a> Drop for Outgoing<'a> {
131592f3ab15Sopenharmony_ci        fn drop(&mut self) {
131692f3ab15Sopenharmony_ci            self.0.clear();
131792f3ab15Sopenharmony_ci        }
131892f3ab15Sopenharmony_ci    }
131992f3ab15Sopenharmony_ci
132092f3ab15Sopenharmony_ci    impl<'a> ::std::ops::Deref for Outgoing<'a> {
132192f3ab15Sopenharmony_ci        type Target = [u8];
132292f3ab15Sopenharmony_ci        fn deref(&self) -> &[u8] {
132392f3ab15Sopenharmony_ci            self.0
132492f3ab15Sopenharmony_ci        }
132592f3ab15Sopenharmony_ci    }
132692f3ab15Sopenharmony_ci
132792f3ab15Sopenharmony_ci    impl<'a> AsRef<[u8]> for Outgoing<'a> {
132892f3ab15Sopenharmony_ci        fn as_ref(&self) -> &[u8] {
132992f3ab15Sopenharmony_ci            self.0
133092f3ab15Sopenharmony_ci        }
133192f3ab15Sopenharmony_ci    }
133292f3ab15Sopenharmony_ci
133392f3ab15Sopenharmony_ci    fn send(from: &mut MemoryStream, to: &mut MemoryStream) {
133492f3ab15Sopenharmony_ci        to.extend_incoming(&from.take_outgoing());
133592f3ab15Sopenharmony_ci    }
133692f3ab15Sopenharmony_ci
133792f3ab15Sopenharmony_ci    //
133892f3ab15Sopenharmony_ci    // Setup
133992f3ab15Sopenharmony_ci    //
134092f3ab15Sopenharmony_ci
134192f3ab15Sopenharmony_ci    let mut client_ctx = SslContext::builder(SslMethod::tls()).unwrap();
134292f3ab15Sopenharmony_ci    client_ctx.clear_options(SslOptions::ENABLE_MIDDLEBOX_COMPAT);
134392f3ab15Sopenharmony_ci    let mut client_stream =
134492f3ab15Sopenharmony_ci        SslStream::new(Ssl::new(&client_ctx.build()).unwrap(), MemoryStream::new()).unwrap();
134592f3ab15Sopenharmony_ci
134692f3ab15Sopenharmony_ci    let mut server_ctx = SslContext::builder(SslMethod::tls()).unwrap();
134792f3ab15Sopenharmony_ci    server_ctx
134892f3ab15Sopenharmony_ci        .set_certificate_file(Path::new("test/cert.pem"), SslFiletype::PEM)
134992f3ab15Sopenharmony_ci        .unwrap();
135092f3ab15Sopenharmony_ci    server_ctx
135192f3ab15Sopenharmony_ci        .set_private_key_file(Path::new("test/key.pem"), SslFiletype::PEM)
135292f3ab15Sopenharmony_ci        .unwrap();
135392f3ab15Sopenharmony_ci    const COOKIE: &[u8] = b"chocolate chip";
135492f3ab15Sopenharmony_ci    server_ctx.set_stateless_cookie_generate_cb(|_tls, buf| {
135592f3ab15Sopenharmony_ci        buf[0..COOKIE.len()].copy_from_slice(COOKIE);
135692f3ab15Sopenharmony_ci        Ok(COOKIE.len())
135792f3ab15Sopenharmony_ci    });
135892f3ab15Sopenharmony_ci    server_ctx.set_stateless_cookie_verify_cb(|_tls, buf| buf == COOKIE);
135992f3ab15Sopenharmony_ci    let mut server_stream =
136092f3ab15Sopenharmony_ci        SslStream::new(Ssl::new(&server_ctx.build()).unwrap(), MemoryStream::new()).unwrap();
136192f3ab15Sopenharmony_ci
136292f3ab15Sopenharmony_ci    //
136392f3ab15Sopenharmony_ci    // Handshake
136492f3ab15Sopenharmony_ci    //
136592f3ab15Sopenharmony_ci
136692f3ab15Sopenharmony_ci    // Initial ClientHello
136792f3ab15Sopenharmony_ci    client_stream.connect().unwrap_err();
136892f3ab15Sopenharmony_ci    send(client_stream.get_mut(), server_stream.get_mut());
136992f3ab15Sopenharmony_ci    // HelloRetryRequest
137092f3ab15Sopenharmony_ci    assert!(!server_stream.stateless().unwrap());
137192f3ab15Sopenharmony_ci    send(server_stream.get_mut(), client_stream.get_mut());
137292f3ab15Sopenharmony_ci    // Second ClientHello
137392f3ab15Sopenharmony_ci    client_stream.do_handshake().unwrap_err();
137492f3ab15Sopenharmony_ci    send(client_stream.get_mut(), server_stream.get_mut());
137592f3ab15Sopenharmony_ci    // OldServerHello
137692f3ab15Sopenharmony_ci    assert!(server_stream.stateless().unwrap());
137792f3ab15Sopenharmony_ci    server_stream.accept().unwrap_err();
137892f3ab15Sopenharmony_ci    send(server_stream.get_mut(), client_stream.get_mut());
137992f3ab15Sopenharmony_ci    // Finished
138092f3ab15Sopenharmony_ci    client_stream.do_handshake().unwrap();
138192f3ab15Sopenharmony_ci    send(client_stream.get_mut(), server_stream.get_mut());
138292f3ab15Sopenharmony_ci    server_stream.do_handshake().unwrap();
138392f3ab15Sopenharmony_ci}
138492f3ab15Sopenharmony_ci
138592f3ab15Sopenharmony_ci#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
138692f3ab15Sopenharmony_ci#[test]
138792f3ab15Sopenharmony_cifn psk_ciphers() {
138892f3ab15Sopenharmony_ci    const CIPHER: &str = "PSK-AES256-CBC-SHA";
138992f3ab15Sopenharmony_ci    const PSK: &[u8] = b"thisisaverysecurekey";
139092f3ab15Sopenharmony_ci    const CLIENT_IDENT: &[u8] = b"thisisaclient";
139192f3ab15Sopenharmony_ci    static CLIENT_CALLED: AtomicBool = AtomicBool::new(false);
139292f3ab15Sopenharmony_ci    static SERVER_CALLED: AtomicBool = AtomicBool::new(false);
139392f3ab15Sopenharmony_ci
139492f3ab15Sopenharmony_ci    let mut server = Server::builder();
139592f3ab15Sopenharmony_ci    server.ctx().set_cipher_list(CIPHER).unwrap();
139692f3ab15Sopenharmony_ci    server.ctx().set_psk_server_callback(|_, identity, psk| {
139792f3ab15Sopenharmony_ci        assert!(identity.unwrap_or(&[]) == CLIENT_IDENT);
139892f3ab15Sopenharmony_ci        psk[..PSK.len()].copy_from_slice(PSK);
139992f3ab15Sopenharmony_ci        SERVER_CALLED.store(true, Ordering::SeqCst);
140092f3ab15Sopenharmony_ci        Ok(PSK.len())
140192f3ab15Sopenharmony_ci    });
140292f3ab15Sopenharmony_ci
140392f3ab15Sopenharmony_ci    let server = server.build();
140492f3ab15Sopenharmony_ci
140592f3ab15Sopenharmony_ci    let mut client = server.client();
140692f3ab15Sopenharmony_ci    // This test relies on TLS 1.2 suites
140792f3ab15Sopenharmony_ci    #[cfg(any(boringssl, ossl111))]
140892f3ab15Sopenharmony_ci    client.ctx().set_options(super::SslOptions::NO_TLSV1_3);
140992f3ab15Sopenharmony_ci    client.ctx().set_cipher_list(CIPHER).unwrap();
141092f3ab15Sopenharmony_ci    client
141192f3ab15Sopenharmony_ci        .ctx()
141292f3ab15Sopenharmony_ci        .set_psk_client_callback(move |_, _, identity, psk| {
141392f3ab15Sopenharmony_ci            identity[..CLIENT_IDENT.len()].copy_from_slice(CLIENT_IDENT);
141492f3ab15Sopenharmony_ci            identity[CLIENT_IDENT.len()] = 0;
141592f3ab15Sopenharmony_ci            psk[..PSK.len()].copy_from_slice(PSK);
141692f3ab15Sopenharmony_ci            CLIENT_CALLED.store(true, Ordering::SeqCst);
141792f3ab15Sopenharmony_ci            Ok(PSK.len())
141892f3ab15Sopenharmony_ci        });
141992f3ab15Sopenharmony_ci
142092f3ab15Sopenharmony_ci    client.connect();
142192f3ab15Sopenharmony_ci
142292f3ab15Sopenharmony_ci    assert!(SERVER_CALLED.load(Ordering::SeqCst));
142392f3ab15Sopenharmony_ci    assert!(CLIENT_CALLED.load(Ordering::SeqCst));
142492f3ab15Sopenharmony_ci}
142592f3ab15Sopenharmony_ci
142692f3ab15Sopenharmony_ci#[test]
142792f3ab15Sopenharmony_cifn sni_callback_swapped_ctx() {
142892f3ab15Sopenharmony_ci    static CALLED_BACK: AtomicBool = AtomicBool::new(false);
142992f3ab15Sopenharmony_ci
143092f3ab15Sopenharmony_ci    let mut server = Server::builder();
143192f3ab15Sopenharmony_ci
143292f3ab15Sopenharmony_ci    let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
143392f3ab15Sopenharmony_ci    ctx.set_servername_callback(|_, _| {
143492f3ab15Sopenharmony_ci        CALLED_BACK.store(true, Ordering::SeqCst);
143592f3ab15Sopenharmony_ci        Ok(())
143692f3ab15Sopenharmony_ci    });
143792f3ab15Sopenharmony_ci
143892f3ab15Sopenharmony_ci    let keyed_ctx = mem::replace(server.ctx(), ctx).build();
143992f3ab15Sopenharmony_ci    server.ssl_cb(move |ssl| ssl.set_ssl_context(&keyed_ctx).unwrap());
144092f3ab15Sopenharmony_ci
144192f3ab15Sopenharmony_ci    let server = server.build();
144292f3ab15Sopenharmony_ci
144392f3ab15Sopenharmony_ci    server.client().connect();
144492f3ab15Sopenharmony_ci
144592f3ab15Sopenharmony_ci    assert!(CALLED_BACK.load(Ordering::SeqCst));
144692f3ab15Sopenharmony_ci}
144792f3ab15Sopenharmony_ci
144892f3ab15Sopenharmony_ci#[test]
144992f3ab15Sopenharmony_ci#[cfg(ossl111)]
145092f3ab15Sopenharmony_cifn client_hello() {
145192f3ab15Sopenharmony_ci    static CALLED_BACK: AtomicBool = AtomicBool::new(false);
145292f3ab15Sopenharmony_ci
145392f3ab15Sopenharmony_ci    let mut server = Server::builder();
145492f3ab15Sopenharmony_ci    server.ctx().set_client_hello_callback(|ssl, _| {
145592f3ab15Sopenharmony_ci        assert!(!ssl.client_hello_isv2());
145692f3ab15Sopenharmony_ci        assert_eq!(ssl.client_hello_legacy_version(), Some(SslVersion::TLS1_2));
145792f3ab15Sopenharmony_ci        assert!(ssl.client_hello_random().is_some());
145892f3ab15Sopenharmony_ci        assert!(ssl.client_hello_session_id().is_some());
145992f3ab15Sopenharmony_ci        assert!(ssl.client_hello_ciphers().is_some());
146092f3ab15Sopenharmony_ci        assert!(ssl.client_hello_compression_methods().is_some());
146192f3ab15Sopenharmony_ci        assert!(ssl
146292f3ab15Sopenharmony_ci            .bytes_to_cipher_list(ssl.client_hello_ciphers().unwrap(), ssl.client_hello_isv2())
146392f3ab15Sopenharmony_ci            .is_ok());
146492f3ab15Sopenharmony_ci
146592f3ab15Sopenharmony_ci        CALLED_BACK.store(true, Ordering::SeqCst);
146692f3ab15Sopenharmony_ci        Ok(ClientHelloResponse::SUCCESS)
146792f3ab15Sopenharmony_ci    });
146892f3ab15Sopenharmony_ci
146992f3ab15Sopenharmony_ci    let server = server.build();
147092f3ab15Sopenharmony_ci    server.client().connect();
147192f3ab15Sopenharmony_ci
147292f3ab15Sopenharmony_ci    assert!(CALLED_BACK.load(Ordering::SeqCst));
147392f3ab15Sopenharmony_ci}
147492f3ab15Sopenharmony_ci
147592f3ab15Sopenharmony_ci#[test]
147692f3ab15Sopenharmony_ci#[cfg(ossl111)]
147792f3ab15Sopenharmony_cifn openssl_cipher_name() {
147892f3ab15Sopenharmony_ci    assert_eq!(
147992f3ab15Sopenharmony_ci        super::cipher_name("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"),
148092f3ab15Sopenharmony_ci        "ECDHE-RSA-AES256-SHA384",
148192f3ab15Sopenharmony_ci    );
148292f3ab15Sopenharmony_ci
148392f3ab15Sopenharmony_ci    assert_eq!(super::cipher_name("asdf"), "(NONE)");
148492f3ab15Sopenharmony_ci}
148592f3ab15Sopenharmony_ci
148692f3ab15Sopenharmony_ci#[test]
148792f3ab15Sopenharmony_cifn session_cache_size() {
148892f3ab15Sopenharmony_ci    let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
148992f3ab15Sopenharmony_ci    ctx.set_session_cache_size(1234);
149092f3ab15Sopenharmony_ci    let ctx = ctx.build();
149192f3ab15Sopenharmony_ci    assert_eq!(ctx.session_cache_size(), 1234);
149292f3ab15Sopenharmony_ci}
149392f3ab15Sopenharmony_ci
149492f3ab15Sopenharmony_ci#[test]
149592f3ab15Sopenharmony_ci#[cfg(ossl102)]
149692f3ab15Sopenharmony_cifn add_chain_cert() {
149792f3ab15Sopenharmony_ci    let ctx = SslContext::builder(SslMethod::tls()).unwrap().build();
149892f3ab15Sopenharmony_ci    let cert = X509::from_pem(CERT).unwrap();
149992f3ab15Sopenharmony_ci    let mut ssl = Ssl::new(&ctx).unwrap();
150092f3ab15Sopenharmony_ci    assert!(ssl.add_chain_cert(cert).is_ok());
150192f3ab15Sopenharmony_ci}
150292f3ab15Sopenharmony_ci#[test]
150392f3ab15Sopenharmony_ci#[cfg(ossl111)]
150492f3ab15Sopenharmony_cifn set_ssl_certificate_key_related_api() {
150592f3ab15Sopenharmony_ci    let cert_str: &str = include_str!("../../../test/cert.pem");
150692f3ab15Sopenharmony_ci    let key_str: &str = include_str!("../../../test/key.pem");
150792f3ab15Sopenharmony_ci    let ctx = SslContext::builder(SslMethod::tls()).unwrap().build();
150892f3ab15Sopenharmony_ci    let cert_x509 = X509::from_pem(CERT).unwrap();
150992f3ab15Sopenharmony_ci    let mut ssl = Ssl::new(&ctx).unwrap();
151092f3ab15Sopenharmony_ci    assert!(ssl.set_method(SslMethod::tls()).is_ok());
151192f3ab15Sopenharmony_ci    ssl.set_private_key_file("test/key.pem", SslFiletype::PEM)
151292f3ab15Sopenharmony_ci        .unwrap();
151392f3ab15Sopenharmony_ci    {
151492f3ab15Sopenharmony_ci        let pkey = String::from_utf8(
151592f3ab15Sopenharmony_ci            ssl.private_key()
151692f3ab15Sopenharmony_ci                .unwrap()
151792f3ab15Sopenharmony_ci                .private_key_to_pem_pkcs8()
151892f3ab15Sopenharmony_ci                .unwrap(),
151992f3ab15Sopenharmony_ci        )
152092f3ab15Sopenharmony_ci        .unwrap();
152192f3ab15Sopenharmony_ci        assert!(pkey.lines().eq(key_str.lines()));
152292f3ab15Sopenharmony_ci    }
152392f3ab15Sopenharmony_ci    let pkey = PKey::private_key_from_pem(KEY).unwrap();
152492f3ab15Sopenharmony_ci    ssl.set_private_key(pkey.as_ref()).unwrap();
152592f3ab15Sopenharmony_ci    {
152692f3ab15Sopenharmony_ci        let pkey = String::from_utf8(
152792f3ab15Sopenharmony_ci            ssl.private_key()
152892f3ab15Sopenharmony_ci                .unwrap()
152992f3ab15Sopenharmony_ci                .private_key_to_pem_pkcs8()
153092f3ab15Sopenharmony_ci                .unwrap(),
153192f3ab15Sopenharmony_ci        )
153292f3ab15Sopenharmony_ci        .unwrap();
153392f3ab15Sopenharmony_ci        assert!(pkey.lines().eq(key_str.lines()));
153492f3ab15Sopenharmony_ci    }
153592f3ab15Sopenharmony_ci    ssl.set_certificate(cert_x509.as_ref()).unwrap();
153692f3ab15Sopenharmony_ci    let cert = String::from_utf8(ssl.certificate().unwrap().to_pem().unwrap()).unwrap();
153792f3ab15Sopenharmony_ci    assert!(cert.lines().eq(cert_str.lines()));
153892f3ab15Sopenharmony_ci    ssl.add_client_ca(cert_x509.as_ref()).unwrap();
153992f3ab15Sopenharmony_ci    ssl.set_min_proto_version(Some(SslVersion::TLS1_2)).unwrap();
154092f3ab15Sopenharmony_ci    ssl.set_max_proto_version(Some(SslVersion::TLS1_3)).unwrap();
154192f3ab15Sopenharmony_ci    ssl.set_cipher_list("HIGH:!aNULL:!MD5").unwrap();
154292f3ab15Sopenharmony_ci    ssl.set_ciphersuites("TLS_AES_128_GCM_SHA256").unwrap();
154392f3ab15Sopenharmony_ci    let x509 = X509::from_pem(ROOT_CERT).unwrap();
154492f3ab15Sopenharmony_ci    let mut builder = X509StoreBuilder::new().unwrap();
154592f3ab15Sopenharmony_ci    builder.add_cert(x509).unwrap();
154692f3ab15Sopenharmony_ci    let store = builder.build();
154792f3ab15Sopenharmony_ci    ssl.set_verify_cert_store(store).unwrap();
154892f3ab15Sopenharmony_ci}
154992f3ab15Sopenharmony_ci
155092f3ab15Sopenharmony_ci#[test]
155192f3ab15Sopenharmony_ci#[cfg(ossl110)]
155292f3ab15Sopenharmony_cifn test_ssl_set_cert_chain_file() {
155392f3ab15Sopenharmony_ci    let ctx = SslContext::builder(SslMethod::tls()).unwrap().build();
155492f3ab15Sopenharmony_ci    let mut ssl = Ssl::new(&ctx).unwrap();
155592f3ab15Sopenharmony_ci    ssl.set_certificate_chain_file("test/cert.pem").unwrap();
155692f3ab15Sopenharmony_ci}
155792f3ab15Sopenharmony_ci
155892f3ab15Sopenharmony_ci#[test]
155992f3ab15Sopenharmony_ci#[cfg(ossl111)]
156092f3ab15Sopenharmony_cifn set_num_tickets() {
156192f3ab15Sopenharmony_ci    let mut ctx = SslContext::builder(SslMethod::tls_server()).unwrap();
156292f3ab15Sopenharmony_ci    ctx.set_num_tickets(3).unwrap();
156392f3ab15Sopenharmony_ci    let ctx = ctx.build();
156492f3ab15Sopenharmony_ci    assert_eq!(3, ctx.num_tickets());
156592f3ab15Sopenharmony_ci
156692f3ab15Sopenharmony_ci    let mut ssl = Ssl::new(&ctx).unwrap();
156792f3ab15Sopenharmony_ci    ssl.set_num_tickets(5).unwrap();
156892f3ab15Sopenharmony_ci    let ssl = ssl;
156992f3ab15Sopenharmony_ci    assert_eq!(5, ssl.num_tickets());
157092f3ab15Sopenharmony_ci}
1571