Unverified Commit 2c89ef52 authored by Steven Fackler's avatar Steven Fackler Committed by GitHub
Browse files

Merge pull request #944 from sfackler/1.1.1-pre7

Update to 1.1.1-pre7
parents 24f4bdb5 0745d669
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -91,7 +91,7 @@ macos_job: &MACOS_JOB

openssl_111: &OPENSSL_111
  LIBRARY: openssl
  VERSION: 1.1.1-pre3
  VERSION: 1.1.1-pre7
openssl_110: &OPENSSL_110
  LIBRARY: openssl
  VERSION: 1.1.0h
+72 −43
Original line number Diff line number Diff line
use libc::{c_char, c_uchar, c_int, c_uint, c_ulong, size_t, c_void};
use libc::{c_char, c_int, c_uchar, c_uint, c_ulong, c_void, size_t};

pub type SSL_CTX_keylog_cb_func =
    Option<unsafe extern "C" fn(ssl: *const ::SSL, line: *const c_char)>;

pub type SSL_custom_ext_add_cb_ex =
    Option<unsafe extern "C" fn(ssl: *mut ::SSL, ext_type: c_uint,
pub type SSL_custom_ext_add_cb_ex = Option<
    unsafe extern "C" fn(
        ssl: *mut ::SSL,
        ext_type: c_uint,
        context: c_uint,
        out: *mut *const c_uchar,
                                outlen: *mut size_t, x: *mut ::X509,
                                chainidx: size_t, al: *mut c_int,
                                add_arg: *mut c_void) -> c_int>;
        outlen: *mut size_t,
        x: *mut ::X509,
        chainidx: size_t,
        al: *mut c_int,
        add_arg: *mut c_void,
    ) -> c_int,
>;

pub type SSL_custom_ext_free_cb_ex =
    Option<unsafe extern "C" fn(ssl: *mut ::SSL, ext_type: c_uint,
pub type SSL_custom_ext_free_cb_ex = Option<
    unsafe extern "C" fn(
        ssl: *mut ::SSL,
        ext_type: c_uint,
        context: c_uint,
        out: *mut *const c_uchar,
                                add_arg: *mut c_void)>;
        add_arg: *mut c_void,
    ),
>;

pub type SSL_custom_ext_parse_cb_ex =
    Option<unsafe extern "C" fn(ssl: *mut ::SSL, ext_type: c_uint,
pub type SSL_custom_ext_parse_cb_ex = Option<
    unsafe extern "C" fn(
        ssl: *mut ::SSL,
        ext_type: c_uint,
        context: c_uint,
        input: *const c_uchar,
                                inlen: size_t, x: *mut ::X509,
                                chainidx: size_t, al: *mut c_int,
                                parse_arg: *mut c_void) -> c_int>;
        inlen: size_t,
        x: *mut ::X509,
        chainidx: size_t,
        al: *mut c_int,
        parse_arg: *mut c_void,
    ) -> c_int,
>;

pub const SSL_COOKIE_LENGTH: c_int = 4096;

@@ -61,38 +77,38 @@ pub const SSL_READ_EARLY_DATA_FINISH: c_int = 2;

