From 8986c3c4f471fde0c8d603b9826ce2d079b60a26 Mon Sep 17 00:00:00 2001 From: Ryan Meulenkamp Date: Wed, 16 Aug 2023 22:32:08 +0200 Subject: [PATCH 1/4] Add TLS1.3 support --- src/imp/openssl.rs | 1 + src/imp/schannel.rs | 1 + src/imp/security_framework.rs | 1 + src/lib.rs | 2 ++ src/test.rs | 19 +++++++++++++++++++ 5 files changed, 24 insertions(+) diff --git a/src/imp/openssl.rs b/src/imp/openssl.rs index 8fc43620..2d1df1a7 100644 --- a/src/imp/openssl.rs +++ b/src/imp/openssl.rs @@ -32,6 +32,7 @@ fn supported_protocols( Protocol::Tlsv10 => SslVersion::TLS1, Protocol::Tlsv11 => SslVersion::TLS1_1, Protocol::Tlsv12 => SslVersion::TLS1_2, + Protocol::Tlsv13 => SslVersion::TLS1_3, } } diff --git a/src/imp/schannel.rs b/src/imp/schannel.rs index 62e5042f..faeb5dcb 100644 --- a/src/imp/schannel.rs +++ b/src/imp/schannel.rs @@ -19,6 +19,7 @@ static PROTOCOLS: &'static [Protocol] = &[ Protocol::Tls10, Protocol::Tls11, Protocol::Tls12, + Protocol::Tls13, ]; fn convert_protocols(min: Option<::Protocol>, max: Option<::Protocol>) -> &'static [Protocol] { diff --git a/src/imp/security_framework.rs b/src/imp/security_framework.rs index f56a916d..8a2489de 100644 --- a/src/imp/security_framework.rs +++ b/src/imp/security_framework.rs @@ -49,6 +49,7 @@ fn convert_protocol(protocol: Protocol) -> SslProtocol { Protocol::Tlsv10 => SslProtocol::TLS1, Protocol::Tlsv11 => SslProtocol::TLS11, Protocol::Tlsv12 => SslProtocol::TLS12, + Protocol::Tlsv13 => SslProtocol::TLS13, } } diff --git a/src/lib.rs b/src/lib.rs index 267679dc..614007dc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -322,6 +322,8 @@ pub enum Protocol { Tlsv11, /// The TLS 1.2 protocol. Tlsv12, + /// The TLS 1.3 protocol. + Tlsv13, } /// A builder for `TlsConnector`s. diff --git a/src/test.rs b/src/test.rs index c51b0bc4..a40486c3 100644 --- a/src/test.rs +++ b/src/test.rs @@ -16,6 +16,25 @@ macro_rules! p { }; } +#[test] +fn connect_google_tls13() { + let builder = p!( + TlsConnector::builder() + .min_protocol_version(Some(Protocol::Tlsv13)) + .max_protocol_version(Some(Protocol::Tlsv13)) + .build()); + let s = p!(TcpStream::connect("google.com:443")); + let mut socket = p!(builder.connect("google.com", s)); + + p!(socket.write_all(b"GET / HTTP/1.0\r\n\r\n")); + let mut result = vec![]; + p!(socket.read_to_end(&mut result)); + + println!("{}", String::from_utf8_lossy(&result)); + assert!(result.starts_with(b"HTTP/1.0")); + assert!(result.ends_with(b"\r\n") || result.ends_with(b"")); +} + #[test] fn connect_google() { let builder = p!(TlsConnector::new()); From 9490734c2c6ae91425e35ce56280a4d2a20d7ec8 Mon Sep 17 00:00:00 2001 From: Alexis Mousset Date: Wed, 16 Aug 2023 22:54:17 +0200 Subject: [PATCH 2/4] TLS 1.3 version support --- build.rs | 10 ++++++++++ src/imp/openssl.rs | 1 + src/lib.rs | 1 + 3 files changed, 12 insertions(+) diff --git a/build.rs b/build.rs index b7a41f45..f0b6f7d5 100644 --- a/build.rs +++ b/build.rs @@ -8,6 +8,11 @@ fn main() { if version >= 0x1_01_00_00_0 { println!("cargo:rustc-cfg=have_min_max_version"); } + + // TLS 1.3 requires openssl 1.1.1 + if version >= 0x1_01_01_00_0 { + println!("cargo:rustc-cfg=have_tls13_version"); + } } if let Ok(version) = env::var("DEP_OPENSSL_LIBRESSL_VERSION_NUMBER") { @@ -16,5 +21,10 @@ fn main() { if version >= 0x2_06_01_00_0 { println!("cargo:rustc-cfg=have_min_max_version"); } + + // TLS 1.3 requires libressl 3.2 + if version >= 0x3_02_01_00_0 { + println!("cargo:rustc-cfg=have_tls13_version"); + } } } diff --git a/src/imp/openssl.rs b/src/imp/openssl.rs index 2d1df1a7..f0ad7fb3 100644 --- a/src/imp/openssl.rs +++ b/src/imp/openssl.rs @@ -32,6 +32,7 @@ fn supported_protocols( Protocol::Tlsv10 => SslVersion::TLS1, Protocol::Tlsv11 => SslVersion::TLS1_1, Protocol::Tlsv12 => SslVersion::TLS1_2, + #[cfg(have_tls13_version)] Protocol::Tlsv13 => SslVersion::TLS1_3, } } diff --git a/src/lib.rs b/src/lib.rs index 614007dc..3fb5f2b7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -323,6 +323,7 @@ pub enum Protocol { /// The TLS 1.2 protocol. Tlsv12, /// The TLS 1.3 protocol. + #[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios", have_tls13_version))] Tlsv13, } From 1e65774e4282b3696496e3f036b0903d7d879f87 Mon Sep 17 00:00:00 2001 From: Alexis Mousset Date: Wed, 16 Aug 2023 23:09:47 +0200 Subject: [PATCH 3/4] TLS 1.3 version support --- build.rs | 4 ++-- src/imp/schannel.rs | 1 - src/imp/security_framework.rs | 1 - src/lib.rs | 4 +++- src/test.rs | 1 + 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/build.rs b/build.rs index f0b6f7d5..4f9f63bc 100644 --- a/build.rs +++ b/build.rs @@ -22,8 +22,8 @@ fn main() { println!("cargo:rustc-cfg=have_min_max_version"); } - // TLS 1.3 requires libressl 3.2 - if version >= 0x3_02_01_00_0 { + // TLS 1.3 requires libressl 3.4.0 + if version >= 0x3_04_00_00_0 { println!("cargo:rustc-cfg=have_tls13_version"); } } diff --git a/src/imp/schannel.rs b/src/imp/schannel.rs index faeb5dcb..62e5042f 100644 --- a/src/imp/schannel.rs +++ b/src/imp/schannel.rs @@ -19,7 +19,6 @@ static PROTOCOLS: &'static [Protocol] = &[ Protocol::Tls10, Protocol::Tls11, Protocol::Tls12, - Protocol::Tls13, ]; fn convert_protocols(min: Option<::Protocol>, max: Option<::Protocol>) -> &'static [Protocol] { diff --git a/src/imp/security_framework.rs b/src/imp/security_framework.rs index 8a2489de..f56a916d 100644 --- a/src/imp/security_framework.rs +++ b/src/imp/security_framework.rs @@ -49,7 +49,6 @@ fn convert_protocol(protocol: Protocol) -> SslProtocol { Protocol::Tlsv10 => SslProtocol::TLS1, Protocol::Tlsv11 => SslProtocol::TLS11, Protocol::Tlsv12 => SslProtocol::TLS12, - Protocol::Tlsv13 => SslProtocol::TLS13, } } diff --git a/src/lib.rs b/src/lib.rs index 3fb5f2b7..f9e91014 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -323,7 +323,9 @@ pub enum Protocol { /// The TLS 1.2 protocol. Tlsv12, /// The TLS 1.3 protocol. - #[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios", have_tls13_version))] + /// + /// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer. + #[cfg(have_tls13_version)] Tlsv13, } diff --git a/src/test.rs b/src/test.rs index a40486c3..c5a2645d 100644 --- a/src/test.rs +++ b/src/test.rs @@ -16,6 +16,7 @@ macro_rules! p { }; } +#[cfg(have_tls13_version)] #[test] fn connect_google_tls13() { let builder = p!( From b81f70295bdb6672dd0b5c4686673c0775968d1d Mon Sep 17 00:00:00 2001 From: Alexis Mousset Date: Fri, 18 Aug 2023 15:24:04 +0200 Subject: [PATCH 4/4] Always define TLSv3 --- Cargo.toml | 2 +- src/imp/openssl.rs | 23 ++++++++++++++--------- src/imp/schannel.rs | 1 + src/imp/security_framework.rs | 12 +++++++----- src/lib.rs | 4 ++-- src/test.rs | 2 +- 6 files changed, 26 insertions(+), 18 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index cab1d474..41931175 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ libc = "0.2" tempfile = "3.1.0" [target.'cfg(target_os = "windows")'.dependencies] -schannel = "0.1.17" +schannel = "0.1.20" [target.'cfg(not(any(target_os = "windows", target_os = "macos", target_os = "ios")))'.dependencies] log = "0.4.5" diff --git a/src/imp/openssl.rs b/src/imp/openssl.rs index f0ad7fb3..b318b7c0 100644 --- a/src/imp/openssl.rs +++ b/src/imp/openssl.rs @@ -23,22 +23,24 @@ fn supported_protocols( min: Option, max: Option, ctx: &mut SslContextBuilder, -) -> Result<(), ErrorStack> { +) -> Result<(), Error> { use self::openssl::ssl::SslVersion; - fn cvt(p: Protocol) -> SslVersion { + fn cvt(p: Protocol) -> Result { match p { - Protocol::Sslv3 => SslVersion::SSL3, - Protocol::Tlsv10 => SslVersion::TLS1, - Protocol::Tlsv11 => SslVersion::TLS1_1, - Protocol::Tlsv12 => SslVersion::TLS1_2, + Protocol::Sslv3 => Ok(SslVersion::SSL3), + Protocol::Tlsv10 => Ok(SslVersion::TLS1), + Protocol::Tlsv11 => Ok(SslVersion::TLS1_1), + Protocol::Tlsv12 => Ok(SslVersion::TLS1_2), #[cfg(have_tls13_version)] - Protocol::Tlsv13 => SslVersion::TLS1_3, + Protocol::Tlsv13 => Ok(SslVersion::TLS1_3), + #[cfg(not(have_tls13_version))] + Protocol::Tlsv13 => Err(Error::UnsupportedTls13) } } - ctx.set_min_proto_version(min.map(cvt))?; - ctx.set_max_proto_version(max.map(cvt))?; + ctx.set_min_proto_version(min.map(cvt).transpose()?)?; + ctx.set_max_proto_version(max.map(cvt).transpose()?)?; Ok(()) } @@ -117,6 +119,7 @@ pub enum Error { Ssl(ssl::Error, X509VerifyResult), EmptyChain, NotPkcs8, + UnsupportedTls13, } impl error::Error for Error { @@ -126,6 +129,7 @@ impl error::Error for Error { Error::Ssl(ref e, _) => error::Error::source(e), Error::EmptyChain => None, Error::NotPkcs8 => None, + Error::UnsupportedTls13 => None, } } } @@ -141,6 +145,7 @@ impl fmt::Display for Error { "at least one certificate must be provided to create an identity" ), Error::NotPkcs8 => write!(fmt, "expected PKCS#8 PEM"), + Error::UnsupportedTls13 => write!(fmt, "TLS version 1.3 not supported"), } } } diff --git a/src/imp/schannel.rs b/src/imp/schannel.rs index 62e5042f..faeb5dcb 100644 --- a/src/imp/schannel.rs +++ b/src/imp/schannel.rs @@ -19,6 +19,7 @@ static PROTOCOLS: &'static [Protocol] = &[ Protocol::Tls10, Protocol::Tls11, Protocol::Tls12, + Protocol::Tls13, ]; fn convert_protocols(min: Option<::Protocol>, max: Option<::Protocol>) -> &'static [Protocol] { diff --git a/src/imp/security_framework.rs b/src/imp/security_framework.rs index f56a916d..b5366eeb 100644 --- a/src/imp/security_framework.rs +++ b/src/imp/security_framework.rs @@ -43,12 +43,14 @@ static SET_AT_EXIT: Once = Once::new(); #[cfg(not(target_os = "ios"))] static TEMP_KEYCHAIN: Lazy>> = Lazy::new(|| Mutex::new(None)); -fn convert_protocol(protocol: Protocol) -> SslProtocol { +fn convert_protocol(protocol: Protocol) -> Result { match protocol { - Protocol::Sslv3 => SslProtocol::SSL3, - Protocol::Tlsv10 => SslProtocol::TLS1, - Protocol::Tlsv11 => SslProtocol::TLS11, - Protocol::Tlsv12 => SslProtocol::TLS12, + Protocol::Sslv3 => Ok(SslProtocol::SSL3), + Protocol::Tlsv10 => Ok(SslProtocol::TLS1), + Protocol::Tlsv11 => Ok(SslProtocol::TLS11), + Protocol::Tlsv12 => Ok(SslProtocol::TLS12), + // Not supported in SecureTransport API used in security_framework + Protocol::Tlsv13 => Err(Error(base::Error::from("TLS 1.3 is not supported"))) } } diff --git a/src/lib.rs b/src/lib.rs index f9e91014..e10d6642 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -324,8 +324,8 @@ pub enum Protocol { Tlsv12, /// The TLS 1.3 protocol. /// - /// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer. - #[cfg(have_tls13_version)] + /// Only works on Windows, or with openssl >= 1.1.1 or libressl >= 3.4.0. + /// It will fail at runtime when used in other situations. Tlsv13, } diff --git a/src/test.rs b/src/test.rs index c5a2645d..05beb1e6 100644 --- a/src/test.rs +++ b/src/test.rs @@ -16,7 +16,7 @@ macro_rules! p { }; } -#[cfg(have_tls13_version)] +#[cfg(any(target_os = "windows", have_tls13_version))] #[test] fn connect_google_tls13() { let builder = p!(