diff options
| -rw-r--r-- | .travis.yml | 6 | ||||
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | appveyor.yml | 8 | ||||
| -rw-r--r-- | openssl-sys/Cargo.toml | 8 | ||||
| -rw-r--r-- | openssl-sys/build.rs | 18 | ||||
| -rw-r--r-- | openssl-sys/src/lib.rs | 17 | ||||
| -rw-r--r-- | openssl/Cargo.toml | 8 | ||||
| -rw-r--r-- | openssl/src/lib.rs | 2 | ||||
| -rw-r--r-- | openssl/src/ocsp.rs | 24 | ||||
| -rw-r--r-- | openssl/src/pkey.rs | 7 | ||||
| -rw-r--r-- | openssl/src/rsa.rs | 2 | ||||
| -rw-r--r-- | openssl/src/ssl/mod.rs | 221 | ||||
| -rw-r--r-- | openssl/src/ssl/tests/mod.rs | 36 | ||||
| -rw-r--r-- | openssl/src/verify.rs | 14 | ||||
| -rw-r--r-- | openssl/test/key.der | bin | 0 -> 1193 bytes | |||
| -rw-r--r-- | systest/build.rs | 3 |
16 files changed, 192 insertions, 184 deletions
diff --git a/.travis.yml b/.travis.yml index e19b2d0a..d9caed69 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,7 +29,7 @@ matrix: - binfmt-support - env: > TARGET=arm-unknown-linux-gnueabihf - BUILD_OPENSSL_VERSION=1.1.0e + BUILD_OPENSSL_VERSION=1.1.0f CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf RUST_TEST_THREADS=1 @@ -50,7 +50,7 @@ matrix: # 64-bit version compat - env: BUILD_OPENSSL_VERSION=1.0.2k - - env: BUILD_OPENSSL_VERSION=1.1.0e + - env: BUILD_OPENSSL_VERSION=1.1.0f # 32-bit version compat - env: TARGET=i686-unknown-linux-gnu BUILD_OPENSSL_VERSION=1.0.1u @@ -63,7 +63,7 @@ matrix: apt: packages: - gcc-multilib - - env: TARGET=i686-unknown-linux-gnu BUILD_OPENSSL_VERSION=1.1.0e + - env: TARGET=i686-unknown-linux-gnu BUILD_OPENSSL_VERSION=1.1.0f addons: apt: packages: @@ -27,7 +27,7 @@ on them. ```bash # On Ubuntu -sudo apt-get install libssl-dev +sudo apt-get install pkg-config libssl-dev # On Arch Linux sudo pacman -S openssl # On Fedora diff --git a/appveyor.yml b/appveyor.yml index 711435b4..dd351e5c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -5,20 +5,20 @@ environment: - TARGET: i686-pc-windows-gnu BITS: 32 MSYS2: 1 - OPENSSL_VERSION: 1_1_0e + OPENSSL_VERSION: 1_1_0f - TARGET: x86_64-pc-windows-msvc BITS: 64 - OPENSSL_VERSION: 1_1_0e + OPENSSL_VERSION: 1_1_0f OPENSSL_DIR: C:\OpenSSL # 1.0.2, 64/32 bit - TARGET: x86_64-pc-windows-gnu BITS: 64 MSYS2: 1 - OPENSSL_VERSION: 1_0_2k + OPENSSL_VERSION: 1_0_2L - TARGET: i686-pc-windows-msvc BITS: 32 - OPENSSL_VERSION: 1_0_2k + OPENSSL_VERSION: 1_0_2L OPENSSL_DIR: C:\OpenSSL install: # install OpenSSL diff --git a/openssl-sys/Cargo.toml b/openssl-sys/Cargo.toml index 3c9d98f3..41d5f255 100644 --- a/openssl-sys/Cargo.toml +++ b/openssl-sys/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "openssl-sys" -version = "0.9.12" +version = "0.9.14" authors = ["Alex Crichton <[email protected]>", "Steven Fackler <[email protected]>"] license = "MIT" description = "FFI bindings to OpenSSL" repository = "https://github.com/sfackler/rust-openssl" -documentation = "https://docs.rs/openssl-sys/0.9.12/openssl_sys" +documentation = "https://docs.rs/openssl-sys/0.9.13/openssl_sys" categories = ["cryptography", "external-ffi-bindings"] links = "openssl" build = "build.rs" @@ -18,10 +18,6 @@ libc = "0.2" pkg-config = "0.3.9" gcc = "0.3.42" -[target.'cfg(windows)'.dependencies] -user32-sys = "0.2" -gdi32-sys = "0.2" - # We don't actually use metadeps for annoying reasons but this is still here for tooling [package.metadata.pkg-config] openssl = "1.0.1" diff --git a/openssl-sys/build.rs b/openssl-sys/build.rs index 983c5899..348c2f82 100644 --- a/openssl-sys/build.rs +++ b/openssl-sys/build.rs @@ -237,8 +237,10 @@ fn validate_headers(include_dirs: &[PathBuf]) -> Version { #include <openssl/opensslv.h> #include <openssl/opensslconf.h> -#if LIBRESSL_VERSION_NUMBER >= 0x20505000 +#if LIBRESSL_VERSION_NUMBER >= 0x20601000 RUST_LIBRESSL_NEW +#elif LIBRESSL_VERSION_NUMBER >= 0x20600000 +RUST_LIBRESSL_260 #elif LIBRESSL_VERSION_NUMBER >= 0x20504000 RUST_LIBRESSL_254 #elif LIBRESSL_VERSION_NUMBER >= 0x20503000 @@ -253,6 +255,8 @@ RUST_LIBRESSL_250 RUST_LIBRESSL_OLD #elif OPENSSL_VERSION_NUMBER >= 0x10101000 RUST_OPENSSL_NEW +#elif OPENSSL_VERSION_NUMBER >= 0x10100060 +RUST_OPENSSL_110F #elif OPENSSL_VERSION_NUMBER >= 0x10100000 RUST_OPENSSL_110 #elif OPENSSL_VERSION_NUMBER >= 0x10002000 @@ -348,6 +352,18 @@ See rust-openssl README for more information: println!("cargo:libressl=true"); println!("cargo:version=101"); Version::Libressl + } else if expanded.contains("RUST_LIBRESSL_260") { + println!("cargo:rustc-cfg=libressl"); + println!("cargo:rustc-cfg=libressl260"); + println!("cargo:libressl=true"); + println!("cargo:version=101"); + Version::Libressl + } else if expanded.contains("RUST_OPENSSL_110F") { + println!("cargo:rustc-cfg=ossl110"); + println!("cargo:rustc-cfg=ossl110f"); + println!("cargo:version=110"); + println!("cargo:patch=f"); + Version::Openssl110 } else if expanded.contains("RUST_OPENSSL_110") { println!("cargo:rustc-cfg=ossl110"); println!("cargo:version=110"); diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs index 06d37dab..00e1208b 100644 --- a/openssl-sys/src/lib.rs +++ b/openssl-sys/src/lib.rs @@ -1,6 +1,6 @@ #![allow(non_camel_case_types, non_upper_case_globals, non_snake_case)] #![allow(dead_code, overflowing_literals)] -#![doc(html_root_url="https://docs.rs/openssl-sys/0.9.12")] +#![doc(html_root_url="https://docs.rs/openssl-sys/0.9.14")] extern crate libc; @@ -1205,8 +1205,18 @@ pub const SSL_VERIFY_FAIL_IF_NO_PEER_CERT: c_int = 2; #[cfg(not(ossl101))] pub const SSL_OP_TLSEXT_PADDING: c_ulong = 0x00000010; pub const SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: c_ulong = 0x00000800; +pub const SSL_OP_CRYPTOPRO_TLSEXT_BUG: c_ulong = 0x80000000; +pub const SSL_OP_LEGACY_SERVER_CONNECT: c_ulong = 0x00000004; #[cfg(not(libressl))] +pub const SSL_OP_SAFARI_ECDHE_ECDSA_BUG: c_ulong = 0x00000040; +#[cfg(not(any(libressl, ossl110f)))] pub const SSL_OP_ALL: c_ulong = 0x80000BFF; +#[cfg(ossl110f)] +pub const SSL_OP_ALL: c_ulong = SSL_OP_CRYPTOPRO_TLSEXT_BUG | + SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS | + SSL_OP_LEGACY_SERVER_CONNECT | + SSL_OP_TLSEXT_PADDING | + SSL_OP_SAFARI_ECDHE_ECDSA_BUG; pub const SSL_OP_NO_QUERY_MTU: c_ulong = 0x00001000; pub const SSL_OP_COOKIE_EXCHANGE: c_ulong = 0x00002000; pub const SSL_OP_NO_TICKET: c_ulong = 0x00004000; @@ -2273,8 +2283,10 @@ extern "C" { len: *mut c_uint); pub fn SSL_get_session(s: *const SSL) -> *mut SSL_SESSION; pub fn SSL_set_session(ssl: *mut SSL, session: *mut SSL_SESSION) -> c_int; - #[cfg(not(any(ossl101, libressl)))] + #[cfg(not(any(ossl101, libressl, ossl110f)))] pub fn SSL_is_server(s: *mut SSL) -> c_int; + #[cfg(ossl110f)] + pub fn SSL_is_server(s: *const SSL) -> c_int; pub fn SSL_SESSION_free(s: *mut SSL_SESSION); pub fn SSL_SESSION_get_id(s: *const SSL_SESSION, len: *mut c_uint) -> *const c_uchar; @@ -2409,6 +2421,7 @@ extern "C" { pub fn i2d_X509_REQ_bio(b: *mut BIO, x: *mut X509_REQ) -> c_int; pub fn i2d_X509_REQ(x: *mut X509_REQ, buf: *mut *mut u8) -> c_int; + pub fn d2i_AutoPrivateKey(a: *mut *mut EVP_PKEY, pp: *mut *const c_uchar, length: c_long) -> *mut EVP_PKEY; pub fn d2i_PUBKEY(k: *mut *mut EVP_PKEY, buf: *mut *const u8, len: c_long) -> *mut EVP_PKEY; pub fn i2d_PUBKEY_bio(b: *mut BIO, x: *mut EVP_PKEY) -> c_int; pub fn i2d_PrivateKey_bio(b: *mut BIO, x: *mut EVP_PKEY) -> c_int; diff --git a/openssl/Cargo.toml b/openssl/Cargo.toml index 83637095..026c3c06 100644 --- a/openssl/Cargo.toml +++ b/openssl/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "openssl" -version = "0.9.12" +version = "0.9.14" authors = ["Steven Fackler <[email protected]>"] license = "Apache-2.0" description = "OpenSSL bindings" repository = "https://github.com/sfackler/rust-openssl" -documentation = "https://docs.rs/openssl/0.9.12/openssl" +documentation = "https://docs.rs/openssl/0.9.13/openssl" readme = "../README.md" keywords = ["crypto", "tls", "ssl", "dtls"] categories = ["cryptography", "api-bindings"] @@ -17,11 +17,11 @@ v102 = [] v110 = [] [dependencies] -bitflags = "0.8" +bitflags = "0.9" foreign-types = "0.2" lazy_static = "0.2" libc = "0.2" -openssl-sys = { version = "0.9.12", path = "../openssl-sys" } +openssl-sys = { version = "0.9.14", path = "../openssl-sys" } [dev-dependencies] tempdir = "0.3" diff --git a/openssl/src/lib.rs b/openssl/src/lib.rs index 7ace3b36..0c7a9bdb 100644 --- a/openssl/src/lib.rs +++ b/openssl/src/lib.rs @@ -1,4 +1,4 @@ -#![doc(html_root_url="https://docs.rs/openssl/0.9.12")] +#![doc(html_root_url="https://docs.rs/openssl/0.9.14")] #[macro_use] extern crate bitflags; diff --git a/openssl/src/ocsp.rs b/openssl/src/ocsp.rs index 67d51838..03744619 100644 --- a/openssl/src/ocsp.rs +++ b/openssl/src/ocsp.rs @@ -13,18 +13,18 @@ use x509::store::X509StoreRef; use x509::{X509, X509Ref}; bitflags! { - pub flags Flag: c_ulong { - const FLAG_NO_CERTS = ffi::OCSP_NOCERTS, - const FLAG_NO_INTERN = ffi::OCSP_NOINTERN, - const FLAG_NO_CHAIN = ffi::OCSP_NOCHAIN, - const FLAG_NO_VERIFY = ffi::OCSP_NOVERIFY, - const FLAG_NO_EXPLICIT = ffi::OCSP_NOEXPLICIT, - const FLAG_NO_CA_SIGN = ffi::OCSP_NOCASIGN, - const FLAG_NO_DELEGATED = ffi::OCSP_NODELEGATED, - const FLAG_NO_CHECKS = ffi::OCSP_NOCHECKS, - const FLAG_TRUST_OTHER = ffi::OCSP_TRUSTOTHER, - const FLAG_RESPID_KEY = ffi::OCSP_RESPID_KEY, - const FLAG_NO_TIME = ffi::OCSP_NOTIME, + pub struct Flag: c_ulong { + const FLAG_NO_CERTS = ffi::OCSP_NOCERTS; + const FLAG_NO_INTERN = ffi::OCSP_NOINTERN; + const FLAG_NO_CHAIN = ffi::OCSP_NOCHAIN; + const FLAG_NO_VERIFY = ffi::OCSP_NOVERIFY; + const FLAG_NO_EXPLICIT = ffi::OCSP_NOEXPLICIT; + const FLAG_NO_CA_SIGN = ffi::OCSP_NOCASIGN; + const FLAG_NO_DELEGATED = ffi::OCSP_NODELEGATED; + const FLAG_NO_CHECKS = ffi::OCSP_NOCHECKS; + const FLAG_TRUST_OTHER = ffi::OCSP_TRUSTOTHER; + const FLAG_RESPID_KEY = ffi::OCSP_RESPID_KEY; + const FLAG_NO_TIME = ffi::OCSP_NOTIME; } } diff --git a/openssl/src/pkey.rs b/openssl/src/pkey.rs index f8211b25..7bda47b5 100644 --- a/openssl/src/pkey.rs +++ b/openssl/src/pkey.rs @@ -141,6 +141,7 @@ impl PKey { private_key_from_pem!(PKey, ffi::PEM_read_bio_PrivateKey); public_key_from_pem!(PKey, ffi::PEM_read_bio_PUBKEY); public_key_from_der!(PKey, ffi::d2i_PUBKEY); + private_key_from_der!(PKey, ffi::d2i_AutoPrivateKey); /// Deserializes a DER-formatted PKCS#8 private key, using a callback to retrieve the password /// if the key is encrpyted. @@ -318,6 +319,12 @@ mod tests { } #[test] + fn test_private_key_from_der() { + let key = include_bytes!("../test/key.der"); + PKey::private_key_from_der(key).unwrap(); + } + + #[test] fn test_pem() { let key = include_bytes!("../test/key.pem"); let key = PKey::private_key_from_pem(key).unwrap(); diff --git a/openssl/src/rsa.rs b/openssl/src/rsa.rs index 792f7070..31e1a349 100644 --- a/openssl/src/rsa.rs +++ b/openssl/src/rsa.rs @@ -126,7 +126,7 @@ impl RsaRef { } } - /// Encrypts data using the private key, returning the number of encrypted bytes. + /// Encrypts data using the public key, returning the number of encrypted bytes. /// /// # Panics /// diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 0a380b6f..8dd2b455 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -117,65 +117,67 @@ mod tests; use self::bio::BioMethod; -pub use ssl::connector::{SslConnectorBuilder, SslConnector, SslAcceptorBuilder, SslAcceptor}; +pub use ssl::connector::{SslConnectorBuilder, SslConnector, SslAcceptorBuilder, SslAcceptor, + ConnectConfiguration}; pub use ssl::error::{Error, HandshakeError}; // FIXME drop SSL_ prefix +// FIXME remvove flags not used in OpenSSL 1.1 bitflags! { - pub flags SslOption: c_ulong { - const SSL_OP_MICROSOFT_SESS_ID_BUG = ffi::SSL_OP_MICROSOFT_SESS_ID_BUG, - const SSL_OP_NETSCAPE_CHALLENGE_BUG = ffi::SSL_OP_NETSCAPE_CHALLENGE_BUG, + pub struct SslOption: c_ulong { + const SSL_OP_MICROSOFT_SESS_ID_BUG = ffi::SSL_OP_MICROSOFT_SESS_ID_BUG; + const SSL_OP_NETSCAPE_CHALLENGE_BUG = ffi::SSL_OP_NETSCAPE_CHALLENGE_BUG; const SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = - ffi::SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG, - const SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER = ffi::SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER, - const SSL_OP_SSLEAY_080_CLIENT_DH_BUG = ffi::SSL_OP_SSLEAY_080_CLIENT_DH_BUG, - const SSL_OP_TLS_D5_BUG = ffi::SSL_OP_TLS_D5_BUG, - const SSL_OP_TLS_BLOCK_PADDING_BUG = ffi::SSL_OP_TLS_BLOCK_PADDING_BUG, - const SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS = ffi::SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS, - const SSL_OP_ALL = ffi::SSL_OP_ALL, - const SSL_OP_NO_QUERY_MTU = ffi::SSL_OP_NO_QUERY_MTU, - const SSL_OP_COOKIE_EXCHANGE = ffi::SSL_OP_COOKIE_EXCHANGE, - const SSL_OP_NO_TICKET = ffi::SSL_OP_NO_TICKET, - const SSL_OP_CISCO_ANYCONNECT = ffi::SSL_OP_CISCO_ANYCONNECT, + ffi::SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG; + const SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER = ffi::SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER; + const SSL_OP_SSLEAY_080_CLIENT_DH_BUG = ffi::SSL_OP_SSLEAY_080_CLIENT_DH_BUG; + const SSL_OP_TLS_D5_BUG = ffi::SSL_OP_TLS_D5_BUG; + const SSL_OP_TLS_BLOCK_PADDING_BUG = ffi::SSL_OP_TLS_BLOCK_PADDING_BUG; + const SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS = ffi::SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; + const SSL_OP_ALL = ffi::SSL_OP_ALL; + const SSL_OP_NO_QUERY_MTU = ffi::SSL_OP_NO_QUERY_MTU; + const SSL_OP_COOKIE_EXCHANGE = ffi::SSL_OP_COOKIE_EXCHANGE; + const SSL_OP_NO_TICKET = ffi::SSL_OP_NO_TICKET; + const SSL_OP_CISCO_ANYCONNECT = ffi::SSL_OP_CISCO_ANYCONNECT; const SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION = - ffi::SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION, - const SSL_OP_NO_COMPRESSION = ffi::SSL_OP_NO_COMPRESSION, + ffi::SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION; + const SSL_OP_NO_COMPRESSION = ffi::SSL_OP_NO_COMPRESSION; const SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION = - ffi::SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION, - const SSL_OP_SINGLE_ECDH_USE = ffi::SSL_OP_SINGLE_ECDH_USE, - const SSL_OP_SINGLE_DH_USE = ffi::SSL_OP_SINGLE_DH_USE, - const SSL_OP_CIPHER_SERVER_PREFERENCE = ffi::SSL_OP_CIPHER_SERVER_PREFERENCE, - const SSL_OP_TLS_ROLLBACK_BUG = ffi::SSL_OP_TLS_ROLLBACK_BUG, - const SSL_OP_NO_SSLV2 = ffi::SSL_OP_NO_SSLv2, - const SSL_OP_NO_SSLV3 = ffi::SSL_OP_NO_SSLv3, - const SSL_OP_NO_TLSV1 = ffi::SSL_OP_NO_TLSv1, - const SSL_OP_NO_TLSV1_2 = ffi::SSL_OP_NO_TLSv1_2, - const SSL_OP_NO_TLSV1_1 = ffi::SSL_OP_NO_TLSv1_1, + ffi::SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION; + const SSL_OP_SINGLE_ECDH_USE = ffi::SSL_OP_SINGLE_ECDH_USE; + const SSL_OP_SINGLE_DH_USE = ffi::SSL_OP_SINGLE_DH_USE; + const SSL_OP_CIPHER_SERVER_PREFERENCE = ffi::SSL_OP_CIPHER_SERVER_PREFERENCE; + const SSL_OP_TLS_ROLLBACK_BUG = ffi::SSL_OP_TLS_ROLLBACK_BUG; + const SSL_OP_NO_SSLV2 = ffi::SSL_OP_NO_SSLv2; + const SSL_OP_NO_SSLV3 = ffi::SSL_OP_NO_SSLv3; + const SSL_OP_NO_TLSV1 = ffi::SSL_OP_NO_TLSv1; + const SSL_OP_NO_TLSV1_2 = ffi::SSL_OP_NO_TLSv1_2; + const SSL_OP_NO_TLSV1_1 = ffi::SSL_OP_NO_TLSv1_1; /// Requires the `v102` or `v110` features and OpenSSL 1.0.2 or OpenSSL 1.1.0. #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] - const SSL_OP_NO_DTLSV1 = ffi::SSL_OP_NO_DTLSv1, + const SSL_OP_NO_DTLSV1 = ffi::SSL_OP_NO_DTLSv1; /// Requires the `v102` or `v110` features and OpenSSL 1.0.2 or OpenSSL 1.1.0. #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] - const SSL_OP_NO_DTLSV1_2 = ffi::SSL_OP_NO_DTLSv1_2, + const SSL_OP_NO_DTLSV1_2 = ffi::SSL_OP_NO_DTLSv1_2; /// Requires the `v102` or `v110` features and OpenSSL 1.0.2 or OpenSSL 1.1.0. #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] - const SSL_OP_NO_SSL_MASK = ffi::SSL_OP_NO_SSL_MASK, + const SSL_OP_NO_SSL_MASK = ffi::SSL_OP_NO_SSL_MASK; } } bitflags! { - pub flags SslMode: c_long { - const SSL_MODE_ENABLE_PARTIAL_WRITE = ffi::SSL_MODE_ENABLE_PARTIAL_WRITE, - const SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER = ffi::SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER, - const SSL_MODE_AUTO_RETRY = ffi::SSL_MODE_AUTO_RETRY, - const SSL_MODE_NO_AUTO_CHAIN = ffi::SSL_MODE_NO_AUTO_CHAIN, - const SSL_MODE_RELEASE_BUFFERS = ffi::SSL_MODE_RELEASE_BUFFERS, + pub struct SslMode: c_long { + const SSL_MODE_ENABLE_PARTIAL_WRITE = ffi::SSL_MODE_ENABLE_PARTIAL_WRITE; + const SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER = ffi::SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER; + const SSL_MODE_AUTO_RETRY = ffi::SSL_MODE_AUTO_RETRY; + const SSL_MODE_NO_AUTO_CHAIN = ffi::SSL_MODE_NO_AUTO_CHAIN; + const SSL_MODE_RELEASE_BUFFERS = ffi::SSL_MODE_RELEASE_BUFFERS; #[cfg(not(libressl))] - const SSL_MODE_SEND_CLIENTHELLO_TIME = ffi::SSL_MODE_SEND_CLIENTHELLO_TIME, + const SSL_MODE_SEND_CLIENTHELLO_TIME = ffi::SSL_MODE_SEND_CLIENTHELLO_TIME; #[cfg(not(libressl))] - const SSL_MODE_SEND_SERVERHELLO_TIME = ffi::SSL_MODE_SEND_SERVERHELLO_TIME, + const SSL_MODE_SEND_SERVERHELLO_TIME = ffi::SSL_MODE_SEND_SERVERHELLO_TIME; #[cfg(not(libressl))] - const SSL_MODE_SEND_FALLBACK_SCSV = ffi::SSL_MODE_SEND_FALLBACK_SCSV, + const SSL_MODE_SEND_FALLBACK_SCSV = ffi::SSL_MODE_SEND_FALLBACK_SCSV; } } @@ -210,14 +212,14 @@ impl SslMethod { /// Determines the type of certificate verification used bitflags! { - pub flags SslVerifyMode: i32 { + pub struct SslVerifyMode: i32 { /// Verify that the server's certificate is trusted - const SSL_VERIFY_PEER = ::ffi::SSL_VERIFY_PEER, + const SSL_VERIFY_PEER = ::ffi::SSL_VERIFY_PEER; /// Do not verify the server's certificate - const SSL_VERIFY_NONE = ::ffi::SSL_VERIFY_NONE, + const SSL_VERIFY_NONE = ::ffi::SSL_VERIFY_NONE; /// Terminate handshake if client did not return a certificate. /// Use together with SSL_VERIFY_PEER. - const SSL_VERIFY_FAIL_IF_NO_PEER_CERT = ::ffi::SSL_VERIFY_FAIL_IF_NO_PEER_CERT, + const SSL_VERIFY_FAIL_IF_NO_PEER_CERT = ::ffi::SSL_VERIFY_FAIL_IF_NO_PEER_CERT; } } @@ -246,11 +248,19 @@ lazy_static! { // Registers a destructor for the data which will be called // when context is freed fn get_callback_idx<T: Any + 'static>() -> c_int { - *INDEXES.lock().unwrap().entry(TypeId::of::<T>()).or_insert_with(|| get_new_idx::<T>()) + *INDEXES + .lock() + .unwrap() + .entry(TypeId::of::<T>()) + .or_insert_with(|| get_new_idx::<T>()) } fn get_ssl_callback_idx<T: Any + 'static>() -> c_int { - *SSL_INDEXES.lock().unwrap().entry(TypeId::of::<T>()).or_insert_with(|| get_new_ssl_idx::<T>()) + *SSL_INDEXES + .lock() + .unwrap() + .entry(TypeId::of::<T>()) + .or_insert_with(|| get_new_ssl_idx::<T>()) } lazy_static! { @@ -429,10 +439,10 @@ extern "C" fn raw_alpn_select_cb(ssl: *mut ffi::SSL, unsafe { select_proto_using(ssl, out as *mut _, outlen, inbuf, inlen, *ALPN_PROTOS_IDX) } } -unsafe extern fn raw_tmp_dh<F>(ssl: *mut ffi::SSL, - is_export: c_int, - keylength: c_int) - -> *mut ffi::DH +unsafe extern "C" fn raw_tmp_dh<F>(ssl: *mut ffi::SSL, + is_export: c_int, + keylength: c_int) + -> *mut ffi::DH where F: Fn(&mut SslRef, bool, u32) -> Result<Dh, ErrorStack> + Any + 'static + Sync + Send { let ctx = ffi::SSL_get_SSL_CTX(ssl); @@ -454,10 +464,10 @@ unsafe extern fn raw_tmp_dh<F>(ssl: *mut ffi::SSL, } #[cfg(any(all(feature = "v101", ossl101), all(feature = "v102", ossl102)))] -unsafe extern fn raw_tmp_ecdh<F>(ssl: *mut ffi::SSL, - is_export: c_int, - keylength: c_int) - -> *mut ffi::EC_KEY +unsafe extern "C" fn raw_tmp_ecdh<F>(ssl: *mut ffi::SSL, + is_export: c_int, + keylength: c_int) + -> *mut ffi::EC_KEY where F: Fn(&mut SslRef, bool, u32) -> Result<EcKey, ErrorStack> + Any + 'static + Sync + Send { let ctx = ffi::SSL_get_SSL_CTX(ssl); @@ -478,10 +488,10 @@ unsafe extern fn raw_tmp_ecdh<F>(ssl: *mut ffi::SSL, } } -unsafe extern fn raw_tmp_dh_ssl<F>(ssl: *mut ffi::SSL, - is_export: c_int, - keylength: c_int) - -> *mut ffi::DH +unsafe extern "C" fn raw_tmp_dh_ssl<F>(ssl: *mut ffi::SSL, + is_export: c_int, + keylength: c_int) + -> *mut ffi::DH where F: Fn(&mut SslRef, bool, u32) -> Result<Dh, ErrorStack> + Any + 'static + Sync + Send { let callback = ffi::SSL_get_ex_data(ssl, get_ssl_callback_idx::<F>()); @@ -502,10 +512,10 @@ unsafe extern fn raw_tmp_dh_ssl<F>(ssl: *mut ffi::SSL, } #[cfg(any(all(feature = "v101", ossl101), all(feature = "v102", ossl102)))] -unsafe extern fn raw_tmp_ecdh_ssl<F>(ssl: *mut ffi::SSL, - is_export: c_int, - keylength: c_int) - -> *mut ffi::EC_KEY +unsafe extern "C" fn raw_tmp_ecdh_ssl<F>(ssl: *mut ffi::SSL, + is_export: c_int, + keylength: c_int) + -> *mut ffi::EC_KEY where F: Fn(&mut SslRef, bool, u32) -> Result<EcKey, ErrorStack> + Any + 'static + Sync + Send { let callback = ffi::SSL_get_ex_data(ssl, get_ssl_callback_idx::<F>()); @@ -525,7 +535,7 @@ unsafe extern fn raw_tmp_ecdh_ssl<F>(ssl: *mut ffi::SSL, } } -unsafe extern fn raw_tlsext_status<F>(ssl: *mut ffi::SSL, _: *mut c_void) -> c_int +unsafe extern "C" fn raw_tlsext_status<F>(ssl: *mut ffi::SSL, _: *mut c_void) -> c_int where F: Fn(&mut SslRef) -> Result<bool, ErrorStack> + Any + 'static + Sync + Send { let ssl_ctx = ffi::SSL_get_SSL_CTX(ssl as *const _); @@ -725,7 +735,7 @@ impl SslContextBuilder { ffi::SSL_CTX_set_ex_data(self.as_ptr(), get_callback_idx::<F>(), Box::into_raw(callback) as *mut c_void); - let f: unsafe extern fn (_, _, _) -> _ = raw_tmp_dh::<F>; + let f: unsafe extern "C" fn(_, _, _) -> _ = raw_tmp_dh::<F>; ffi::SSL_CTX_set_tmp_dh_callback(self.as_ptr(), f); } } @@ -744,7 +754,7 @@ impl SslContextBuilder { ffi::SSL_CTX_set_ex_data(self.as_ptr(), get_callback_idx::<F>(), Box::into_raw(callback) as *mut c_void); - let f: unsafe extern fn(_, _, _) -> _ = raw_tmp_ecdh::<F>; + let f: unsafe extern "C" fn(_, _, _) -> _ = raw_tmp_ecdh::<F>; ffi::SSL_CTX_set_tmp_ecdh_callback(self.as_ptr(), f); } } @@ -765,7 +775,7 @@ impl SslContextBuilder { cvt(ffi::SSL_CTX_load_verify_locations(self.as_ptr(), file.as_ptr() as *const _, ptr::null())) - .map(|_| ()) + .map(|_| ()) } } @@ -781,7 +791,7 @@ impl SslContextBuilder { /// Set the context identifier for sessions /// - /// This value identifies the server's session cache to a clients, telling them when they're + /// This value identifies the server's session cache to clients, telling them when they're /// able to reuse sessions. Should be set to a unique value per server, unless multiple servers /// share a session cache. /// @@ -793,7 +803,7 @@ impl SslContextBuilder { cvt(ffi::SSL_CTX_set_session_id_context(self.as_ptr(), sid_ctx.as_ptr(), sid_ctx.len() as c_uint)) - .map(|_| ()) + .map(|_| ()) } } @@ -807,7 +817,7 @@ impl SslContextBuilder { cvt(ffi::SSL_CTX_use_certificate_file(self.as_ptr(), file.as_ptr() as *const _, file_type.as_raw())) - .map(|_| ()) + .map(|_| ()) } } @@ -853,7 +863,7 @@ impl SslContextBuilder { cvt(ffi::SSL_CTX_use_PrivateKey_file(self.as_ptr(), file.as_ptr() as *const _, file_type.as_raw())) - .map(|_| ()) + .map(|_| ()) } } @@ -1002,7 +1012,7 @@ impl SslContextBuilder { ffi::SSL_CTX_set_ex_data(self.as_ptr(), get_callback_idx::<F>(), Box::into_raw(callback) as *mut c_void); - let f: unsafe extern fn (_, _) -> _ = raw_tlsext_status::<F>; + let f: unsafe extern "C" fn(_, _) -> _ = raw_tlsext_status::<F>; cvt(ffi::SSL_CTX_set_tlsext_status_cb(self.as_ptr(), Some(f)) as c_int).map(|_| ()) } } @@ -1098,9 +1108,7 @@ impl SslContextRef { /// Returns the certificate store used for verification. pub fn cert_store(&self) -> &X509StoreRef { - unsafe { - X509StoreRef::from_ptr(ffi::SSL_CTX_get_cert_store(self.as_ptr())) - } + unsafe { X509StoreRef::from_ptr(ffi::SSL_CTX_get_cert_store(self.as_ptr())) } } pub fn extra_chain_certs(&self) -> &StackRef<X509> { @@ -1335,7 +1343,7 @@ impl SslRef { ffi::SSL_set_ex_data(self.as_ptr(), get_ssl_callback_idx::<F>(), Box::into_raw(callback) as *mut c_void); - let f: unsafe extern fn (_, _, _) -> _ = raw_tmp_dh_ssl::<F>; + let f: unsafe extern "C" fn(_, _, _) -> _ = raw_tmp_dh_ssl::<F>; ffi::SSL_set_tmp_dh_callback(self.as_ptr(), f); } } @@ -1354,7 +1362,7 @@ impl SslRef { ffi::SSL_set_ex_data(self.as_ptr(), get_ssl_callback_idx::<F>(), Box::into_raw(callback) as *mut c_void); - let f: unsafe extern fn(_, _, _) -> _ = raw_tmp_ecdh_ssl::<F>; + let f: unsafe extern "C" fn(_, _, _) -> _ = raw_tmp_ecdh_ssl::<F>; ffi::SSL_set_tmp_ecdh_callback(self.as_ptr(), f); } } @@ -1595,9 +1603,7 @@ impl SslRef { /// Determines if the session provided to `set_session` was successfully reused. pub fn session_reused(&self) -> bool { - unsafe { - ffi::SSL_session_reused(self.as_ptr()) != 0 - } + unsafe { ffi::SSL_session_reused(self.as_ptr()) != 0 } } /// Sets the status response a client wishes the server to reply with. @@ -1631,16 +1637,15 @@ impl SslRef { ptr::copy_nonoverlapping(response.as_ptr(), p as *mut u8, response.len()); cvt(ffi::SSL_set_tlsext_status_ocsp_resp(self.as_ptr(), p as *mut c_uchar, - response.len() as c_long) as c_int) - .map(|_| ()) + response.len() as c_long) as + c_int) + .map(|_| ()) } } /// Determines if this `Ssl` is configured for server-side or client-side use. pub fn is_server(&self) -> bool { - unsafe { - compat::SSL_is_server(self.as_ptr()) != 0 - } + unsafe { compat::SSL_is_server(self.as_ptr()) != 0 } } } @@ -1679,15 +1684,15 @@ impl Ssl { e @ Error::WantWrite(_) | e @ Error::WantRead(_) => { Err(HandshakeError::Interrupted(MidHandshakeSslStream { - stream: stream, - error: e, - })) + stream: stream, + error: e, + })) } err => { Err(HandshakeError::Failure(MidHandshakeSslStream { - stream: stream, - error: err, - })) + stream: stream, + error: err, + })) } } } @@ -1711,15 +1716,15 @@ impl Ssl { e @ Error::WantWrite(_) | e @ Error::WantRead(_) => { Err(HandshakeError::Interrupted(MidHandshakeSslStream { - stream: stream, - error: e, - })) + stream: stream, + error: e, + })) } err => { Err(HandshakeError::Failure(MidHandshakeSslStream { - stream: stream, - error: err, - })) + stream: stream, + error: err, + })) } } } @@ -1823,7 +1828,7 @@ impl<S: Read + Write> SslStream<S> { // To avoid that confusion short-circuit that logic and return quickly // if `buf` has a length of zero. if buf.len() == 0 { - return Ok(0) + return Ok(0); } let ret = self.ssl.read(buf); @@ -1845,7 +1850,7 @@ impl<S: Read + Write> SslStream<S> { pub fn ssl_write(&mut self, buf: &[u8]) -> Result<usize, Error> { // See above for why we short-circuit on zero-length buffers if buf.len() == 0 { - return Ok(0) + return Ok(0); } let ret = self.ssl.write(buf); @@ -1907,7 +1912,7 @@ impl<S> SslStream<S> { } }; Error::WantWrite(err) - }, + } ffi::SSL_ERROR_WANT_READ => { let err = match self.get_bio_error() { Some(err) => err, @@ -1917,7 +1922,7 @@ impl<S> SslStream<S> { } }; Error::WantRead(err) - }, + } err => { Error::Stream(io::Error::new(io::ErrorKind::InvalidData, format!("unexpected error {}", err))) @@ -1977,14 +1982,13 @@ impl<S: Read + Write> Read for SslStream<S> { impl<S: Read + Write> Write for SslStream<S> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { - self.ssl_write(buf).map_err(|e| { - match e { - Error::Stream(e) => e, - Error::WantRead(e) => e, - Error::WantWrite(e) => e, - e => io::Error::new(io::ErrorKind::Other, e), - } - }) + self.ssl_write(buf) + .map_err(|e| match e { + Error::Stream(e) => e, + Error::WantRead(e) => e, + Error::WantWrite(e) => e, + e => io::Error::new(io::ErrorKind::Other, e), + }) } fn flush(&mut self) -> io::Result<()> { @@ -2084,7 +2088,8 @@ mod compat { pub unsafe fn SSL_SESSION_get_master_key(session: *const ffi::SSL_SESSION, out: *mut c_uchar, - mut outlen: size_t) -> size_t { + mut outlen: size_t) + -> size_t { if outlen == 0 { return (*session).master_key_length as size_t; } diff --git a/openssl/src/ssl/tests/mod.rs b/openssl/src/ssl/tests/mod.rs index 5b52a524..48d83b78 100644 --- a/openssl/src/ssl/tests/mod.rs +++ b/openssl/src/ssl/tests/mod.rs @@ -180,7 +180,7 @@ macro_rules! run_test( use hex::FromHex; use foreign_types::ForeignTypeRef; use super::Server; - #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] + #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] use super::ROOT_CERT; #[test] @@ -743,7 +743,7 @@ fn test_alpn_server_advertise_multiple() { /// Test that Servers supporting ALPN don't report a protocol when none of their protocols match /// the client's reported protocol. #[test] -#[cfg(all(feature = "v102", ossl102))] +#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] fn test_alpn_server_select_none() { let listener = TcpListener::bind("127.0.0.1:0").unwrap(); let localhost = listener.local_addr().unwrap(); @@ -776,38 +776,6 @@ fn test_alpn_server_select_none() { assert_eq!(None, stream.ssl().selected_alpn_protocol()); } -// In 1.1.0, ALPN negotiation failure is a fatal error -#[test] -#[cfg(all(feature = "v110", ossl110))] -fn test_alpn_server_select_none() { - let listener = TcpListener::bind("127.0.0.1:0").unwrap(); - let localhost = listener.local_addr().unwrap(); - // We create a different context instance for the server... - let listener_ctx = { - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_verify(SSL_VERIFY_PEER); - ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]).unwrap(); - assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509_FILETYPE_PEM) - .is_ok()); - ctx.set_private_key_file(&Path::new("test/key.pem"), X509_FILETYPE_PEM) - .unwrap(); - ctx.build() - }; - // Have the listener wait on the connection in a different thread. - thread::spawn(move || { - let (stream, _) = listener.accept().unwrap(); - assert!(Ssl::new(&listener_ctx).unwrap().accept(stream).is_err()); - }); - - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_verify(SSL_VERIFY_PEER); - ctx.set_alpn_protocols(&[b"http/2"]).unwrap(); - 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(); - assert!(Ssl::new(&ctx.build()).unwrap().connect(stream).is_err()); -} - #[test] #[cfg_attr(any(libressl, windows, target_arch = "arm"), ignore)] // FIXME(#467) fn test_read_dtlsv1() { diff --git a/openssl/src/verify.rs b/openssl/src/verify.rs index f554127a..f8049ce4 100644 --- a/openssl/src/verify.rs +++ b/openssl/src/verify.rs @@ -6,16 +6,16 @@ use cvt; use error::ErrorStack; bitflags! { - pub flags X509CheckFlags: c_uint { - const X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT = ffi::X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT, - const X509_CHECK_FLAG_NO_WILDCARDS = ffi::X509_CHECK_FLAG_NO_WILDCARDS, - const X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS = ffi::X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS, - const X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS = ffi::X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS, + pub struct X509CheckFlags: c_uint { + const X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT = ffi::X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT; + const X509_CHECK_FLAG_NO_WILDCARDS = ffi::X509_CHECK_FLAG_NO_WILDCARDS; + const X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS = ffi::X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS; + const X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS = ffi::X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS; const X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS - = ffi::X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS, + = ffi::X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS; /// Requires the `v110` feature and OpenSSL 1.1.0. #[cfg(all(feature = "v110", ossl110))] - const X509_CHECK_FLAG_NEVER_CHECK_SUBJECT = ffi::X509_CHECK_FLAG_NEVER_CHECK_SUBJECT, + const X509_CHECK_FLAG_NEVER_CHECK_SUBJECT = ffi::X509_CHECK_FLAG_NEVER_CHECK_SUBJECT; } } diff --git a/openssl/test/key.der b/openssl/test/key.der Binary files differnew file mode 100644 index 00000000..6b6209fd --- /dev/null +++ b/openssl/test/key.der diff --git a/systest/build.rs b/systest/build.rs index 548d6080..115eda29 100644 --- a/systest/build.rs +++ b/systest/build.rs @@ -27,6 +27,9 @@ fn main() { } else if let Ok(version) = env::var("DEP_OPENSSL_VERSION") { cfg.cfg(&format!("ossl{}", version), None); } + if let (Ok(version), Ok(patch)) = (env::var("DEP_OPENSSL_VERSION"), env::var("DEP_OPENSSL_PATCH")) { + cfg.cfg(&format!("ossl{}{}", version, patch), None); + } if let Ok(vars) = env::var("DEP_OPENSSL_CONF") { for var in vars.split(",") { cfg.cfg("osslconf", Some(var)); |