diff --git a/.travis.yml b/.travis.yml index c88f97024..fda8cdd07 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ branches: - trying # Not really necessary, just to get a green badge on “master” - master + - v0.8 language: rust os: linux dist: focal @@ -18,14 +19,16 @@ addons: - clang-11 - cmake - qemu-user -rust: - - stable +before_script: + - printenv + - whereis clang && clang --version + # remove clang-16 path from PATH + - export PATH=$(echo $PATH | sed -e 's|:/usr/local/clang-16.0.0/bin||') + # setup clang-11 as default clang + - sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-11 100 + - whereis clang && clang --version + env: - jobs: - # Matrix build of 3 targets against Rust stable - - TARGET=x86_64-unknown-linux-gnu ZLIB_INSTALLED=true AES_NI_SUPPORT=true - - TARGET=aarch64-unknown-linux-musl - - TARGET=x86_64-fortanix-unknown-sgx global: - RUST_BACKTRACE=1 # Pinned to this particular nightly version because of core_io. This can be @@ -33,9 +36,17 @@ env: - CORE_IO_NIGHTLY=nightly-2021-03-25 jobs: include: - # Test additional Rust toolchains on x86_64 - - rust: beta - - rust: nightly - - rust: nightly-2021-03-25 + - env: TARGET=x86_64-unknown-linux-gnu ZLIB_INSTALLED=true AES_NI_SUPPORT=true + rust: nightly-2021-03-25 + - env: TARGET=x86_64-fortanix-unknown-sgx + rust: stable + - env: TARGET=aarch64-unknown-linux-musl + rust: stable + - env: TARGET=x86_64-unknown-linux-gnu ZLIB_INSTALLED=true AES_NI_SUPPORT=true + rust: nightly + - env: TARGET=x86_64-unknown-linux-gnu ZLIB_INSTALLED=true AES_NI_SUPPORT=true + rust: beta + - env: TARGET=x86_64-unknown-linux-gnu ZLIB_INSTALLED=true AES_NI_SUPPORT=true + rust: stable script: - ./ct.sh diff --git a/Cargo.lock b/Cargo.lock index f7406b3ef..4c1a4d139 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -383,7 +383,7 @@ checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" [[package]] name = "mbedtls" -version = "0.8.3" +version = "0.8.4" dependencies = [ "bit-vec", "bitflags", diff --git a/mbedtls/Cargo.toml b/mbedtls/Cargo.toml index ab53ae989..635665be8 100644 --- a/mbedtls/Cargo.toml +++ b/mbedtls/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mbedtls" -version = "0.8.3" +version = "0.8.4" authors = ["Jethro Beekman "] build = "build.rs" edition = "2018" diff --git a/mbedtls/src/ssl/config.rs b/mbedtls/src/ssl/config.rs index 3cb8bfa9d..4aa15748c 100644 --- a/mbedtls/src/ssl/config.rs +++ b/mbedtls/src/ssl/config.rs @@ -252,6 +252,9 @@ impl Config { } pub fn push_cert(&mut self, own_cert: Arc>, own_pk: Arc) -> Result<()> { + if own_cert.is_empty() { + return Err(Error::SslBadInputData); + } // Need to ensure own_cert/pk_key outlive the config. self.own_cert.push(own_cert.clone()); self.own_pk.push(own_pk.clone()); diff --git a/mbedtls/src/ssl/context.rs b/mbedtls/src/ssl/context.rs index f40a31f15..126bfa28d 100644 --- a/mbedtls/src/ssl/context.rs +++ b/mbedtls/src/ssl/context.rs @@ -350,7 +350,7 @@ impl<'ctx> HandshakeContext<'ctx> { key: Arc, ) -> Result<()> { // mbedtls_ssl_set_hs_own_cert does not check for NULL handshake. - if self.context.inner.handshake as *const _ == ::core::ptr::null() { + if self.context.inner.handshake as *const _ == ::core::ptr::null() || chain.is_empty() { return Err(Error::SslBadInputData); } diff --git a/mbedtls/src/x509/certificate.rs b/mbedtls/src/x509/certificate.rs index 9e14cb3af..a3b576c8c 100644 --- a/mbedtls/src/x509/certificate.rs +++ b/mbedtls/src/x509/certificate.rs @@ -228,6 +228,9 @@ impl Certificate { where F: VerifyCallback + 'static, { + if chain.is_empty() { + return Err(Error::X509BadInputData); + } let (f_vrfy, p_vrfy): (Option _>, _) = if let Some(cb) = cb.as_ref() { (Some(x509::verify_callback::), cb as *const _ as *mut c_void) @@ -1034,7 +1037,59 @@ cYp0bH/RcPTC0Z+ZaqSWMtfxRrk63MJQF9EXpDCdvQRcTMD9D85DJrMKn8aumq0M Err(e) => panic!("Failed to verify, error: {}, err_str: {}", e, err_str), }; } - + + #[test] + fn empty_cert_chain_test() { + const C_LEAF: &'static str = concat!(include_str!("../../tests/data/chain-leaf.crt"),"\0"); + const C_INT1: &'static str = concat!(include_str!("../../tests/data/chain-int1.crt"),"\0"); + const C_INT2: &'static str = concat!(include_str!("../../tests/data/chain-int2.crt"),"\0"); + const C_ROOT: &'static str = concat!(include_str!("../../tests/data/chain-root.crt"),"\0"); + + let c_leaf = Certificate::from_pem(C_LEAF.as_bytes()).unwrap(); + let c_int1 = Certificate::from_pem(C_INT1.as_bytes()).unwrap(); + let c_int2 = Certificate::from_pem(C_INT2.as_bytes()).unwrap(); + let c_root = Certificate::from_pem_multiple(C_ROOT.as_bytes()).unwrap(); + + // Certificate C_INT2 is missing at the beginning so the verification should fail at first + let mut chain = MbedtlsList::::new(); + chain.push(c_leaf.clone()); + chain.push(c_int1.clone()); + chain.push(c_int2.clone()); + + // The certificates used for this test are expired so we remove the CERT_EXPIRED flag with the callback + let verify_callback = |_crt: &Certificate, _depth: i32, verify_flags: &mut VerifyError| { + verify_flags.remove(VerifyError::CERT_EXPIRED); + Ok(()) + }; + + let mut err_str = String::new(); + + let res = Certificate::verify_with_callback(&chain, &c_root, Some(&mut err_str), verify_callback); + + match res { + Ok(()) => (), + Err(e) => panic!("Failed to verify, error: {}, err_str: {}", e, err_str), + }; + + let empty_certs = MbedtlsList::::new(); + assert_eq!( + Certificate::verify(&empty_certs, &empty_certs, None).unwrap_err(), + Error::X509BadInputData + ); + assert_eq!( + Certificate::verify_with_callback(&empty_certs, &empty_certs, Some(&mut err_str), verify_callback).unwrap_err(), + Error::X509BadInputData + ); + assert_eq!( + Certificate::verify_with_callback(&chain, &empty_certs, Some(&mut err_str), verify_callback).unwrap_err(), + Error::X509CertVerifyFailed + ); + assert_eq!( + Certificate::verify_with_callback(&empty_certs, &c_root, Some(&mut err_str), verify_callback).unwrap_err(), + Error::X509BadInputData + ); + } + #[test] fn clone_test() { let cert_chain = Certificate::from_pem(TEST_CERT_PEM.as_bytes()).unwrap();