From a11252614be39848964ba34b10067cc28a01611c Mon Sep 17 00:00:00 2001 From: ssrlive <30760636+ssrlive@users.noreply.github.com> Date: Sun, 5 Jan 2025 14:05:20 +0800 Subject: [PATCH 1/6] testing suits for iOS --- .github/workflows/ci.yml | 23 ++++++++++++++++++++++- .gitignore | 1 + Cargo.toml | 3 +++ src/imp/openssl.rs | 2 +- src/imp/security_framework.rs | 21 +++++++++++++++++---- src/lib.rs | 2 +- 6 files changed, 45 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 29e22df7..8aa74f74 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,4 +55,25 @@ jobs: path: target key: target-${{ runner.os }}-${{ steps.rust-version.outputs.version }}-${{ hashFiles('Cargo.lock') }} - run: cargo test --features vendored - - run: cargo test --features vendored + + build_n_test_ios: + strategy: + fail-fast: false + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + - name: Install cargo lipo and rust compiler for ios target + if: ${{ !cancelled() }} + run: | + cargo install --locked cargo-lipo + rustup target add x86_64-apple-ios aarch64-apple-ios + - name: clippy + if: ${{ !cancelled() }} + run: cargo clippy --target x86_64-apple-ios --all-features -- -D warnings + - name: Build + if: ${{ !cancelled() }} + run: | + cargo lipo --verbose --all-features + - name: Abort on error + if: ${{ failure() }} + run: echo "iOS build job failed" && false diff --git a/.gitignore b/.gitignore index 2deeb18e..5b04ad24 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.VSCodeCounter/ target Cargo.lock .idea diff --git a/Cargo.toml b/Cargo.toml index dc50f8c4..90d6a002 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,9 @@ rust-version = "1.53.0" features = ["alpn"] rustdoc-args = ["--cfg", "docsrs"] +[lib] +crate-type = ["staticlib", "rlib"] + [features] vendored = ["openssl/vendored"] alpn = ["security-framework/alpn"] diff --git a/src/imp/openssl.rs b/src/imp/openssl.rs index 8fc43620..8b889e77 100644 --- a/src/imp/openssl.rs +++ b/src/imp/openssl.rs @@ -16,7 +16,7 @@ use std::fmt; use std::io; use std::sync::Once; -use {Protocol, TlsAcceptorBuilder, TlsConnectorBuilder}; +use crate::{Protocol, TlsAcceptorBuilder, TlsConnectorBuilder}; #[cfg(have_min_max_version)] fn supported_protocols( diff --git a/src/imp/security_framework.rs b/src/imp/security_framework.rs index 302791a9..b7d79b57 100644 --- a/src/imp/security_framework.rs +++ b/src/imp/security_framework.rs @@ -15,7 +15,6 @@ use std::error; use std::fmt; use std::io; use std::str; -use std::sync::Mutex; use std::sync::Once; #[cfg(not(any( @@ -58,6 +57,7 @@ use self::security_framework::os::macos::keychain::{self, KeychainSettings, SecK use {Protocol, TlsAcceptorBuilder, TlsConnectorBuilder}; +#[allow(dead_code)] static SET_AT_EXIT: Once = Once::new(); #[cfg(not(any( @@ -66,7 +66,8 @@ static SET_AT_EXIT: Once = Once::new(); target_os = "tvos", target_os = "visionos" )))] -static TEMP_KEYCHAIN: Mutex> = Mutex::new(None); +static TEMP_KEYCHAIN: std::sync::Mutex> = + std::sync::Mutex::new(None); fn convert_protocol(protocol: Protocol) -> SslProtocol { match protocol { @@ -233,6 +234,7 @@ impl Identity { } } +#[allow(dead_code)] fn random_password() -> Result { use std::fmt::Write; let mut bytes = [0_u8; 10]; @@ -479,6 +481,7 @@ impl TlsAcceptor { pub struct TlsStream { stream: secure_transport::SslStream, + #[allow(dead_code)] cert: Option, } @@ -641,6 +644,7 @@ impl io::Write for TlsStream { } } +#[allow(dead_code)] enum Digest { Sha224, Sha256, @@ -649,9 +653,10 @@ enum Digest { } impl Digest { + #[allow(dead_code)] fn hash(&self, data: &[u8]) -> Vec { unsafe { - assert!(data.len() <= CC_LONG::max_value() as usize); + assert!(data.len() <= CC_LONG::MAX as usize); match *self { Digest::Sha224 => { let mut buf = [0; CC_SHA224_DIGEST_LENGTH]; @@ -679,16 +684,24 @@ impl Digest { } // FIXME ideally we'd pull these in from elsewhere +#[allow(dead_code)] const CC_SHA224_DIGEST_LENGTH: usize = 28; +#[allow(dead_code)] const CC_SHA256_DIGEST_LENGTH: usize = 32; +#[allow(dead_code)] const CC_SHA384_DIGEST_LENGTH: usize = 48; +#[allow(dead_code)] const CC_SHA512_DIGEST_LENGTH: usize = 64; -#[allow(non_camel_case_types)] +#[allow(non_camel_case_types, dead_code)] type CC_LONG = u32; extern "C" { + #[allow(dead_code)] fn CC_SHA224(data: *const u8, len: CC_LONG, md: *mut u8) -> *mut u8; + #[allow(dead_code)] fn CC_SHA256(data: *const u8, len: CC_LONG, md: *mut u8) -> *mut u8; + #[allow(dead_code)] fn CC_SHA384(data: *const u8, len: CC_LONG, md: *mut u8) -> *mut u8; + #[allow(dead_code)] fn CC_SHA512(data: *const u8, len: CC_LONG, md: *mut u8) -> *mut u8; } diff --git a/src/lib.rs b/src/lib.rs index 0f738dfd..79947339 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -106,7 +106,7 @@ use std::result; #[cfg(not(any(target_os = "windows", target_vendor = "apple",)))] #[macro_use] extern crate log; -#[cfg(any(target_vendor = "apple",))] +#[cfg(target_vendor = "apple")] #[path = "imp/security_framework.rs"] mod imp; #[cfg(target_os = "windows")] From 2d8b39826d823aaaeb5f1c4c01ef08c63543fc45 Mon Sep 17 00:00:00 2001 From: ssrlive <30760636+ssrlive@users.noreply.github.com> Date: Sun, 5 Jan 2025 16:44:58 +0800 Subject: [PATCH 2/6] have_min_max_version feature --- Cargo.toml | 1 + src/imp/openssl.rs | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 90d6a002..31a02121 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ crate-type = ["staticlib", "rlib"] [features] vendored = ["openssl/vendored"] alpn = ["security-framework/alpn"] +have_min_max_version = [] [target.'cfg(target_vendor = "apple")'.dependencies] security-framework = "2.0.0" diff --git a/src/imp/openssl.rs b/src/imp/openssl.rs index 8b889e77..09e44b51 100644 --- a/src/imp/openssl.rs +++ b/src/imp/openssl.rs @@ -18,7 +18,7 @@ use std::sync::Once; use crate::{Protocol, TlsAcceptorBuilder, TlsConnectorBuilder}; -#[cfg(have_min_max_version)] +#[cfg(feature = "have_min_max_version")] fn supported_protocols( min: Option, max: Option, @@ -41,7 +41,7 @@ fn supported_protocols( Ok(()) } -#[cfg(not(have_min_max_version))] +#[cfg(not(feature = "have_min_max_version"))] fn supported_protocols( min: Option, max: Option, From 038a1f71b21c58a294d4ecf0526b53eac0783e14 Mon Sep 17 00:00:00 2001 From: ssrlive <30760636+ssrlive@users.noreply.github.com> Date: Sun, 5 Jan 2025 16:48:41 +0800 Subject: [PATCH 3/6] CI any branches --- .github/workflows/ci.yml | 4 ++-- Cargo.toml | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8aa74f74..a6f8aacd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,10 +3,10 @@ name: CI on: pull_request: branches: - - master + - '**' push: branches: - - master + - '**' env: RUSTFLAGS: -Dwarnings diff --git a/Cargo.toml b/Cargo.toml index 31a02121..86439a34 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "native-tls" version = "0.2.12" +edition = "2018" authors = ["Steven Fackler "] license = "MIT OR Apache-2.0" description = "A wrapper over a platform's native TLS implementation" From 71f08ce2f682152881ccdf19ddea8861842e90f3 Mon Sep 17 00:00:00 2001 From: ssrlive <30760636+ssrlive@users.noreply.github.com> Date: Sun, 5 Jan 2025 16:50:10 +0800 Subject: [PATCH 4/6] Android test suits --- .github/workflows/ci.yml | 22 ++++++++++++++++++++++ src/imp/schannel.rs | 15 +++++++++------ src/imp/security_framework.rs | 2 +- 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a6f8aacd..522e7426 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -77,3 +77,25 @@ jobs: - name: Abort on error if: ${{ failure() }} run: echo "iOS build job failed" && false + + build_n_test_android: + strategy: + fail-fast: false + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install cargo ndk and rust compiler for android target + if: ${{ !cancelled() }} + run: | + cargo install --locked cargo-ndk + rustup target add x86_64-linux-android + - name: clippy + if: ${{ !cancelled() }} + run: cargo ndk -t x86_64 clippy --features vendored -- -D warnings + - name: Build + if: ${{ !cancelled() }} + run: | + cargo ndk -t x86_64 rustc --verbose --features vendored --lib --crate-type=cdylib + - name: Abort on error + if: ${{ failure() }} + run: echo "Android build job failed" && false diff --git a/src/imp/schannel.rs b/src/imp/schannel.rs index 62e5042f..dd26a5f6 100644 --- a/src/imp/schannel.rs +++ b/src/imp/schannel.rs @@ -10,7 +10,7 @@ use std::fmt; use std::io; use std::str; -use {TlsAcceptorBuilder, TlsConnectorBuilder}; +use crate::{TlsAcceptorBuilder, TlsConnectorBuilder}; const SEC_E_NO_CREDENTIALS: u32 = 0x8009030E; @@ -21,7 +21,10 @@ static PROTOCOLS: &'static [Protocol] = &[ Protocol::Tls12, ]; -fn convert_protocols(min: Option<::Protocol>, max: Option<::Protocol>) -> &'static [Protocol] { +fn convert_protocols( + min: Option, + max: Option, +) -> &'static [Protocol] { let mut protocols = PROTOCOLS; if let Some(p) = max.and_then(|max| protocols.get(..=max as usize)) { protocols = p; @@ -236,8 +239,8 @@ impl From for HandshakeError { pub struct TlsConnector { cert: Option, roots: CertStore, - min_protocol: Option<::Protocol>, - max_protocol: Option<::Protocol>, + min_protocol: Option, + max_protocol: Option, use_sni: bool, accept_invalid_hostnames: bool, accept_invalid_certs: bool, @@ -327,8 +330,8 @@ impl TlsConnector { #[derive(Clone)] pub struct TlsAcceptor { cert: CertContext, - min_protocol: Option<::Protocol>, - max_protocol: Option<::Protocol>, + min_protocol: Option, + max_protocol: Option, } impl TlsAcceptor { diff --git a/src/imp/security_framework.rs b/src/imp/security_framework.rs index b7d79b57..15190ccc 100644 --- a/src/imp/security_framework.rs +++ b/src/imp/security_framework.rs @@ -55,7 +55,7 @@ use self::security_framework::os::macos::import_export::{ )))] use self::security_framework::os::macos::keychain::{self, KeychainSettings, SecKeychain}; -use {Protocol, TlsAcceptorBuilder, TlsConnectorBuilder}; +use crate::{Protocol, TlsAcceptorBuilder, TlsConnectorBuilder}; #[allow(dead_code)] static SET_AT_EXIT: Once = Once::new(); From 9fe8de9cd65922320afedbf9fa0e7d32d090c292 Mon Sep 17 00:00:00 2001 From: ssrlive <30760636+ssrlive@users.noreply.github.com> Date: Fri, 16 May 2025 22:31:44 +0800 Subject: [PATCH 5/6] minor changes --- .github/workflows/ci.yml | 24 ++++-------------------- src/imp/openssl.rs | 4 +--- src/lib.rs | 4 ++-- 3 files changed, 7 insertions(+), 25 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ea5b76ae..a72b5bb7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,8 +18,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: sfackler/actions/rustup@master - - uses: sfackler/actions/rustfmt@master + - uses: dtolnay/rust-toolchain@stable windows: strategy: @@ -32,28 +31,13 @@ jobs: name: test-${{ matrix.os }} runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 - - uses: sfackler/actions/rustup@master - with: - version: 1.80.0 + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable - run: echo "::set-output name=version::$(rustc --version)" id: rust-version - - uses: actions/cache@v1 - with: - path: ~/.cargo/registry/index - key: index-${{ runner.os }}-${{ github.run_number }} - restore-keys: | - index-${{ runner.os }}- - run: cargo generate-lockfile - - uses: actions/cache@v1 - with: - path: ~/.cargo/registry/cache - key: registry-${{ runner.os }}-${{ steps.rust-version.outputs.version }}-${{ hashFiles('Cargo.lock') }} - run: cargo fetch - - uses: actions/cache@v1 - with: - path: target - key: target-${{ runner.os }}-${{ steps.rust-version.outputs.version }}-${{ hashFiles('Cargo.lock') }} + - run: cargo clippy --all-targets -- -D warnings - run: cargo test --features vendored build_n_test_ios: diff --git a/src/imp/openssl.rs b/src/imp/openssl.rs index 0dcde43d..bc3ab74d 100644 --- a/src/imp/openssl.rs +++ b/src/imp/openssl.rs @@ -465,9 +465,7 @@ impl TlsStream { match self.0.shutdown() { Ok(_) => Ok(()), Err(ref e) if e.code() == ssl::ErrorCode::ZERO_RETURN => Ok(()), - Err(e) => Err(e - .into_io_error() - .unwrap_or_else(|e| io::Error::new(io::ErrorKind::Other, e))), + Err(e) => Err(e.into_io_error().unwrap_or_else(io::Error::other)), } } } diff --git a/src/lib.rs b/src/lib.rs index 30c53ff0..ce5ffabf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -35,8 +35,8 @@ //! # Cargo Features //! //! * `vendored` - If enabled, the crate will compile and statically link to a -//! vendored copy of OpenSSL. This feature has no effect on Windows and -//! macOS, where OpenSSL is not used. +//! vendored copy of OpenSSL. This feature has no effect on Windows and +//! macOS, where OpenSSL is not used. //! //! # Examples //! From 6ade8742d985f4b70aecfb4cf23ff015829e96d5 Mon Sep 17 00:00:00 2001 From: ssrlive <30760636+ssrlive@users.noreply.github.com> Date: Fri, 16 May 2025 23:33:22 +0800 Subject: [PATCH 6/6] fix clippy errors --- .github/workflows/ci.yml | 1 + Cargo.toml | 2 +- src/imp/schannel.rs | 21 +++++++++++---------- src/imp/security_framework.rs | 2 +- src/lib.rs | 4 ++++ 5 files changed, 18 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a72b5bb7..7178fc80 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,6 +37,7 @@ jobs: id: rust-version - run: cargo generate-lockfile - run: cargo fetch + - run: cargo fmt --check - run: cargo clippy --all-targets -- -D warnings - run: cargo test --features vendored diff --git a/Cargo.toml b/Cargo.toml index 1007516d..a790c0b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ alpn = ["security-framework/alpn"] have_min_max_version = [] [target.'cfg(target_vendor = "apple")'.dependencies] -security-framework = "2.0.0" +security-framework = "3" security-framework-sys = "2.0.0" libc = "0.2" diff --git a/src/imp/schannel.rs b/src/imp/schannel.rs index dd26a5f6..5ba23db4 100644 --- a/src/imp/schannel.rs +++ b/src/imp/schannel.rs @@ -14,7 +14,7 @@ use crate::{TlsAcceptorBuilder, TlsConnectorBuilder}; const SEC_E_NO_CREDENTIALS: u32 = 0x8009030E; -static PROTOCOLS: &'static [Protocol] = &[ +static PROTOCOLS: &[Protocol] = &[ Protocol::Ssl3, Protocol::Tls10, Protocol::Tls11, @@ -104,7 +104,7 @@ impl Identity { } let mut store = Memory::new()?.into_store(); - let mut cert_iter = pem::PemBlock::new(pem).into_iter(); + let mut cert_iter = pem::PemBlock::new(pem); let leaf = cert_iter.next().ok_or_else(|| { io::Error::new( io::ErrorKind::InvalidInput, @@ -127,7 +127,7 @@ impl Identity { Ok(container) => container, Err(_) => options.new_keyset(true).acquire(type_)?, }; - container.import().import_pkcs8_pem(&key)?; + container.import().import_pkcs8_pem(key)?; cert.set_key_prov_info() .container(&name) @@ -205,6 +205,7 @@ impl MidHandshakeTlsStream where S: io::Read + io::Write, { + #[allow(clippy::result_large_err)] pub fn handshake(self) -> Result, HandshakeError> { match self.0.handshake() { Ok(s) => Ok(TlsStream(s)), @@ -213,6 +214,7 @@ where } } +#[allow(clippy::large_enum_variant)] pub enum HandshakeError { Failure(Error), WouldBlock(MidHandshakeTlsStream), @@ -271,6 +273,7 @@ impl TlsConnector { }) } + #[allow(clippy::result_large_err)] pub fn connect(&self, domain: &str, stream: S) -> Result, HandshakeError> where S: io::Read + io::Write, @@ -292,10 +295,8 @@ impl TlsConnector { } else if self.disable_built_in_roots { let roots_copy = self.roots.clone(); builder.verify_callback(move |res| { - if let Err(err) = res.result() { - // Propagate previous error encountered during normal cert validation. - return Err(err); - } + // Propagate previous error encountered during normal cert validation. + res.result()?; if let Some(chain) = res.chain() { if chain @@ -306,8 +307,7 @@ impl TlsConnector { } } - Err(io::Error::new( - io::ErrorKind::Other, + Err(io::Error::other( "unable to find any user-specified roots in the final cert chain", )) }); @@ -343,6 +343,7 @@ impl TlsAcceptor { }) } + #[allow(clippy::result_large_err)] pub fn accept(&self, stream: S) -> Result, HandshakeError> where S: io::Read + io::Write, @@ -472,7 +473,7 @@ mod pem { Some(end) => end + begin + 1, None => last, }; - return Some(&self.pem_block[begin..self.cur_end].as_bytes()); + Some(&self.pem_block.as_bytes()[begin..self.cur_end]) } } diff --git a/src/imp/security_framework.rs b/src/imp/security_framework.rs index 15190ccc..acbd355e 100644 --- a/src/imp/security_framework.rs +++ b/src/imp/security_framework.rs @@ -153,7 +153,7 @@ impl Identity { let cert = items .certificates - .get(0) + .first() .ok_or_else(|| Error(base::Error::from(errSecParam)))?; let ident = SecIdentity::with_certificate(&[keychain], cert)?; Ok(Identity { diff --git a/src/lib.rs b/src/lib.rs index ce5ffabf..32d7afcf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -246,6 +246,7 @@ where /// Note that the error may not be fatal. For example if the underlying /// stream is an asynchronous one then `HandshakeError::WouldBlock` may /// just mean to wait for more I/O to happen later. + #[allow(clippy::result_large_err)] pub fn handshake(self) -> result::Result, HandshakeError> { match self.0.handshake() { Ok(s) => Ok(TlsStream(s)), @@ -256,6 +257,7 @@ where /// An error returned from `ClientBuilder::handshake`. #[derive(Debug)] +#[allow(clippy::large_enum_variant)] pub enum HandshakeError { /// A fatal error. Failure(Error), @@ -500,6 +502,7 @@ impl TlsConnector { /// /// The domain is ignored if both SNI and hostname verification are /// disabled. + #[allow(clippy::result_large_err)] pub fn connect( &self, domain: &str, @@ -616,6 +619,7 @@ impl TlsAcceptor { /// the handshake, a `HandshakeError::WouldBlock` error will be returned /// which can be used to restart the handshake when the socket is ready /// again. + #[allow(clippy::result_large_err)] pub fn accept(&self, stream: S) -> result::Result, HandshakeError> where S: io::Read + io::Write,