extern "C" {
    pub fn SSL_CTX_set_keylog_callback(ctx: *mut ::SSL_CTX, cb: SSL_CTX_keylog_cb_func);
    pub fn SSL_CTX_add_custom_ext(ctx: *mut ::SSL_CTX, ext_type: c_uint, context: c_uint,
    pub fn SSL_CTX_add_custom_ext(
        ctx: *mut ::SSL_CTX,
        ext_type: c_uint,
        context: c_uint,
        add_cb: SSL_custom_ext_add_cb_ex,
        free_cb: SSL_custom_ext_free_cb_ex,
        add_arg: *mut c_void,
        parse_cb: SSL_custom_ext_parse_cb_ex,
                                  parse_arg: *mut c_void) -> c_int;
    pub fn SSL_stateless(s: *mut ::SSL) -> c_int;
        parse_arg: *mut c_void,
    ) -> c_int;
    pub fn SSL_CIPHER_get_handshake_digest(cipher: *const ::SSL_CIPHER) -> *const ::EVP_MD;
    pub fn SSL_CTX_set_stateless_cookie_generate_cb(
        s: *mut ::SSL_CTX,
        cb: Option<unsafe extern "C" fn(
            ssl: *mut ::SSL,
            cookie: *mut c_uchar,
            cookie_len: *mut size_t
        ) -> c_int>
        cb: Option<
            unsafe extern "C" fn(ssl: *mut ::SSL, cookie: *mut c_uchar, cookie_len: *mut size_t)
                -> c_int,
        >,
    );
    pub fn SSL_CTX_set_stateless_cookie_verify_cb(
        s: *mut ::SSL_CTX,
        cb: Option<unsafe extern "C" fn(
            ssl: *mut ::SSL,
            cookie: *const c_uchar,
            cookie_len: size_t
        ) -> c_int>
        cb: Option<
            unsafe extern "C" fn(ssl: *mut ::SSL, cookie: *const c_uchar, cookie_len: size_t)
                -> c_int,
        >,
    );

    pub fn SSL_CTX_set_max_early_data(ctx: *mut ::SSL_CTX, max_early_data: u32) -> c_int;
    pub fn SSL_CTX_get_max_early_data(ctx: *const ::SSL_CTX) -> u32;
    pub fn SSL_CTX_set_ciphersuites(ctx: *mut ::SSL_CTX, str: *const c_char) -> c_int;

    pub fn SSL_set_max_early_data(ctx: *mut ::SSL, max_early_data: u32) -> c_int;
    pub fn SSL_get_max_early_data(ctx: *const ::SSL) -> u32;
    pub fn SSL_SESSION_set_max_early_data(ctx: *mut ::SSL_SESSION, max_early_data: u32) -> c_int;
    pub fn SSL_SESSION_get_max_early_data(ctx: *const ::SSL_SESSION) -> u32;

    pub fn SSL_stateless(s: *mut ::SSL) -> c_int;
    pub fn SSL_export_keying_material_early(
        s: *mut ::SSL,
        out: *mut c_uchar,
@@ -102,7 +118,20 @@ extern "C" {
        context: *const c_uchar,
        contextlen: size_t,
    ) -> c_int;
    pub fn SSL_write_early_data(
        s: *mut ::SSL,
        buf: *const c_void,
        num: size_t,
        written: *mut size_t,
    ) -> c_int;
    pub fn SSL_read_early_data(
        s: *mut ::SSL,
        buf: *mut c_void,
        num: size_t,
        readbytes: *mut size_t,
    ) -> c_int;
    pub fn SSL_set_ciphersuites(ssl: *mut ::SSL, str: *const c_char) -> c_int;

    pub fn SSL_write_early_data(s: *mut ::SSL, buf: *const c_void, num: size_t, written: *mut size_t) -> c_int;
    pub fn SSL_read_early_data(s: *mut ::SSL, buf: *mut c_void, num: size_t, readbytes: *mut size_t) -> c_int;
    pub fn SSL_SESSION_set_max_early_data(ctx: *mut ::SSL_SESSION, max_early_data: u32) -> c_int;
    pub fn SSL_SESSION_get_max_early_data(ctx: *const ::SSL_SESSION) -> u32;
}
+26 −1
Original line number Diff line number Diff line
@@ -952,7 +952,9 @@ impl SslContextBuilder {
        unsafe { cvt(ffi::SSL_CTX_use_PrivateKey(self.as_ptr(), key.as_ptr())).map(|_| ()) }
    }

    /// Sets the list of supported ciphers.
    /// Sets the list of supported ciphers for protocols before TLSv1.3.
    ///
    /// The `set_ciphersuites` method controls the cipher suites for TLSv1.3.
    ///
    /// See [`ciphers`] for details on the format.
    ///
@@ -970,6 +972,29 @@ impl SslContextBuilder {
        }
    }

    /// Sets the list of supported ciphers for the TLSv1.3 protocol.
    ///
    /// The `set_cipher_list` method controls lthe cipher suites for protocols before TLSv1.3.
    ///
    /// The format consists of TLSv1.3 ciphersuite names separated by `:` characters in order of
    /// preference.
    ///
    /// Requires OpenSSL 1.1.1 or newer.
    ///
    /// This corresponds to [`SSL_CTX_set_ciphersuites`].
    ///
    /// [`SSL_CTX_set_ciphersuites`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_ciphersuites.html
    #[cfg(ossl111)]
    pub fn set_ciphersuites(&mut self, cipher_list: &str) -> Result<(), ErrorStack> {
        let cipher_list = CString::new(cipher_list).unwrap();
        unsafe {
            cvt(ffi::SSL_CTX_set_ciphersuites(
                self.as_ptr(),
                cipher_list.as_ptr() as *const _,
            )).map(|_| ())
        }
    }

    /// Enables ECDHE key exchange with an automatically chosen curve list.
    ///
    /// Requires OpenSSL 1.0.2.
