diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 0e12c8ab..ef9a57cc 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -15,13 +15,15 @@ jobs: strategy: fail-fast: false matrix: - make_target: ["check-licenses", "build", "integ"] + make_target: ["check-licenses", "build", "integ", "integ-fips"] os: [ubuntu-latest, windows-latest, macos-latest] exclude: - os: windows-latest make_target: check-licenses - os: macos-latest make_target: check-licenses + - os: macos-latest + make_target: integ-fips runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 @@ -33,6 +35,9 @@ jobs: key: ${{ hashFiles('.github/cache_bust') }}-${{ runner.os }}-${{ matrix.make_target }}-${{ hashFiles('**/Cargo.lock') }} restore-keys: | ${{ hashFiles('.github/cache_bust') }}-${{ runner.os }}-${{ matrix.make_target }} + - uses: ilammy/setup-nasm@v1 # requirement for windows FIPS builds + - name: Install ninja-build tool + uses: seanmiddleditch/gha-setup-ninja@v4 # print the current rustc. replace stable to pin to a specific toolchain version. - run: rustup default stable - run: rustup component add rustfmt diff --git a/Cargo.lock b/Cargo.lock index 72b385e8..13ca81d0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -114,7 +114,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc1835b7f27878de8525dc71410b5a31cdcc5f230aed5ba5df968e09c201b23d" dependencies = [ "anstyle", - "bstr 1.10.0", + "bstr", "doc-comment", "libc", "predicates", @@ -216,12 +216,27 @@ dependencies = [ "zeroize", ] +[[package]] +name = "aws-lc-fips-sys" +version = "0.12.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33d41a5d02120c5eca009507574fa0d4885fa370cbda6b561d91ba463c3025a7" +dependencies = [ + "bindgen", + "cmake", + "dunce", + "fs_extra", + "libc", + "paste", +] + [[package]] name = "aws-lc-rs" version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f95446d919226d587817a7d21379e6eb099b97b45110a7f272a444ca5c54070" dependencies = [ + "aws-lc-fips-sys", "aws-lc-sys", "mirai-annotations", "paste", @@ -575,7 +590,7 @@ dependencies = [ "serde_json", "serde_path_to_error", "serde_urlencoded", - "sync_wrapper", + "sync_wrapper 0.1.2", "tokio", "tower", "tower-layer", @@ -653,7 +668,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "rustc-hash", + "rustc-hash 1.1.0", "shlex", "syn 2.0.77", "which", @@ -700,17 +715,6 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "bstr" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" -dependencies = [ - "lazy_static", - "memchr", - "regex-automata 0.1.10", -] - [[package]] name = "bstr" version = "1.10.0" @@ -1249,7 +1253,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "15f1ce686646e7f1e19bf7d5533fe443a45dbfb990e00629110797578b42fb19" dependencies = [ "aho-corasick", - "bstr 1.10.0", + "bstr", "log", "regex-automata 0.4.7", "regex-syntax 0.8.4", @@ -1433,17 +1437,19 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "httptest" -version = "0.15.5" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8b44a11846bda8c9fe9194f9924db7132c34635c7ce020f180f6c5d46d2308f" +checksum = "ae0fc8d140f1f0f3e7f821c8eff55cd13966db7a3370b2d9a7b08e9ec8ee8786" dependencies = [ - "bstr 0.2.17", + "bstr", "bytes", "crossbeam-channel", "form_urlencoded", "futures", - "http 0.2.12", - "hyper 0.14.30", + "http 1.1.0", + "http-body-util", + "hyper 1.4.1", + "hyper-util", "log", "once_cell", "regex", @@ -1490,6 +1496,7 @@ dependencies = [ "http 1.1.0", "http-body 1.0.1", "httparse", + "httpdate", "itoa", "pin-project-lite", "smallvec", @@ -1848,7 +1855,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b7ab7a9efb5768cd07e2b2455f80b3998d7397be76398c2ac03a52a42b652e7" dependencies = [ "noxious", - "reqwest", + "reqwest 0.11.27", "serde", "thiserror", "tokio", @@ -2153,6 +2160,54 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "quinn" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c7c5fdde3cdae7203427dc4f0a68fe0ed09833edc525a03456b153b79828684" +dependencies = [ + "bytes", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash 2.0.0", + "rustls 0.23.13", + "socket2", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "quinn-proto" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6" +dependencies = [ + "bytes", + "rand", + "ring", + "rustc-hash 2.0.0", + "rustls 0.23.13", + "slab", + "thiserror", + "tinyvec", + "tracing", +] + +[[package]] +name = "quinn-udp" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fe68c2e9e1a1234e218683dbdf9f9dfcb094113c5ac2b938dfcb9bab4c4140b" +dependencies = [ + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.59.0", +] + [[package]] name = "quote" version = "1.0.37" @@ -2277,7 +2332,6 @@ dependencies = [ "http 0.2.12", "http-body 0.4.6", "hyper 0.14.30", - "hyper-rustls 0.24.2", "hyper-tls", "ipnet", "js-sys", @@ -2287,17 +2341,56 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.21.12", - "rustls-native-certs 0.6.3", "rustls-pemfile 1.0.4", "serde", "serde_json", "serde_urlencoded", - "sync_wrapper", + "sync_wrapper 0.1.2", "system-configuration", "tokio", "tokio-native-tls", - "tokio-rustls 0.24.1", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + +[[package]] +name = "reqwest" +version = "0.12.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f713147fbe92361e52392c73b8c9e48c04c6625bce969ef54dc901e58e042a7b" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-core", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", + "http-body-util", + "hyper 1.4.1", + "hyper-rustls 0.27.3", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls 0.23.13", + "rustls-native-certs 0.8.0", + "rustls-pemfile 2.1.3", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 1.0.1", + "tokio", + "tokio-rustls 0.26.0", "tokio-util 0.7.12", "tower-service", "url", @@ -2305,7 +2398,7 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "winreg", + "windows-registry", ] [[package]] @@ -2344,6 +2437,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustc-hash" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" + [[package]] name = "rustc_version" version = "0.4.1" @@ -2385,7 +2484,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8" dependencies = [ "aws-lc-rs", + "log", "once_cell", + "ring", "rustls-pki-types", "rustls-webpki 0.102.8", "subtle", @@ -2760,6 +2861,15 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +[[package]] +name = "sync_wrapper" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +dependencies = [ + "futures-core", +] + [[package]] name = "system-configuration" version = "0.5.1" @@ -3030,7 +3140,8 @@ dependencies = [ "olpc-cjson", "pem", "percent-encoding", - "reqwest", + "reqwest 0.12.8", + "rustls 0.23.13", "serde", "serde_json", "serde_plain", @@ -3244,7 +3355,8 @@ dependencies = [ "maplit", "olpc-cjson", "rayon", - "reqwest", + "reqwest 0.12.8", + "rustls 0.23.13", "serde", "serde_json", "simplelog", @@ -3541,6 +3653,36 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-registry" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +dependencies = [ + "windows-result", + "windows-strings", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.48.0" diff --git a/Makefile b/Makefile index 55bf5325..24ece291 100644 --- a/Makefile +++ b/Makefile @@ -42,4 +42,10 @@ noxious: integ: noxious set +e cargo test --manifest-path tough/Cargo.toml --features '' --locked + cargo test --manifest-path tough/Cargo.toml --features 'http' --features 'integ' --locked + +# tests tough fips features with and without the http feature. +integ-fips: noxious + set +e + cargo test --manifest-path tough/Cargo.toml --features 'fips' --locked cargo test --manifest-path tough/Cargo.toml --all-features --locked diff --git a/deny.toml b/deny.toml index 39f7a7c1..e21ecaaf 100644 --- a/deny.toml +++ b/deny.toml @@ -90,8 +90,10 @@ skip = [ ] skip-tree = [ - # reqwest is using several older dependencies + # noxious-client is using an older version of reqwest { name = "reqwest", version = "=0.11" }, + # aws-smithy-runtime-experimental is using several newer dependencies + { name = "aws-smithy-experimental", version = "=0.1" }, ] [sources] diff --git a/tough-kms/Cargo.toml b/tough-kms/Cargo.toml index f2cd4f56..43cb055d 100644 --- a/tough-kms/Cargo.toml +++ b/tough-kms/Cargo.toml @@ -12,10 +12,11 @@ edition = "2018" default = ["aws-sdk-rust"] aws-sdk-rust = ["aws-sdk-rust-rustls"] aws-sdk-rust-rustls = ["aws-config/rustls", "aws-sdk-kms/rustls"] +fips = ["aws-lc-rs/fips", "tough/fips"] [dependencies] tough = { version = "0.18", path = "../tough", features = ["http"] } -aws-lc-rs = { version = "1", features = ["prebuilt-nasm"] } +aws-lc-rs = "1" aws-sdk-kms = "1" aws-config = { version = "1", default-features = false, features = ["credentials-process"] } aws-smithy-experimental = { version = "0.1", features = ["crypto-aws-lc"] } diff --git a/tough-ssm/Cargo.toml b/tough-ssm/Cargo.toml index f7cdd58c..5fd090af 100644 --- a/tough-ssm/Cargo.toml +++ b/tough-ssm/Cargo.toml @@ -12,6 +12,7 @@ edition = "2018" default = ["aws-sdk-rust"] aws-sdk-rust = ["aws-sdk-rust-rustls"] aws-sdk-rust-rustls = ["aws-config/rustls", "aws-sdk-ssm/rustls"] +fips = ["tough/fips"] [dependencies] tough = { version = "0.18", path = "../tough", features = ["http"] } diff --git a/tough/Cargo.toml b/tough/Cargo.toml index ffa6f05d..053662b7 100644 --- a/tough/Cargo.toml +++ b/tough/Cargo.toml @@ -11,7 +11,7 @@ edition = "2018" [dependencies] async-recursion = "1" async-trait = "0.1" -aws-lc-rs = { version = "1", features = ["prebuilt-nasm"] } +aws-lc-rs = "1" bytes = "1" chrono = { version = "0.4", default-features = false, features = ["std", "alloc", "serde", "clock"] } dyn-clone = "1" @@ -23,7 +23,8 @@ log = "0.4" olpc-cjson = { version = "0.1", path = "../olpc-cjson" } pem = "3" percent-encoding = "2" -reqwest = { version = "0.11", optional = true, default-features = false, features = ["stream"] } +reqwest = { version = "0.12", optional = true, default-features = false, features = ["stream"] } +rustls = "0.23" serde = { version = "1", features = ["derive"] } serde_json = "1" serde_plain = "1" @@ -41,12 +42,13 @@ walkdir = "2" [dev-dependencies] failure-server = { path = "../integ/failure-server" } hex-literal = "0.4" -httptest = "0.15" +httptest = "0.16" maplit = "1" tokio = { version = "1", features = ["macros", "rt", "rt-multi-thread"] } tokio-test = "0.4" [features] +fips = ["aws-lc-rs/fips", "rustls/fips"] http = ["reqwest"] # The `integ` feature enables integration tests. These tests require `noxious-server` to be installed on the host. diff --git a/tough/src/http.rs b/tough/src/http.rs index 4fbf2fa0..dcb28bc1 100644 --- a/tough/src/http.rs +++ b/tough/src/http.rs @@ -11,6 +11,7 @@ use log::trace; use reqwest::header::{self, HeaderValue, ACCEPT_RANGES}; use reqwest::{Client, ClientBuilder, Request, Response}; use reqwest::{Error, Method}; +use rustls::crypto::{aws_lc_rs, CryptoProvider}; use snafu::ResultExt; use snafu::Snafu; use std::cmp::Ordering; @@ -45,6 +46,14 @@ pub struct HttpTransportBuilder { impl Default for HttpTransportBuilder { fn default() -> Self { + // Set the aws_lc_rs CryptoProvider for rustls. This is to ensure that the reqwest client + // is using a FIPS enabled aws_lc_rs when creating a client. Otherwise, ring is used: + // https://github.com/seanmonstar/reqwest/blob/d85f44b217f36f8bef065fe95877eab98c52c2e5/src/async_impl/client.rs#L577-L587 + // This can be called successfully at most once in any process execution: https://docs.rs/rustls/latest/rustls/crypto/struct.CryptoProvider.html#method.install_default + // The return type is Result<(), Arc>, which can be dropped. + if CryptoProvider::get_default().is_none() { + let _ = aws_lc_rs::default_provider().install_default(); + } Self { timeout: std::time::Duration::from_secs(30), connect_timeout: std::time::Duration::from_secs(10), @@ -322,7 +331,6 @@ impl RetryStream { &mut self, cx: &mut std::task::Context<'_>, ) -> Result>>, HttpError> { - // create a reqwest client let client = ClientBuilder::new() .timeout(self.settings.timeout) .connect_timeout(self.settings.connect_timeout) diff --git a/tuftool/Cargo.toml b/tuftool/Cargo.toml index 811038d4..7bbf1524 100644 --- a/tuftool/Cargo.toml +++ b/tuftool/Cargo.toml @@ -13,10 +13,11 @@ integ = [] default = ["aws-sdk-rust"] aws-sdk-rust = ["aws-sdk-rust-rustls"] aws-sdk-rust-rustls = ["aws-config/rustls", "aws-sdk-ssm/rustls", "aws-sdk-kms/rustls", ] +fips = ["tough/fips", "rustls/fips"] [dependencies] aws-config = { version = "1", default-features = false, features = ["credentials-process"] } -aws-lc-rs = { version = "1", features = ["prebuilt-nasm"] } +aws-lc-rs = "1" aws-sdk-kms = "1" aws-sdk-ssm = "1" chrono = { version = "0.4", default-features = false, features = ["alloc", "std", "clock"] } @@ -27,7 +28,8 @@ log = "0.4" maplit = "1" olpc-cjson = { version = "0.1", path = "../olpc-cjson" } rayon = "1" -reqwest = { version = "0.11", default-features = false, features = ["rustls-tls-native-roots"] } +reqwest = { version = "0.12", default-features = false, features = ["rustls-tls-native-roots"] } +rustls = "0.23" serde = "1" serde_json = "1" simplelog = "0.12" @@ -44,4 +46,4 @@ walkdir = "2" assert_cmd = "2" futures = "0.3" futures-core = "0.3" -httptest = "0.15" +httptest = "0.16"