+74 −42
Original line number Diff line number Diff line
@@ -567,9 +567,10 @@ fn test_alpn_server_advertise_multiple() {
        ctx.build()
    };
    // Have the listener wait on the connection in a different thread.
    thread::spawn(move || {
    let guard = thread::spawn(move || {
        let (stream, _) = listener.accept().unwrap();
        Ssl::new(&listener_ctx).unwrap().accept(stream).unwrap();
        let mut stream = Ssl::new(&listener_ctx).unwrap().accept(stream).unwrap();
        stream.write_all(&[0]).unwrap();
    });

    let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
@@ -581,12 +582,16 @@ fn test_alpn_server_advertise_multiple() {
    }
    // Now connect to the socket and make sure the protocol negotiation works...
    let stream = TcpStream::connect(localhost).unwrap();
    let stream = match Ssl::new(&ctx.build()).unwrap().connect(stream) {
    let mut stream = match Ssl::new(&ctx.build()).unwrap().connect(stream) {
        Ok(stream) => stream,
        Err(err) => panic!("Expected success, got {:?}", err),
    };
    // SPDY is selected since that's the only thing the client supports.
    assert_eq!(b"spdy/3.1", stream.ssl().selected_alpn_protocol().unwrap());
    let mut buf = [0];
    stream.read_exact(&mut buf).unwrap();

    guard.join().unwrap();
}

#[test]
@@ -643,9 +648,10 @@ fn test_alpn_server_select_none() {
        ctx.build()
    };
    // Have the listener wait on the connection in a different thread.
    thread::spawn(move || {
    let guard = thread::spawn(move || {
        let (stream, _) = listener.accept().unwrap();
        Ssl::new(&listener_ctx).unwrap().accept(stream).unwrap();
        let mut stream = Ssl::new(&listener_ctx).unwrap().accept(stream).unwrap();
        stream.write_all(&[0]).unwrap();
    });

    let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
@@ -654,10 +660,15 @@ fn test_alpn_server_select_none() {
    ctx.set_ca_file(&Path::new("test/root-ca.pem")).unwrap();
    // Now connect to the socket and make sure the protocol negotiation works...
    let stream = TcpStream::connect(localhost).unwrap();
    let stream = Ssl::new(&ctx.build()).unwrap().connect(stream).unwrap();
    let mut stream = Ssl::new(&ctx.build()).unwrap().connect(stream).unwrap();

    // Since the protocols from the server and client don't overlap at all, no protocol is selected
    assert_eq!(None, stream.ssl().selected_alpn_protocol());

    let mut buf = [0];
    stream.read_exact(&mut buf).unwrap();

    guard.join().unwrap();
}

#[test]
@@ -972,7 +983,7 @@ fn shutdown() {
    let listener = TcpListener::bind("127.0.0.1:0").unwrap();
    let port = listener.local_addr().unwrap().port();

    thread::spawn(move || {
    let guard = thread::spawn(move || {
        let stream = listener.accept().unwrap().0;
        let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
        ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM)
@@ -999,6 +1010,8 @@ fn shutdown() {

    assert_eq!(stream.shutdown().unwrap(), ShutdownResult::Sent);
    assert_eq!(stream.shutdown().unwrap(), ShutdownResult::Received);

    guard.join().unwrap();
}

#[test]
@@ -1030,7 +1043,7 @@ fn tmp_dh_callback() {
    let listener = TcpListener::bind("127.0.0.1:0").unwrap();
    let port = listener.local_addr().unwrap().port();

    thread::spawn(move || {
    let guard = thread::spawn(move || {
        let stream = listener.accept().unwrap().0;
        let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
        ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM)
@@ -1043,23 +1056,24 @@ fn tmp_dh_callback() {
            Dh::params_from_pem(dh)
        });
        let ssl = Ssl::new(&ctx.build()).unwrap();
        ssl.accept(stream).unwrap();
        let mut stream = ssl.accept(stream).unwrap();
        stream.write_all(&[0]).unwrap();
    });

    let stream = TcpStream::connect(("127.0.0.1", port)).unwrap();
    let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
    // TLS 1.3 has no DH suites, and openssl isn't happy if the max version has no suites :(
    // TLS 1.3 has no DH suites, so make sure we don't pick that version
    #[cfg(ossl111)]
    {
        ctx.set_options(super::SslOptions {
            bits: ::ffi::SSL_OP_NO_TLSv1_3,
        });
    }
    ctx.set_options(super::SslOptions::NO_TLSV1_3);
    ctx.set_cipher_list("EDH").unwrap();
    let ssl = Ssl::new(&ctx.build()).unwrap();
    ssl.connect(stream).unwrap();
    let mut stream = ssl.connect(stream).unwrap();

    stream.read_exact(&mut [0]).unwrap();

    assert!(CALLED_BACK.load(Ordering::SeqCst));

    guard.join().unwrap();
}

#[test]
@@ -1073,7 +1087,7 @@ fn tmp_ecdh_callback() {
    let listener = TcpListener::bind("127.0.0.1:0").unwrap();
    let port = listener.local_addr().unwrap().port();

    thread::spawn(move || {
    let guard = thread::spawn(move || {
        let stream = listener.accept().unwrap().0;
        let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
        ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM)
@@ -1085,16 +1099,20 @@ fn tmp_ecdh_callback() {
            EcKey::from_curve_name(Nid::X9_62_PRIME256V1)
        });
        let ssl = Ssl::new(&ctx.build()).unwrap();
        ssl.accept(stream).unwrap();
        let mut stream = ssl.accept(stream).unwrap();
        stream.write_all(&[0]).unwrap();
    });

    let stream = TcpStream::connect(("127.0.0.1", port)).unwrap();
    let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
    ctx.set_cipher_list("ECDH").unwrap();
    let ssl = Ssl::new(&ctx.build()).unwrap();
    ssl.connect(stream).unwrap();
    let mut stream = ssl.connect(stream).unwrap();
    stream.read_exact(&mut [0]).unwrap();

    assert!(CALLED_BACK.load(Ordering::SeqCst));

    guard.join().unwrap();
}

#[test]
@@ -1104,7 +1122,7 @@ fn tmp_dh_callback_ssl() {
    let listener = TcpListener::bind("127.0.0.1:0").unwrap();
    let port = listener.local_addr().unwrap().port();

    thread::spawn(move || {
    let guard = thread::spawn(move || {
        let stream = listener.accept().unwrap().0;
        let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
        ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM)
@@ -1117,23 +1135,23 @@ fn tmp_dh_callback_ssl() {
            let dh = include_bytes!("../../test/dhparams.pem");
            Dh::params_from_pem(dh)
        });
        ssl.accept(stream).unwrap();
        let mut stream = ssl.accept(stream).unwrap();
        stream.write_all(&[0]).unwrap();
    });

    let stream = TcpStream::connect(("127.0.0.1", port)).unwrap();
    let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
    // TLS 1.3 has no DH suites, and openssl isn't happy if the max version has no suites :(
    // TLS 1.3 has no DH suites, so make sure we don't pick that version
    #[cfg(ossl111)]
    {
        ctx.set_options(super::SslOptions {
            bits: ::ffi::SSL_OP_NO_TLSv1_3,
        });
    }
    ctx.set_options(super::SslOptions::NO_TLSV1_3);
    ctx.set_cipher_list("EDH").unwrap();
    let ssl = Ssl::new(&ctx.build()).unwrap();
    ssl.connect(stream).unwrap();
    let mut stream = ssl.connect(stream).unwrap();
    stream.read_exact(&mut [0]).unwrap();

    assert!(CALLED_BACK.load(Ordering::SeqCst));

    guard.join().unwrap();
}

#[test]
@@ -1147,7 +1165,7 @@ fn tmp_ecdh_callback_ssl() {
    let listener = TcpListener::bind("127.0.0.1:0").unwrap();
    let port = listener.local_addr().unwrap().port();

    thread::spawn(move || {
    let guard = thread::spawn(move || {
        let stream = listener.accept().unwrap().0;
        let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
        ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM)
@@ -1159,16 +1177,20 @@ fn tmp_ecdh_callback_ssl() {
            CALLED_BACK.store(true, Ordering::SeqCst);
            EcKey::from_curve_name(Nid::X9_62_PRIME256V1)
        });
        ssl.accept(stream).unwrap();
        let mut stream = ssl.accept(stream).unwrap();
        stream.write_all(&[0]).unwrap();
    });

    let stream = TcpStream::connect(("127.0.0.1", port)).unwrap();
    let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
    ctx.set_cipher_list("ECDH").unwrap();
    let ssl = Ssl::new(&ctx.build()).unwrap();
    ssl.connect(stream).unwrap();
    let mut stream = ssl.connect(stream).unwrap();
    stream.read_exact(&mut [0]).unwrap();

    assert!(CALLED_BACK.load(Ordering::SeqCst));

    guard.join().unwrap();
}

#[test]
@@ -1200,7 +1222,7 @@ fn status_callbacks() {
    static CALLED_BACK_SERVER: AtomicBool = ATOMIC_BOOL_INIT;
    static CALLED_BACK_CLIENT: AtomicBool = ATOMIC_BOOL_INIT;

    let listener = TcpListener::bind("127.0.0.1:0").unwrap();
    let listener = TcpListener::bind("127.0.0.1:12345").unwrap();
    let port = listener.local_addr().unwrap().port();

    let guard = thread::spawn(move || {
@@ -1218,7 +1240,8 @@ fn status_callbacks() {
            Ok(true)
        }).unwrap();
        let ssl = Ssl::new(&ctx.build()).unwrap();
        ssl.accept(stream).unwrap();
        let mut stream = ssl.accept(stream).unwrap();
        stream.write_all(&[0]).unwrap();
    });

    let stream = TcpStream::connect(("127.0.0.1", port)).unwrap();
@@ -1231,7 +1254,9 @@ fn status_callbacks() {
    }).unwrap();
    let mut ssl = Ssl::new(&ctx.build()).unwrap();
    ssl.set_status_type(StatusType::OCSP).unwrap();
    ssl.connect(stream).unwrap();
    let mut stream = ssl.connect(stream).unwrap();
    let mut buf = [0];
    stream.read_exact(&mut buf).unwrap();

    assert!(CALLED_BACK_SERVER.load(Ordering::SeqCst));
    assert!(CALLED_BACK_CLIENT.load(Ordering::SeqCst));
@@ -1246,7 +1271,7 @@ fn new_session_callback() {
    let listener = TcpListener::bind("127.0.0.1:0").unwrap();
    let port = listener.local_addr().unwrap().port();

    thread::spawn(move || {
    let guard = thread::spawn(move || {
        let stream = listener.accept().unwrap().0;
        let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
        ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM)
@@ -1265,11 +1290,11 @@ fn new_session_callback() {
    ctx.set_new_session_callback(|_, _| CALLED_BACK.store(true, Ordering::SeqCst));
    let ssl = Ssl::new(&ctx.build()).unwrap();
    let mut stream = ssl.connect(stream).unwrap();
    // read 1 byte to make sure the session is received for TLSv1.3
    let mut buf = [0];
    stream.read_exact(&mut buf).unwrap();
    stream.read_exact(&mut [0]).unwrap();

    assert!(CALLED_BACK.load(Ordering::SeqCst));

    guard.join().unwrap();
}

#[test]
@@ -1288,20 +1313,23 @@ fn keying_export() {
        ctx.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM)
            .unwrap();
        let ssl = Ssl::new(&ctx.build()).unwrap();
        let stream = ssl.accept(stream).unwrap();
        let mut stream = ssl.accept(stream).unwrap();

        let mut buf = [0; 32];
        stream
            .ssl()
            .export_keying_material(&mut buf, label, Some(context))
            .unwrap();

        stream.write_all(&[0]).unwrap();

        buf
    });

    let stream = TcpStream::connect(addr).unwrap();
    let ctx = SslContext::builder(SslMethod::tls()).unwrap();
    let ssl = Ssl::new(&ctx.build()).unwrap();
    let stream = ssl.connect(stream).unwrap();
    let mut stream = ssl.connect(stream).unwrap();

    let mut buf = [1; 32];
    stream
@@ -1309,6 +1337,8 @@ fn keying_export() {
        .export_keying_material(&mut buf, label, Some(context))
        .unwrap();

    stream.read_exact(&mut [0]).unwrap();

    let buf2 = guard.join().unwrap();

    assert_eq!(buf, buf2);
@@ -1374,7 +1404,8 @@ fn custom_extensions() {
            },
        ).unwrap();
        let ssl = Ssl::new(&ctx.build()).unwrap();
        ssl.accept(stream).unwrap();
        let mut stream = ssl.accept(stream).unwrap();
        stream.write_all(&[0]).unwrap();
    });

    let stream = TcpStream::connect(addr).unwrap();
@@ -1386,7 +1417,8 @@ fn custom_extensions() {
        |_, _, _, _| unreachable!(),
    ).unwrap();
    let ssl = Ssl::new(&ctx.build()).unwrap();
    ssl.connect(stream).unwrap();
    let mut stream = ssl.connect(stream).unwrap();
    stream.read_exact(&mut [0]).unwrap();

    guard.join().unwrap();
    assert!(FOUND_EXTENSION.load(Ordering::SeqCst));