diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index a2bf9be14..e8404bd58 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -795,6 +795,17 @@ jobs: rustflags: "" cache-workspaces: "./libs -> ./target" - uses: taiki-e/install-action@cargo-hack + - name: Install NASM for aws-lc-rs on Windows + if: runner.os == 'Windows' + uses: ilammy/setup-nasm@v1 + - name: Install ninja-build tool for aws-lc-fips-sys on Windows + if: runner.os == 'Windows' + uses: seanmiddleditch/gha-setup-ninja@v6 + - name: Install golang for aws-lc-fips-sys on macos + if: runner.os == 'MacOS' + uses: actions/setup-go@v6 + with: + go-version: "1.25.0" - name: Download pavex CLI artifact uses: actions/download-artifact@v4 with: @@ -820,8 +831,16 @@ jobs: pavexc self setup - name: Run Pavex tests with multiple feature combinations working-directory: libs + if: runner.os != 'Windows' run: | cargo hack -p pavex --feature-powerset --depth 2 test --tests + - name: Run Pavex tests with multiple feature combinations + working-directory: libs + if: runner.os == 'Windows' + run: | + # FIPS only builds in `release` mode on Windows + cargo hack -p pavex --feature-powerset --exclude-features="fips" --depth 2 test --tests + cargo test -p pavex --release --tests --features fips,tls_crypto_provider_aws_lc_rs - uses: ./.github/actions/finalize-check if: ${{ always() && github.event_name != 'push' }} with: @@ -1114,6 +1133,17 @@ jobs: rustflags: "" cache-workspaces: "./libs -> ./target" - uses: taiki-e/install-action@cargo-hack + - name: Install NASM for aws-lc-rs on Windows + if: runner.os == 'Windows' + uses: ilammy/setup-nasm@v1 + - name: Install ninja-build tool for aws-lc-fips-sys on Windows + if: runner.os == 'Windows' + uses: seanmiddleditch/gha-setup-ninja@v6 + - name: Install golang for aws-lc-fips-sys on macos + if: runner.os == 'MacOS' + uses: actions/setup-go@v6 + with: + go-version: "1.25.0" - name: Download pavex CLI artifact uses: actions/download-artifact@v4 with: @@ -1139,8 +1169,16 @@ jobs: pavexc self setup - name: Run Pavex tests with multiple feature combinations working-directory: libs + if: runner.os != 'Windows' run: | cargo hack -p pavex --feature-powerset --depth 2 test --tests + - name: Run Pavex tests with multiple feature combinations + working-directory: libs + if: runner.os == 'Windows' + run: | + # FIPS only builds in `release` mode on Windows + cargo hack -p pavex --feature-powerset --exclude-features="fips" --depth 2 test --tests + cargo test -p pavex --release --tests --features fips,tls_crypto_provider_aws_lc_rs - uses: ./.github/actions/finalize-check if: ${{ always() && github.event_name != 'push' }} with: @@ -1427,6 +1465,17 @@ jobs: rustflags: "" cache-workspaces: "./libs -> ./target" - uses: taiki-e/install-action@cargo-hack + - name: Install NASM for aws-lc-rs on Windows + if: runner.os == 'Windows' + uses: ilammy/setup-nasm@v1 + - name: Install ninja-build tool for aws-lc-fips-sys on Windows + if: runner.os == 'Windows' + uses: seanmiddleditch/gha-setup-ninja@v6 + - name: Install golang for aws-lc-fips-sys on macos + if: runner.os == 'MacOS' + uses: actions/setup-go@v6 + with: + go-version: "1.25.0" - name: Download pavex CLI artifact uses: actions/download-artifact@v4 with: @@ -1446,8 +1495,16 @@ jobs: pavexc self setup - name: Run Pavex tests with multiple feature combinations working-directory: libs + if: runner.os != 'Windows' run: | cargo hack -p pavex --feature-powerset --depth 2 test --tests + - name: Run Pavex tests with multiple feature combinations + working-directory: libs + if: runner.os == 'Windows' + run: | + # FIPS only builds in `release` mode on Windows + cargo hack -p pavex --feature-powerset --exclude-features="fips" --depth 2 test --tests + cargo test -p pavex --release --tests --features fips,tls_crypto_provider_aws_lc_rs - uses: ./.github/actions/finalize-check if: ${{ always() && github.event_name != 'push' }} with: diff --git a/ci_utils/templates/job_steps/pavex_tests.jinja b/ci_utils/templates/job_steps/pavex_tests.jinja index 5819927a1..533e7b699 100644 --- a/ci_utils/templates/job_steps/pavex_tests.jinja +++ b/ci_utils/templates/job_steps/pavex_tests.jinja @@ -7,9 +7,28 @@ rustflags: "" cache-workspaces: "./libs -> ./target" - uses: taiki-e/install-action@cargo-hack +- name: Install NASM for aws-lc-rs on Windows + if: runner.os == 'Windows' + uses: ilammy/setup-nasm@v1 +- name: Install ninja-build tool for aws-lc-fips-sys on Windows + if: runner.os == 'Windows' + uses: seanmiddleditch/gha-setup-ninja@v6 +- name: Install golang for aws-lc-fips-sys on macos + if: runner.os == 'MacOS' + uses: actions/setup-go@v6 + with: + go-version: "1.25.0" <% include 'setup_pavex' %> - name: Run Pavex tests with multiple feature combinations working-directory: libs + if: runner.os != 'Windows' run: | cargo hack -p pavex --feature-powerset --depth 2 test --tests +- name: Run Pavex tests with multiple feature combinations + working-directory: libs + if: runner.os == 'Windows' + run: | + # FIPS only builds in `release` mode on Windows + cargo hack -p pavex --feature-powerset --exclude-features="fips" --depth 2 test --tests + cargo test -p pavex --release --tests --features fips,tls_crypto_provider_aws_lc_rs <%- endblock %> diff --git a/libs/Cargo.lock b/libs/Cargo.lock index 19d755eff..4668666ff 100644 --- a/libs/Cargo.lock +++ b/libs/Cargo.lock @@ -4,9 +4,9 @@ version = 4 [[package]] name = "addr2line" -version = "0.24.2" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" dependencies = [ "gimli", ] @@ -107,9 +107,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anstyle-parse" @@ -142,9 +142,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.99" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "anymap2" @@ -229,6 +229,46 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +[[package]] +name = "aws-lc-fips-sys" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e78aabce84ab79501f4777e89cdcaec2a6ba9b051e6e6f26496598a84215c26" +dependencies = [ + "bindgen", + "cc", + "cmake", + "dunce", + "fs_extra", + "libloading", + "regex", +] + +[[package]] +name = "aws-lc-rs" +version = "1.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879b6c89592deb404ba4dc0ae6b58ffd1795c78991cbb5b8bc441c48a070440d" +dependencies = [ + "aws-lc-fips-sys", + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2b715a6010afb9e457ca2b7c9d2b9c344baa8baed7b38dc476034c171b32575" +dependencies = [ + "bindgen", + "cc", + "cmake", + "dunce", + "fs_extra", + "libloading", +] + [[package]] name = "backon" version = "1.5.2" @@ -240,9 +280,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.75" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" dependencies = [ "addr2line", "cfg-if", @@ -250,7 +290,7 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-targets 0.52.6", + "windows-link", ] [[package]] @@ -316,6 +356,26 @@ dependencies = [ "virtue", ] +[[package]] +name = "bindgen" +version = "0.72.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" +dependencies = [ + "bitflags 2.9.4", + "cexpr", + "clang-sys", + "itertools 0.13.0", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", +] + [[package]] name = "biscotti" version = "0.4.3" @@ -343,9 +403,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.3" +version = "2.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34efbcccd345379ca2868b2b2c9d3782e9cc58ba87bc7d79d5b53d9c9ae6f25d" +checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" dependencies = [ "serde", ] @@ -395,11 +455,11 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "camino" -version = "1.1.11" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d07aa9a93b00c76f71bc35d598bed923f6d4f3a9ca5c24b7737ae1a292841c0" +checksum = "276a59bf2b2c967788139340c9f0c5b12d7fd6630315c15c217e559de85d2609" dependencies = [ - "serde", + "serde_core", ] [[package]] @@ -429,7 +489,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d8af896b707212cd0e99c112a78c9497dd32994192a463ed2f7419d29bd8c6" dependencies = [ "serde", - "thiserror 2.0.16", + "thiserror 2.0.17", "toml 0.8.23", ] @@ -442,6 +502,15 @@ dependencies = [ "serde", ] +[[package]] +name = "cargo-platform" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "122ec45a44b270afd1402f351b782c676b173e3c3fb28d86ff7ebfb4d86a4ee4" +dependencies = [ + "serde", +] + [[package]] name = "cargo-util-schemas" version = "0.8.2" @@ -452,7 +521,7 @@ dependencies = [ "serde", "serde-untagged", "serde-value", - "thiserror 2.0.16", + "thiserror 2.0.17", "toml 0.8.23", "unicode-xid", "url", @@ -465,28 +534,61 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5cfca2aaa699835ba88faf58a06342a314a950d2b9686165e038286c30316868" dependencies = [ "camino", - "cargo-platform", + "cargo-platform 0.2.0", + "cargo-util-schemas", + "semver", + "serde", + "serde_json", + "thiserror 2.0.17", +] + +[[package]] +name = "cargo_metadata" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3f56c207c76c07652489840ff98687dcf213de178ac0974660d6fefeaf5ec6" +dependencies = [ + "camino", + "cargo-platform 0.3.1", "cargo-util-schemas", "semver", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] name = "cc" -version = "1.2.34" +version = "1.2.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42bc4aea80032b7bf409b0bc7ccad88853858911b7713a8062fdc0623867bedc" +checksum = "e1354349954c6fc9cb0deab020f27f783cf0b604e8bb754dc4658ecf0d29c35f" dependencies = [ + "find-msvc-tools", + "jobserver", + "libc", "shlex", ] +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + [[package]] name = "cfg-expr" -version = "0.20.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8d458d63f0f0f482c8da9b7c8b76c21bd885a02056cc94c6404d861ca2b8206" +checksum = "1a2c5f3bf25ec225351aa1c8e230d04d880d3bd89dea133537dafad4ae291e5c" dependencies = [ "smallvec", "target-lexicon", @@ -514,11 +616,22 @@ dependencies = [ "inout", ] +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + [[package]] name = "clap" -version = "4.5.45" +version = "4.5.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc0e74a703892159f5ae7d3aac52c8e6c392f5ae5f359c70b5881d60aaac318" +checksum = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae" dependencies = [ "clap_builder", "clap_derive", @@ -530,14 +643,14 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1101d998d15574d862ee282bcb93e0cf2d192c2fb12338dec35daa91425769a9" dependencies = [ - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] name = "clap_builder" -version = "4.5.44" +version = "4.5.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3e7f4214277f3c7aa526a59dd3fbe306a370daee1f8b7b8c987069cd8e888a8" +checksum = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9" dependencies = [ "anstream", "anstyle", @@ -547,9 +660,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.45" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14cb31bb0a7d536caef2639baa7fad459e15c3144efefa6dbd1c84562c4739f6" +checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c" dependencies = [ "heck", "proc-macro2", @@ -563,6 +676,15 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" +[[package]] +name = "cmake" +version = "0.1.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" +dependencies = [ + "cc", +] + [[package]] name = "colorchoice" version = "1.0.4" @@ -594,9 +716,9 @@ dependencies = [ [[package]] name = "config" -version = "0.15.14" +version = "0.15.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa4092bf3922a966e2bd74640b80f36c73eaa7251a4fd0fbcda1f8a4de401352" +checksum = "180e549344080374f9b32ed41bf3b6b57885ff6a289367b3dbc10eea8acc1918" dependencies = [ "async-trait", "convert_case 0.6.0", @@ -604,10 +726,10 @@ dependencies = [ "pathdiff", "ron 0.8.1", "rust-ini", - "serde", "serde-untagged", + "serde_core", "serde_json", - "toml 0.9.5", + "toml 0.9.7", "winnow", "yaml-rust2", ] @@ -626,15 +748,15 @@ dependencies = [ [[package]] name = "console" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e09ced7ebbccb63b4c65413d821f2e00ce54c5ca4514ddc6b3c892fdbcbc69d" +checksum = "b430743a6eb14e9764d4260d4c0d8123087d504eeb9c48f2b2a5e810dd369df4" dependencies = [ "encode_unicode", "libc", "once_cell", "unicode-width 0.2.1", - "windows-sys 0.60.2", + "windows-sys 0.61.1", ] [[package]] @@ -710,6 +832,22 @@ dependencies = [ "url", ] +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + [[package]] name = "cpufeatures" version = "0.2.17" @@ -890,9 +1028,9 @@ checksum = "ffe7ed1d93f4553003e20b629abe9085e1e81b1429520f897f8f8860bc6dfc21" [[package]] name = "deflate64" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da692b8d1080ea3045efaab14434d40468c3d8657e42abddfffca87b428f4c1b" +checksum = "26bf8fc351c5ed29b5c2f0cbbac1b209b74f60ecd62e675a998df72c49af5204" [[package]] name = "der" @@ -907,9 +1045,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.4.0" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +checksum = "a41953f86f8a05768a6cda24def994fd2f424b04ec5c719cf89989779f199071" dependencies = [ "powerfmt", ] @@ -1003,6 +1141,12 @@ version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "either" version = "1.15.0" @@ -1044,22 +1188,23 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "erased-serde" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e004d887f51fcb9fef17317a2f3525c887d8aa3f4f50fed920816a688284a5b7" +checksum = "259d404d09818dec19332e31d94558aeb442fea04c817006456c24b5460bbd4b" dependencies = [ "serde", + "serde_core", "typeid", ] [[package]] name = "errno" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.1", ] [[package]] @@ -1134,6 +1279,12 @@ dependencies = [ "windows-sys 0.60.2", ] +[[package]] +name = "find-msvc-tools" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ced73b1dacfc750a6db6c0a0c3a3853c8b41997e2e2c563dc90804ae6867959" + [[package]] name = "fixedbitset" version = "0.5.7" @@ -1184,9 +1335,9 @@ dependencies = [ [[package]] name = "fs-err" -version = "3.1.1" +version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d7be93788013f265201256d58f04936a8079ad5dc898743aa20525f503b683" +checksum = "44f150ffc8782f35521cec2b23727707cb4045706ba3c854e86bef66b3a8cdbd" dependencies = [ "autocfg", ] @@ -1205,6 +1356,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + [[package]] name = "futures" version = "0.3.31" @@ -1319,7 +1476,7 @@ dependencies = [ "regex", "sanitize-filename", "tempfile", - "toml 0.9.5", + "toml 0.9.7", "tracing", "walkdir", ] @@ -1357,15 +1514,15 @@ dependencies = [ "js-sys", "libc", "r-efi", - "wasi 0.14.2+wasi-0.2.4", + "wasi 0.14.7+wasi-0.2.4", "wasm-bindgen", ] [[package]] name = "gimli" -version = "0.31.1" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" [[package]] name = "glob" @@ -1392,7 +1549,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "ignore", "walkdir", ] @@ -1422,19 +1579,19 @@ dependencies = [ [[package]] name = "guppy" -version = "0.17.20" +version = "0.17.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eadc0c380d2c5f421758a5838ce593687da4a47d1dcf1169bf3bad629b764e7" +checksum = "41ae4d3577acdf296abfed57f2f391137b545f445d9a6e3600c0a40815872e31" dependencies = [ "ahash", "camino", - "cargo_metadata", + "cargo_metadata 0.22.0", "cfg-if", "debug-ignore", "fixedbitset", "guppy-workspace-hack", "indexmap", - "itertools", + "itertools 0.14.0", "nested", "once_cell", "pathdiff", @@ -1492,6 +1649,12 @@ dependencies = [ "foldhash", ] +[[package]] +name = "hashbrown" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" + [[package]] name = "hashlink" version = "0.9.1" @@ -1643,9 +1806,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e" +checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" dependencies = [ "base64 0.22.1", "bytes", @@ -1815,13 +1978,14 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.11.0" +version = "2.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9" +checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" dependencies = [ "equivalent", - "hashbrown 0.15.5", + "hashbrown 0.16.0", "serde", + "serde_core", ] [[package]] @@ -1830,7 +1994,7 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70a646d946d06bedbbc4cac4c218acf4bbf2d87757a784857025f4d447e4e1cd" dependencies = [ - "console 0.16.0", + "console 0.16.1", "portable-atomic", "unicode-width 0.2.1", "unit-prefix", @@ -1854,9 +2018,9 @@ dependencies = [ [[package]] name = "insta" -version = "1.43.1" +version = "1.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "154934ea70c58054b556dd430b99a98c2a7ff5309ac9891597e339b5c28f4371" +checksum = "46fdb647ebde000f43b5b53f773c30cf9b0cb4300453208713fa38b2c70935a0" dependencies = [ "console 0.15.11", "once_cell", @@ -1881,7 +2045,7 @@ version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "cfg-if", "libc", ] @@ -1914,6 +2078,15 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.14.0" @@ -1981,11 +2154,43 @@ dependencies = [ "jiff-tzdb", ] +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror 1.0.69", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jobserver" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.3", + "libc", +] + [[package]] name = "js-sys" -version = "0.3.77" +version = "0.3.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305" dependencies = [ "once_cell", "wasm-bindgen", @@ -2044,9 +2249,19 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.175" +version = "0.2.176" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" +checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174" + +[[package]] +name = "libloading" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" +dependencies = [ + "cfg-if", + "windows-targets 0.53.4", +] [[package]] name = "libm" @@ -2056,11 +2271,11 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libredox" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3" +checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "libc", "redox_syscall 0.5.17", ] @@ -2090,9 +2305,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.9.4" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "liquid" @@ -2113,7 +2328,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc623edee8a618b4543e8e8505584f4847a4e51b805db1af6d9af0a3395d0d57" dependencies = [ "anymap2", - "itertools", + "itertools 0.14.0", "kstring", "liquid-derive", "pest", @@ -2140,7 +2355,7 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9befeedd61f5995bc128c571db65300aeb50d62e4f0542c88282dbcb5f72372a" dependencies = [ - "itertools", + "itertools 0.14.0", "liquid-core", "percent-encoding", "regex", @@ -2172,9 +2387,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.27" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" [[package]] name = "lru-slab" @@ -2230,9 +2445,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "miette" @@ -2270,6 +2485,12 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.8.9" @@ -2302,19 +2523,29 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "cfg-if", "cfg_aliases", "libc", ] +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "normpath" -version = "1.3.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8911957c4b1549ac0dc74e30db9c8b0e66ddcd6d7acc33098f4c63a64a6d7ed" +checksum = "bf23ab2b905654b4cb177e30b629937b3868311d4e1cba859f899c041046e69b" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.1", ] [[package]] @@ -2410,9 +2641,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.7" +version = "0.37.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" dependencies = [ "memchr", ] @@ -2444,6 +2675,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + [[package]] name = "ordered-float" version = "2.10.1" @@ -2465,9 +2702,9 @@ dependencies = [ [[package]] name = "owo-colors" -version = "4.2.2" +version = "4.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48dd4f4a2c8405440fd0462561f0e5806bd0f77e86f51c761481bdd4018b545e" +checksum = "9c6901729fa79e91a0913333229e9ca5dc725089d1c363b2f4b4760709dc4a52" [[package]] name = "parking" @@ -2574,7 +2811,7 @@ dependencies = [ "hyper-util", "indexmap", "insta", - "itertools", + "itertools 0.14.0", "jiff", "matchit", "mime", @@ -2588,14 +2825,17 @@ dependencies = [ "pin-project-lite", "reqwest", "ron 0.10.1", + "rustls", + "rustls-platform-verifier", "secrecy", "serde", "serde_html_form", "serde_json", "serde_path_to_error", + "serde_yaml", "smallvec", "socket2 0.6.0", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tracing", "tracing_log_error", @@ -2628,7 +2868,7 @@ dependencies = [ "guppy", "hex", "http", - "itertools", + "itertools 0.14.0", "jiff", "jsonwebtoken", "libc", @@ -2658,9 +2898,9 @@ dependencies = [ "supports-color", "tar", "tempfile", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", - "toml 0.9.5", + "toml 0.9.7", "tracing", "tracing-chrome", "tracing-subscriber", @@ -2679,7 +2919,7 @@ version = "0.2.7" dependencies = [ "anyhow", "pavex", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] @@ -2690,7 +2930,7 @@ dependencies = [ "cargo-like-utils", "miette", "pavex_cli_shell", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] @@ -2699,7 +2939,7 @@ version = "0.2.7" dependencies = [ "anyhow", "miette", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] @@ -2767,14 +3007,14 @@ dependencies = [ "async-trait", "googletest", "insta", - "itertools", + "itertools 0.14.0", "pavex", "pavex_session_memory_store", "pavex_tracing", "serde", "serde_json", "static_assertions", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tracing", "uuid", @@ -2833,12 +3073,12 @@ version = "0.2.7" dependencies = [ "ahash", "anyhow", - "cargo_metadata", - "console 0.16.0", + "cargo_metadata 0.21.0", + "console 0.16.1", "fs-err", "globwalk", "guppy", - "itertools", + "itertools 0.14.0", "libtest-mimic", "miette", "num_cpus", @@ -2854,7 +3094,7 @@ dependencies = [ "sha2", "similar", "textwrap", - "toml 0.9.5", + "toml 0.9.7", "tracing-subscriber", "walkdir", ] @@ -2888,7 +3128,7 @@ dependencies = [ "guppy", "indexmap", "insta", - "itertools", + "itertools 0.14.0", "la-arena", "matchit", "miette", @@ -2918,9 +3158,9 @@ dependencies = [ "serde_stacker", "syn", "textwrap", - "thiserror 2.0.16", - "toml 0.9.5", - "toml_edit 0.23.4", + "thiserror 2.0.17", + "toml 0.9.7", + "toml_edit 0.23.6", "tracing", "tracing_log_error", "vergen-gitcl", @@ -2934,13 +3174,13 @@ version = "0.2.7" dependencies = [ "darling 0.21.3", "insta", - "itertools", + "itertools 0.14.0", "pavex_bp_schema", "proc-macro2", "quote", "serde", "syn", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] @@ -2986,7 +3226,7 @@ version = "0.2.7" dependencies = [ "anyhow", "pavex", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] @@ -3049,20 +3289,20 @@ dependencies = [ [[package]] name = "pest" -version = "2.8.1" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1db05f56d34358a8b1066f67cbb203ee3e7ed2ba674a6263a1d5ec6db2204323" +checksum = "21e0a3a33733faeaf8651dfee72dd0f388f0c8e5ad496a3478fa5a922f49cfa8" dependencies = [ "memchr", - "thiserror 2.0.16", + "thiserror 2.0.17", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.8.1" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb056d9e8ea77922845ec74a1c4e8fb17e7c218cc4fc11a15c5d25e189aa40bc" +checksum = "bc58706f770acb1dbd0973e6530a3cff4746fb721207feb3a8a6064cd0b6c663" dependencies = [ "pest", "pest_generator", @@ -3070,9 +3310,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.8.1" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87e404e638f781eb3202dc82db6760c8ae8a1eeef7fb3fa8264b2ef280504966" +checksum = "6d4f36811dfe07f7b8573462465d5cb8965fffc2e71ae377a33aecf14c2c9a2f" dependencies = [ "pest", "pest_meta", @@ -3083,9 +3323,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.8.1" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edd1101f170f5903fde0914f899bb503d9ff5271d7ba76bbb70bea63690cc0d5" +checksum = "42919b05089acbd0a5dcd5405fb304d17d1053847b81163d09c4ad18ce8e8420" dependencies = [ "pest", "sha2", @@ -3093,9 +3333,9 @@ dependencies = [ [[package]] name = "petgraph" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54acf3a685220b533e437e264e4d932cfbdc4cc7ec0cd232ed73c08d03b8a7ca" +checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" dependencies = [ "fixedbitset", "hashbrown 0.15.5", @@ -3171,9 +3411,9 @@ dependencies = [ [[package]] name = "potential_utf" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" dependencies = [ "zerovec", ] @@ -3240,9 +3480,9 @@ version = "0.1.0" [[package]] name = "quinn" -version = "0.11.8" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "626214629cda6781b6dc1d316ba307189c85ba657213ce642d9c77670f8202c8" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" dependencies = [ "bytes", "cfg_aliases", @@ -3251,8 +3491,8 @@ dependencies = [ "quinn-udp", "rustc-hash", "rustls", - "socket2 0.5.10", - "thiserror 2.0.16", + "socket2 0.6.0", + "thiserror 2.0.17", "tokio", "tracing", "web-time", @@ -3260,9 +3500,9 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.12" +version = "0.11.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49df843a9161c85bb8aae55f101bc0bac8bcafd637a620d9122fd7e0b2f7422e" +checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" dependencies = [ "bytes", "getrandom 0.3.3", @@ -3273,7 +3513,7 @@ dependencies = [ "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.16", + "thiserror 2.0.17", "tinyvec", "tracing", "web-time", @@ -3281,23 +3521,23 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.13" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcebb1209ee276352ef14ff8732e24cc2b02bbac986cd74a4c81bcb2f9881970" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.5.10", + "socket2 0.6.0", "tracing", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] name = "quote" -version = "1.0.40" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" dependencies = [ "proc-macro2", ] @@ -3458,14 +3698,14 @@ version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", ] [[package]] name = "regex" -version = "1.11.1" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +checksum = "8b5288124840bee7b386bc413c487869b360b2b4ec421ea56425128692f2a82c" dependencies = [ "aho-corasick", "memchr", @@ -3475,9 +3715,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.9" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad" dependencies = [ "aho-corasick", "memchr", @@ -3486,9 +3726,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" [[package]] name = "relative-path" @@ -3643,7 +3883,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" dependencies = [ "base64 0.21.7", - "bitflags 2.9.3", + "bitflags 2.9.4", "serde", "serde_derive", ] @@ -3655,7 +3895,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "beceb6f7bf81c73e73aeef6dd1356d9a1b2b4909e1f0fc3e59b034f9572d7b7f" dependencies = [ "base64 0.22.1", - "bitflags 2.9.3", + "bitflags 2.9.4", "serde", "serde_derive", "unicode-ident", @@ -3687,7 +3927,7 @@ version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7753b721174eb8ff87a9a0e799e2d7bc3749323e773db92e0984debb00019d6e" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "fallible-iterator", "fallible-streaming-iterator", "hashlink 0.9.1", @@ -3697,13 +3937,12 @@ dependencies = [ [[package]] name = "rust-ini" -version = "0.21.1" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e310ef0e1b6eeb79169a1171daf9abcb87a2e17c03bee2c4bb100b55c75409f" +checksum = "796e8d2b6696392a43bea58116b667fb4c29727dc5abd27d6acf338bb4f688c7" dependencies = [ "cfg-if", "ordered-multimap", - "trim-in-place", ] [[package]] @@ -3731,23 +3970,24 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.8" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "errno", "libc", "linux-raw-sys", - "windows-sys 0.60.2", + "windows-sys 0.61.1", ] [[package]] name = "rustls" -version = "0.23.31" +version = "0.23.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" +checksum = "cd3c25631629d034ce7cd9940adc9d45762d46de2b0f57193c4443b92c6d4d40" dependencies = [ + "aws-lc-rs", "log", "once_cell", "ring", @@ -3757,6 +3997,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-native-certs" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + [[package]] name = "rustls-pemfile" version = "2.2.0" @@ -3776,12 +4028,40 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-platform-verifier" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be59af91596cac372a6942530653ad0c3a246cdd491aaa9dcaee47f88d67d5a0" +dependencies = [ + "core-foundation", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls", + "rustls-native-certs", + "rustls-platform-verifier-android", + "rustls-webpki", + "security-framework", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + [[package]] name = "rustls-webpki" -version = "0.103.4" +version = "0.103.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" +checksum = "e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf" dependencies = [ + "aws-lc-rs", "ring", "rustls-pki-types", "untrusted", @@ -3817,6 +4097,15 @@ dependencies = [ "regex", ] +[[package]] +name = "schannel" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +dependencies = [ + "windows-sys 0.61.1", +] + [[package]] name = "scheduled-thread-pool" version = "0.2.7" @@ -3842,6 +4131,29 @@ dependencies = [ "zeroize", ] +[[package]] +name = "security-framework" +version = "3.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" +dependencies = [ + "bitflags 2.9.4", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "self-replace" version = "1.5.0" @@ -3855,30 +4167,33 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" dependencies = [ "serde", + "serde_core", ] [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ + "serde_core", "serde_derive", ] [[package]] name = "serde-untagged" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34836a629bcbc6f1afdf0907a744870039b1e14c0561cb26094fa683b158eff3" +checksum = "f9faf48a4a2d2693be24c6289dbe26552776eb7737074e6722891fadbe6c5058" dependencies = [ "erased-serde", "serde", + "serde_core", "typeid", ] @@ -3892,11 +4207,20 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -3905,37 +4229,39 @@ dependencies = [ [[package]] name = "serde_html_form" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d2de91cf02bbc07cde38891769ccd5d4f073d22a40683aa4bc7a95781aaa2c4" +checksum = "b2f2d7ff8a2140333718bb329f5c40fc5f0865b84c426183ce14c97d2ab8154f" dependencies = [ "form_urlencoded", "indexmap", "itoa", "ryu", - "serde", + "serde_core", ] [[package]] name = "serde_json" -version = "1.0.143" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ "itoa", "memchr", "ryu", "serde", + "serde_core", ] [[package]] name = "serde_path_to_error" -version = "0.1.17" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59fab13f937fa393d08645bf3a84bdfe86e296747b506ada67bb15f10f218b2a" +checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" dependencies = [ "itoa", "serde", + "serde_core", ] [[package]] @@ -3949,20 +4275,21 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40734c41988f7306bb04f0ecf60ec0f3f1caa34290e4e8ea471dcd3346483b83" +checksum = "5417783452c2be558477e104686f7de5dae53dba813c28435e0e70f82d9b04ee" dependencies = [ - "serde", + "serde_core", ] [[package]] name = "serde_stacker" -version = "0.1.12" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69c8defe6c780725cce4ec6ad3bd91e321baf6fa4e255df1f31e345d507ef01a" +checksum = "d4936375d50c4be7eff22293a9344f8e46f323ed2b3c243e52f89138d9bb0f4a" dependencies = [ "serde", + "serde_core", "stacker", ] @@ -4064,7 +4391,7 @@ checksum = "297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb" dependencies = [ "num-bigint", "num-traits", - "thiserror 2.0.16", + "thiserror 2.0.17", "time", ] @@ -4169,7 +4496,7 @@ dependencies = [ "serde_json", "sha2", "smallvec", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-stream", "tracing", @@ -4224,7 +4551,7 @@ checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526" dependencies = [ "atoi", "base64 0.22.1", - "bitflags 2.9.3", + "bitflags 2.9.4", "byteorder", "bytes", "crc", @@ -4253,7 +4580,7 @@ dependencies = [ "smallvec", "sqlx-core", "stringprep", - "thiserror 2.0.16", + "thiserror 2.0.17", "tracing", "uuid", "whoami", @@ -4267,7 +4594,7 @@ checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46" dependencies = [ "atoi", "base64 0.22.1", - "bitflags 2.9.3", + "bitflags 2.9.4", "byteorder", "crc", "dotenvy", @@ -4291,7 +4618,7 @@ dependencies = [ "smallvec", "sqlx-core", "stringprep", - "thiserror 2.0.16", + "thiserror 2.0.17", "tracing", "uuid", "whoami", @@ -4316,7 +4643,7 @@ dependencies = [ "serde", "serde_urlencoded", "sqlx-core", - "thiserror 2.0.16", + "thiserror 2.0.17", "tracing", "url", "uuid", @@ -4441,9 +4768,9 @@ checksum = "e502f78cdbb8ba4718f566c418c52bc729126ffd16baee5baa718cf25dd5a69a" [[package]] name = "target-spec" -version = "3.5.0" +version = "3.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53928b291de23967df6740f2e584bb68101890f63d730292c0a5205092c8e0fa" +checksum = "b44840fc121ca20db81dadbb66d27ac9133a0d4756d674caa7da088ce89cbf2d" dependencies = [ "cfg-expr", "guppy-workspace-hack", @@ -4458,15 +4785,15 @@ checksum = "1ac9aa371f599d22256307c24a9d748c041e548cbf599f35d890f9d365361790" [[package]] name = "tempfile" -version = "3.21.0" +version = "3.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15b61f8f20e3a6f7e0649d825294eaf317edce30f82cf6026e7e4cb9222a7d1e" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ "fastrand", "getrandom 0.3.3", "once_cell", "rustix", - "windows-sys 0.60.2", + "windows-sys 0.61.1", ] [[package]] @@ -4510,11 +4837,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.16" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ - "thiserror-impl 2.0.16", + "thiserror-impl 2.0.17", ] [[package]] @@ -4530,9 +4857,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.16" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", @@ -4550,9 +4877,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.41" +version = "0.3.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" dependencies = [ "deranged", "itoa", @@ -4567,15 +4894,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" [[package]] name = "time-macros" -version = "0.2.22" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" dependencies = [ "num-conv", "time-core", @@ -4646,9 +4973,9 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.2" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ "rustls", "tokio", @@ -4693,14 +5020,14 @@ dependencies = [ [[package]] name = "toml" -version = "0.9.5" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75129e1dc5000bfbaa9fee9d1b21f974f9fbad9daec557a521ee6e080825f6e8" +checksum = "00e5e5d9bf2475ac9d4f0d9edab68cc573dc2fd644b0dba36b0c30a92dd9eaa0" dependencies = [ "indexmap", - "serde", - "serde_spanned 1.0.0", - "toml_datetime 0.7.0", + "serde_core", + "serde_spanned 1.0.2", + "toml_datetime 0.7.2", "toml_parser", "toml_writer", "winnow", @@ -4717,11 +5044,11 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bade1c3e902f58d73d3f294cd7f20391c1cb2fbcb643b73566bc773971df91e3" +checksum = "32f1085dec27c2b6632b04c80b3bb1b4300d6495d1e129693bdda7d91e72eec1" dependencies = [ - "serde", + "serde_core", ] [[package]] @@ -4740,14 +5067,14 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.23.4" +version = "0.23.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7211ff1b8f0d3adae1663b7da9ffe396eabe1ca25f0b0bee42b0da29a9ddce93" +checksum = "f3effe7c0e86fdff4f69cdd2ccc1b96f933e24811c5441d44904e8683e27184b" dependencies = [ "indexmap", - "serde", - "serde_spanned 1.0.0", - "toml_datetime 0.7.0", + "serde_core", + "serde_spanned 1.0.2", + "toml_datetime 0.7.2", "toml_parser", "toml_writer", "winnow", @@ -4755,9 +5082,9 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b551886f449aa90d4fe2bdaa9f4a2577ad2dde302c61ecf262d80b116db95c10" +checksum = "4cf893c33be71572e0e9aa6dd15e6677937abd686b066eac3f8cd3531688a627" dependencies = [ "winnow", ] @@ -4770,9 +5097,9 @@ checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" [[package]] name = "toml_writer" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc842091f2def52017664b53082ecbbeb5c7731092bad69d2c63050401dfd64" +checksum = "d163a63c116ce562a22cda521fcc4d79152e7aba014456fb5eb442f6d6a10109" [[package]] name = "tower" @@ -4795,7 +5122,7 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "bytes", "futures-util", "http", @@ -4901,12 +5228,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "trim-in-place" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "343e926fc669bc8cde4fa3129ab681c63671bae288b1f1081ceee6d9d37904fc" - [[package]] name = "try-lock" version = "0.2.5" @@ -4915,9 +5236,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "trybuild" -version = "1.0.110" +version = "1.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32e257d7246e7a9fd015fb0b28b330a8d4142151a33f03e6a497754f4b1f6a8e" +checksum = "0ded9fdb81f30a5708920310bfcd9ea7482ff9cba5f54601f7a19a877d5c2392" dependencies = [ "glob", "serde", @@ -4925,7 +5246,7 @@ dependencies = [ "serde_json", "target-triple", "termcolor", - "toml 0.9.5", + "toml 0.9.7", ] [[package]] @@ -4936,7 +5257,7 @@ checksum = "dd9267f90719e0433aae095640b294ff36ccbf89649ecb9ee34464ec504be157" dependencies = [ "arrayvec", "rand 0.9.2", - "thiserror 2.0.16", + "thiserror 2.0.17", "uuid", ] @@ -4948,9 +5269,9 @@ checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" [[package]] name = "typenum" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "ubyte" @@ -4984,9 +5305,9 @@ checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" [[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" [[package]] name = "unicode-linebreak" @@ -5069,9 +5390,9 @@ checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae" [[package]] name = "ureq" -version = "3.1.0" +version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00432f493971db5d8e47a65aeb3b02f8226b9b11f1450ff86bb772776ebadd70" +checksum = "99ba1025f18a4a3fc3e9b48c868e9beb4f24f4b4b1a325bada26bd4119f46537" dependencies = [ "base64 0.22.1", "cookie_store", @@ -5090,9 +5411,9 @@ dependencies = [ [[package]] name = "ureq-proto" -version = "0.5.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5b6cabebbecc4c45189ab06b52f956206cea7d8c8a20851c35a85cb169224cc" +checksum = "60b4531c118335662134346048ddb0e54cc86bd7e81866757873055f0e38f5d2" dependencies = [ "base64 0.22.1", "http", @@ -5132,9 +5453,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.18.0" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f33196643e165781c20a5ead5582283a7dacbb87855d867fbc2df3f81eddc1be" +checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" dependencies = [ "getrandom 0.3.3", "js-sys", @@ -5232,11 +5553,20 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasi" -version = "0.14.2+wasi-0.2.4" +version = "0.14.7+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" dependencies = [ - "wit-bindgen-rt", + "wasip2", +] + +[[package]] +name = "wasip2" +version = "1.0.1+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +dependencies = [ + "wit-bindgen", ] [[package]] @@ -5247,21 +5577,22 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.100" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", + "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.100" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19" dependencies = [ "bumpalo", "log", @@ -5273,9 +5604,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.50" +version = "0.4.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +checksum = "7e038d41e478cc73bae0ff9b36c60cff1c98b8f38f8d7e8061e79ee63608ac5c" dependencies = [ "cfg-if", "js-sys", @@ -5286,9 +5617,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.100" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5296,9 +5627,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.100" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7" dependencies = [ "proc-macro2", "quote", @@ -5309,9 +5640,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.100" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1" dependencies = [ "unicode-ident", ] @@ -5333,9 +5664,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.77" +version = "0.3.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +checksum = "9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120" dependencies = [ "js-sys", "wasm-bindgen", @@ -5351,6 +5682,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki-root-certs" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4ffd8df1c57e87c325000a3d6ef93db75279dc3a231125aac571650f22b12a" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "webpki-roots" version = "0.26.11" @@ -5397,11 +5737,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0978bf7171b3d90bac376700cb56d606feb40f251a475a5d6634613564460b22" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.1", ] [[package]] @@ -5412,9 +5752,18 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-link" -version = "0.1.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" +checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] [[package]] name = "windows-sys" @@ -5449,7 +5798,31 @@ version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.53.3", + "windows-targets 0.53.4", +] + +[[package]] +name = "windows-sys" +version = "0.61.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f109e41dd4a3c848907eb83d5a42ea98b3769495597450cf6d153507b166f0f" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", ] [[package]] @@ -5485,9 +5858,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.3" +version = "0.53.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +checksum = "2d42b7b7f66d2a06854650af09cfdf8713e427a439c97ad65a6375318033ac4b" dependencies = [ "windows-link", "windows_aarch64_gnullvm 0.53.0", @@ -5500,6 +5873,12 @@ dependencies = [ "windows_x86_64_msvc 0.53.0", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -5518,6 +5897,12 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -5536,6 +5921,12 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -5566,6 +5957,12 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -5584,6 +5981,12 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -5602,6 +6005,12 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -5620,6 +6029,12 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -5648,13 +6063,10 @@ dependencies = [ ] [[package]] -name = "wit-bindgen-rt" -version = "0.39.0" +name = "wit-bindgen" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags 2.9.3", -] +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "writeable" @@ -5664,9 +6076,9 @@ checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" [[package]] name = "xattr" -version = "1.5.1" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af3a19837351dc82ba89f8a125e22a3c475f05aba604acc023d62b2739ae2909" +checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" dependencies = [ "libc", "rustix", @@ -5699,9 +6111,9 @@ dependencies = [ [[package]] name = "yaml-rust2" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ce2a4ff45552406d02501cea6c18d8a7e50228e7736a872951fe2fe75c91be7" +checksum = "2462ea039c445496d8793d052e13787f2b90e750b833afee748e601c17621ed9" dependencies = [ "arraydeque", "encoding_rs", @@ -5740,18 +6152,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.26" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.26" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" dependencies = [ "proc-macro2", "quote", @@ -5781,9 +6193,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.8.1" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" [[package]] name = "zerotrie" @@ -5833,7 +6245,7 @@ dependencies = [ "indexmap", "lzma-rs", "memchr", - "thiserror 2.0.16", + "thiserror 2.0.17", "zopfli", ] diff --git a/libs/Cargo.toml b/libs/Cargo.toml index 3ea209e63..e400df1fc 100644 --- a/libs/Cargo.toml +++ b/libs/Cargo.toml @@ -96,6 +96,8 @@ reqwest = { version = "0.12", default-features = false, features = [ reqwest-middleware = "0.4" reqwest-retry = "0.7.0" reqwest-tracing = "0.5.8" +rustls = { version = "0.23", default-features = false } +rustls-platform-verifier = "0.6.1" ring = "0.17.14" rlimit = "0.10.2" ron = "0.10" @@ -111,6 +113,7 @@ serde_html_form = "0.2" serde_json = "1.0.142" serde_path_to_error = "0.1" serde_stacker = "0.1" +serde_yaml = "0.9.33" sha2 = "0.10.9" similar = "2.7.0" smallvec = "1" diff --git a/libs/pavex/Cargo.toml b/libs/pavex/Cargo.toml index 1c789a3b7..60659fa25 100644 --- a/libs/pavex/Cargo.toml +++ b/libs/pavex/Cargo.toml @@ -13,17 +13,18 @@ repository.workspace = true license.workspace = true readme = "README.md" -[lints.rust] -unexpected_cfgs = { level = "allow", check-cfg = ['cfg(pavex_ide_hint)'] } - [features] -default = ["server", "server_request_id", "time", "cookie", "config"] +default = ["server", "server_request_id", "time", "cookie", "config", "rustls_0_23"] server = ["dep:hyper-util", "dep:socket2", "tokio/net"] config = ["dep:figment"] cookie = ["dep:biscotti", "time"] server_request_id = ["dep:uuid"] time = ["dep:jiff"] +rustls_0_23 = ["dep:rustls", "dep:rustls-platform-verifier"] +fips = ["rustls?/fips"] +tls_crypto_provider_ring = ["rustls?/ring"] +tls_crypto_provider_aws_lc_rs = ["rustls?/aws_lc_rs"] [dependencies] bytes = { workspace = true } @@ -46,6 +47,7 @@ persist_if_changed = { path = "../persist_if_changed", version = "0.2.7" } # Configuration figment = { workspace = true, features = ["env", "yaml"], optional = true } +serde_yaml = { workspace = true } # Route parameters matchit = { workspace = true } @@ -74,6 +76,10 @@ type-safe-id = { workspace = true } # Time facilities jiff = { workspace = true, features = ["serde"], optional = true } +# TLS +rustls = { workspace = true, default-features = false, features = ["std", "tls12", "logging"], optional = true } +rustls-platform-verifier = { workspace = true, optional = true } + tokio = { workspace = true, features = ["sync", "rt", "time"] } hyper = { workspace = true, features = ["full"] } hyper-util = { workspace = true, features = [ @@ -93,7 +99,9 @@ tracing = { workspace = true } reqwest = { workspace = true } itertools = { workspace = true } secrecy = { workspace = true, features = ["serde"] } +serde_yaml = { workspace = true } pavex_tracing = { path = "../pavex_tracing" } +uuid = { workspace = true, features = ["v7", "v4"] } pavex_macros = { path = "../pavex_macros", features = [ "allow_unreachable_pub", diff --git a/libs/pavex/src/lib.rs b/libs/pavex/src/lib.rs index 5351a05ff..3f83d41a8 100644 --- a/libs/pavex/src/lib.rs +++ b/libs/pavex/src/lib.rs @@ -1,3 +1,4 @@ +#![cfg_attr(docsrs, feature(doc_cfg))] //! # Pavex - API reference //! //! Welcome to the API reference for Pavex! @@ -16,9 +17,11 @@ pub use response::{into_response::IntoResponse, response_::Response}; pub mod blueprint; #[cfg(feature = "config")] +#[cfg_attr(docsrs, doc(cfg(feature = "config")))] pub mod config; pub mod connection; #[cfg(feature = "cookie")] +#[cfg_attr(docsrs, doc(cfg(feature = "cookie")))] pub mod cookie; pub mod error; pub mod http; @@ -28,16 +31,19 @@ pub mod response; pub mod router; pub mod serialization; #[cfg(feature = "server")] +#[cfg_attr(docsrs, doc(cfg(feature = "server")))] pub mod server; pub mod telemetry; pub mod unit; #[cfg(feature = "time")] +#[cfg_attr(docsrs, doc(cfg(feature = "time")))] pub mod time { //! Utilities to work with dates, timestamps and datetimes. //! //! It's a re-export of the [`jiff@0.2`](https://docs.rs/jiff/0.2) crate. pub use jiff::*; } +pub mod tls; /// Define a [prebuilt type](https://pavex.dev/docs/guide/dependency_injection/prebuilt_types/). /// diff --git a/libs/pavex/src/telemetry/mod.rs b/libs/pavex/src/telemetry/mod.rs index 5bac73c2c..a91bd3e20 100644 --- a/libs/pavex/src/telemetry/mod.rs +++ b/libs/pavex/src/telemetry/mod.rs @@ -1,6 +1,8 @@ //! Tools to instrument and troubleshoot your Pavex applications. #[cfg(feature = "server_request_id")] +#[cfg_attr(docsrs, doc(cfg(feature = "server_request_id")))] mod server_request_id; #[cfg(feature = "server_request_id")] +#[cfg_attr(docsrs, doc(cfg(feature = "server_request_id")))] pub use server_request_id::ServerRequestId; diff --git a/libs/pavex/src/tls/client/config.rs b/libs/pavex/src/tls/client/config.rs new file mode 100644 index 000000000..367319ef0 --- /dev/null +++ b/libs/pavex/src/tls/client/config.rs @@ -0,0 +1,263 @@ +//! Configure the TLS policy for a client. +//! +//! Check out the documentation for [`TlsClientPolicyConfig`](super::TlsClientPolicyConfig) for +//! a detailed explanation of the available configuration options. +use serde::{Deserialize, Serialize}; +use std::path::PathBuf; + +// Wrapped into a sub-module to avoid exposing `TlsClientPolicyConfig` in two places: +// inside `pavex::tls::config` and `pavex::tls::client`. +// We only want users to see `pavex::tls::client::TlsClientPolicyConfig`. +pub(crate) mod _config { + use super::*; + + /// Configure the TLS policy for a client. + /// + /// It covers: + /// - The [cryptographic stack](`Self::crypto_provider`) used to secure the connection. + /// - Which [TLS versions](`Self::allowed_versions`) are allowed. + /// - The [certificate verification](`Self::certificate_verification`) mechanism used to verify server certificates. + /// + /// For testing/development purposes only, it exposes a few [insecure](`Self::insecure`) configuration options + /// that lower the security posture of your client. + /// + /// # Defaults + /// + /// The default configuration should be suitable for most production environments: + /// + /// ```yaml + #[doc = include_str!("../../../tests/fixtures/tls_config/default.yaml")] + /// ``` + /// + /// # Overriding the default configuration + /// + /// If you want to deviate from the default configuration, it's enough to specify the fields you + /// want to override. + /// + /// ## Example: Disable TLS 1.2 + /// + /// ```yaml + #[doc = include_str!("../../../tests/fixtures/tls_config/disable_tls_1_2.yaml")] + /// ``` + /// + /// ## Example: Trust additional root certificates + /// + /// ```yaml + #[doc = include_str!("../../../tests/fixtures/tls_config/additional_roots.yaml")] + /// ``` + /// + /// ## Example: Disable certificate verification + /// + /// ```yaml + #[doc = include_str!("../../../tests/fixtures/tls_config/skip_verification.yaml")] + /// ``` + #[derive(Debug, Default, Clone, Deserialize, Serialize)] + #[non_exhaustive] + pub struct TlsClientPolicyConfig { + /// The cryptographic stack used to secure the connection. + /// + /// Refer to the documentation for [`CryptoProviderConfig`](CryptoProviderConfig) + /// for more details. + #[serde(default)] + #[serde(with = "serde_yaml::with::singleton_map_recursive")] + pub crypto_provider: CryptoProviderConfig, + /// Which TLS versions are allowed. + /// + /// Refer to the documentation for [`AllowedTlsVersionsConfig`](AllowedTlsVersionsConfig) + /// for more details. + #[serde(default)] + pub allowed_versions: AllowedTlsVersionsConfig, + /// The mechanism used to verify server certificates. + /// + /// Refer to the documentation for [`CertificateVerificationConfig`](CertificateVerificationConfig) + /// for more details. + #[serde(default)] + pub certificate_verification: CertificateVerificationConfig, + /// Dangerous configuration options that lower the security + /// posture of your client. + /// + /// These options should never be used in production scenarios. + /// They are available for testing/development purposes only. + #[serde(default)] + pub insecure: InsecureTlsClientConfig, + } +} + +/// Which TLS versions are allowed. +/// +/// By default, TLS 1.2 and TLS 1.3 are enabled. +/// +/// # Security +/// +/// The lack of support for TLS 1.0 and TLS 1.1 is intentional. +#[derive(Debug, Clone, Copy, Deserialize, Serialize)] +#[non_exhaustive] +pub struct AllowedTlsVersionsConfig { + /// Enables TLS 1.2 if `true`. + /// + /// It requires the server to support TLS 1.2. + #[serde(default = "default_v1_2")] + pub v1_2: bool, + /// Enables TLS 1.3 if `true`. + /// + /// It requires the server to support TLS 1.3. + #[serde(default = "default_v1_3")] + pub v1_3: bool, +} + +fn default_v1_2() -> bool { + true +} + +fn default_v1_3() -> bool { + true +} + +impl Default for AllowedTlsVersionsConfig { + fn default() -> Self { + Self { + v1_2: default_v1_2(), + v1_3: default_v1_3(), + } + } +} + +/// Configure how server certificates are verified. +/// +/// # Default +/// +/// By default, we rely on verification machinery of the underlying operating system. +/// Refer to the documentation for [`rustls-platform-verifier`](https://docs.rs/rustls-platform-verifier/latest/rustls_platform_verifier/) +/// for more information on how each platform handles certificate verification. +/// +/// # Customization +/// +/// Set [`additional_roots`][`CertificateVerificationConfig::additional_roots`] to trust +/// additional root certificates in addition to the ones already trusted +/// by the operating system. +/// +/// # Skipping Verification +/// +/// If you want to skip certificate verification altogether, check out the [`insecure`][`super::TlsClientPolicyConfig::insecure`] +/// options in [`TlsClientPolicyConfig`][`super::TlsClientPolicyConfig`]. +/// +/// ## Incorrect Usage +/// +/// Setting [`use_os_verifier`][`CertificateVerificationConfig::use_os_verifier`] to `false`, with +/// no [`additional_roots`][`CertificateVerificationConfig::additional_roots`] specified, does **not** +/// disable certificate verification. It does instead cause all certificate verification attempts to fail. +/// +/// We treat this scenario as a misconfiguration and return an error at runtime, when +/// trying to initialize the client. +#[derive(Debug, Clone, Deserialize, Serialize)] +#[non_exhaustive] +pub struct CertificateVerificationConfig { + /// Whether to use the certificate verification machinery provided by + /// the underlying operating system. + /// + /// Defaults to `true`. + #[serde(default = "default_use_os_verifier")] + pub use_os_verifier: bool, + /// Trust one or more additional root certificates. + /// + /// If [`use_os_verifier`][`CertificateVerificationConfig::use_os_verifier`] is `false`, + /// these will be the only trusted root certificates. + /// If [`use_os_verifier`][`CertificateVerificationConfig::use_os_verifier`] is `true`, these will be + /// trusted **in addition** to the ones already trusted by the underlying operating system. + /// + /// They can either be loaded from files or inlined in configuration. + #[serde(default)] + #[serde(with = "serde_yaml::with::singleton_map_recursive")] + pub additional_roots: Vec, +} + +fn default_use_os_verifier() -> bool { + true +} + +impl Default for CertificateVerificationConfig { + fn default() -> Self { + CertificateVerificationConfig { + use_os_verifier: default_use_os_verifier(), + additional_roots: Default::default(), + } + } +} + +/// [Additional root certificates](`CertificateVerificationConfig::additional_roots`) to be trusted. +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "snake_case")] +#[non_exhaustive] +pub enum RootCertificate { + /// Retrieve the root certificate from a file. + File { + /// How to decode the root certificate inside the file. + encoding: RootCertificateFileEncoding, + /// The path to the root certificate file. + path: PathBuf, + }, + /// A root certificate inlined inside the provided configuration. + Inline { + /// A PEM-encoded X.509 certificate; as specified in [RFC 7468](https://datatracker.ietf.org/doc/html/rfc7468#section-5). + data: String, + }, +} + +/// Supported encodings for the root certificate in [`RootCertificate::File`]. +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "snake_case")] +#[non_exhaustive] +pub enum RootCertificateFileEncoding { + /// A DER-encoded X.509 certificate; as specified in [RFC 5280](https://datatracker.ietf.org/doc/html/rfc5280#section-4.1). + Der, + /// A PEM-encoded X.509 certificate; as specified in [RFC 7468](https://datatracker.ietf.org/doc/html/rfc7468#section-5). + Pem, +} + +/// Dangerous configuration options to lower the security posture of a TLS client. +#[derive(Debug, Clone, Deserialize, Serialize)] +#[non_exhaustive] +pub struct InsecureTlsClientConfig { + /// Don't verify server certificates. + /// + /// Extremely dangerous option, limit its usage to local development environments. + #[serde(default = "default_skip_verification")] + pub skip_verification: bool, +} + +impl Default for InsecureTlsClientConfig { + fn default() -> Self { + InsecureTlsClientConfig { + skip_verification: default_skip_verification(), + } + } +} + +fn default_skip_verification() -> bool { + false +} + +/// Which implementation to use for TLS cryptographic operations. +#[derive(Debug, Default, Copy, Clone, Deserialize, Serialize)] +#[serde(rename_all = "snake_case")] +#[non_exhaustive] +pub enum CryptoProviderConfig { + /// Use [`aws-lc-rs`](https://docs.rs/aws-lc-rs/) for cryptographic operations. + /// + /// If you require FIPS compliance, use the [`AwsLcRsFips`][`CryptoProviderConfig::AwsLcRsFips`] + /// instead. + #[default] + AwsLcRs, + /// Use [`aws-lc-rs`](https://docs.rs/aws-lc-rs/) for cryptographic operations, + /// in FIPS-compliant mode. + /// + /// # Additional constraints + /// + /// FIPS mode is not supported on all platforms. + /// Furthermore, `aws-lc-rs` requires additional system dependencies at build time. + /// Check out their [documentation](https://docs.rs/aws-lc-rs/latest/aws_lc_rs/#fips) for + /// more information. + AwsLcRsFips, + /// Use [`ring`](https://docs.rs/ring/) for cryptographic operations. + Ring, +} diff --git a/libs/pavex/src/tls/client/mod.rs b/libs/pavex/src/tls/client/mod.rs new file mode 100644 index 000000000..bf91bdccb --- /dev/null +++ b/libs/pavex/src/tls/client/mod.rs @@ -0,0 +1,10 @@ +//! Secure your client connections with TLS (Transport Layer Security). +//! +//! Check out the documentation for [`TlsClientPolicyConfig`] for +//! a detailed explanation of the available configuration options. +pub mod config; +pub use config::_config::TlsClientPolicyConfig; + +#[cfg(feature = "rustls_0_23")] +#[cfg_attr(docsrs, doc(cfg(feature = "rustls_0_23")))] +mod rustls_0_23; diff --git a/libs/pavex/src/tls/client/rustls_0_23.rs b/libs/pavex/src/tls/client/rustls_0_23.rs new file mode 100644 index 000000000..449b15830 --- /dev/null +++ b/libs/pavex/src/tls/client/rustls_0_23.rs @@ -0,0 +1,270 @@ +use crate::tls::client::config::{ + AllowedTlsVersionsConfig, CertificateVerificationConfig, CryptoProviderConfig, RootCertificate, + RootCertificateFileEncoding, +}; + +use super::TlsClientPolicyConfig; +use anyhow::{Context, bail, ensure}; +use rustls::{ + ClientConfig, Error as TlsError, RootCertStore, SupportedProtocolVersion, + client::{ + WebPkiServerVerifier, + danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier}, + }, + crypto::CryptoProvider, + pki_types::{ + CertificateDer, ServerName, + pem::{PemObject, SectionKind}, + }, + version::{TLS12, TLS13}, +}; +use std::sync::Arc; + +impl TryFrom<&TlsClientPolicyConfig> for ClientConfig { + type Error = Rustls023ConfigError; + + fn try_from(value: &TlsClientPolicyConfig) -> Result { + value.rustls_0_23_config() + } +} + +#[derive(Debug, thiserror::Error)] +#[error(transparent)] +/// The error that can occur in [`TlsClientPolicyConfig::rustls_0_23_config`] when building a +/// [`rustls::ClientConfig`](https://docs.rs/rustls/0.23/rustls/client/struct.ClientConfig.html). +pub struct Rustls023ConfigError(anyhow::Error); + +impl TlsClientPolicyConfig { + /// Build a [`rustls::ClientConfig`](https://docs.rs/rustls/0.23/rustls/client/struct.ClientConfig.html) according to the specified configuration. + pub fn rustls_0_23_config(&self) -> Result { + fn _config(policy: &TlsClientPolicyConfig) -> Result { + let provider = Arc::new(crypto_provider(&policy.crypto_provider)?); + let builder = ClientConfig::builder_with_provider(provider.clone()) + .with_protocol_versions(supported_versions(policy.allowed_versions)?)?; + + let config = if policy.insecure.skip_verification { + builder + .dangerous() + .with_custom_certificate_verifier(Arc::new(NoVerify { provider })) + } else { + let certificate_verifier = + certificate_verifier(provider, &policy.certificate_verification)?; + builder + .dangerous() + .with_custom_certificate_verifier(certificate_verifier) + } + .with_no_client_auth(); + + Ok(config) + } + + _config(self).map_err(Rustls023ConfigError) + } +} + +fn crypto_provider(p: &CryptoProviderConfig) -> Result { + match p { + #[cfg(not(feature = "tls_crypto_provider_aws_lc_rs"))] + CryptoProviderConfig::AwsLcRs => { + bail!( + "Your TLS client configuration wants to use `aws_lc_rs` as its cryptography stack, but the corresponding `cargo` feature is not enabled.\n\ + Add `tls_crypto_provider_aws_lc_rs` to the `features` array for `pavex` in your Cargo.toml manifest." + ); + } + #[cfg(feature = "tls_crypto_provider_aws_lc_rs")] + CryptoProviderConfig::AwsLcRs => Ok(rustls::crypto::aws_lc_rs::default_provider()), + #[cfg(feature = "tls_crypto_provider_aws_lc_rs")] + CryptoProviderConfig::AwsLcRsFips => { + let prov = rustls::crypto::aws_lc_rs::default_provider(); + + if !prov.fips() { + bail!( + "FIPS requested but the `fips` feature is not enabled. Add `fips` to the `features` array for `pavex` in your Cargo.toml manifest." + ); + } + Ok(prov) + } + #[cfg(not(feature = "tls_crypto_provider_aws_lc_rs"))] + CryptoProviderConfig::AwsLcRsFips => { + bail!( + "Your TLS client configuration wants to use `aws_lc_rs_fips` as its cryptography stack, but the corresponding `cargo` feature is not enabled.\n\ + Add `tls_crypto_provider_aws_lc_rs` and `fips` to the `features` array for `pavex` in your Cargo.toml manifest." + ); + } + #[cfg(feature = "tls_crypto_provider_ring")] + CryptoProviderConfig::Ring => Ok(rustls::crypto::ring::default_provider()), + #[cfg(not(feature = "tls_crypto_provider_ring"))] + CryptoProviderConfig::Ring => bail!( + "Your TLS client configuration wants to use `ring` as its cryptography stack, but the corresponding `cargo` feature is not enabled.\n\ + Add `tls_crypto_provider_ring` to the `features` array for `pavex` in your Cargo.toml manifest." + ), + } +} + +fn certificate_verifier( + crypto_provider: Arc, + config: &CertificateVerificationConfig, +) -> Result, anyhow::Error> { + if !config.use_os_verifier && config.additional_roots.is_empty() { + anyhow::bail!( + "You disabled OS server certificate verification without providing a list of additional root certificates to trust.\n\ + This configuration is invalid: it would cause **all** TLS connections to fail.\n\ + Please enable OS certificate verification or provide a list of root certificates to trust. Check out the documentation \ + of `pavex::tls::client::CertificateVerificationConfig` for more information." + ) + } + let additional_roots = additional_roots(&config.additional_roots)?; + if config.use_os_verifier { + let verifier = rustls_platform_verifier::Verifier::new_with_extra_roots( + additional_roots, + crypto_provider, + ) + .context("Failed to initialize the server certificate verifier")?; + Ok(Arc::new(verifier)) + } else { + let mut root_cert_store = RootCertStore::empty(); + for root in additional_roots { + root_cert_store + .add(root) + .context("One of your additional root certificates is invalid")?; + } + let verifier = + WebPkiServerVerifier::builder_with_provider(Arc::new(root_cert_store), crypto_provider) + .build() + .context("Failed to initialize the server certificate verifier")?; + Ok(verifier) + } +} + +fn supported_versions( + config: AllowedTlsVersionsConfig, +) -> Result<&'static [&'static SupportedProtocolVersion], anyhow::Error> { + static ALL: [&SupportedProtocolVersion; 2] = [&TLS12, &TLS13]; + static ONLY_TLS12: [&SupportedProtocolVersion; 1] = [&TLS12]; + static ONLY_TLS13: [&SupportedProtocolVersion; 1] = [&TLS13]; + + match (config.v1_2, config.v1_3) { + (true, true) => Ok(&ALL), + (true, false) => Ok(&ONLY_TLS12), + (false, true) => Ok(&ONLY_TLS13), + (false, false) => { + bail!("You disabled both TLS 1.2 and TLS 1.3. At least one of them must be enabled."); + } + } +} + +fn additional_roots( + root_sources: &[RootCertificate], +) -> Result>, anyhow::Error> { + let mut roots = Vec::with_capacity(root_sources.len()); + for (i, source) in root_sources.iter().enumerate() { + parse_additional_root(&mut roots, source).with_context(|| { + format!( + "Failed to parse the root certificate at index {i} in your list of `additional_roots`", + ) + })?; + } + Ok(roots) +} + +fn parse_additional_root( + roots: &mut Vec>, + source: &RootCertificate, +) -> Result<(), anyhow::Error> { + match source { + RootCertificate::File { encoding, path } => { + let contents = fs_err::read(path).context("Failed to read root certificate file")?; + match encoding { + RootCertificateFileEncoding::Der => { + roots.push(CertificateDer::from(contents)); + } + RootCertificateFileEncoding::Pem => { + roots.extend(parse_certificates_from_pem_bytes(&contents)?); + } + } + } + RootCertificate::Inline { data } => { + roots.extend(parse_certificates_from_pem_bytes(data.as_bytes())?); + } + } + Ok(()) +} + +fn parse_certificates_from_pem_bytes( + data: &[u8], +) -> Result>, anyhow::Error> { + let mut certs = Vec::new(); + for outcome in <(SectionKind, Vec) as PemObject>::pem_slice_iter(data) { + let (section_kind, section_data) = + outcome.context("Failed to parse a section of your PEM-encoded root certificate")?; + if section_kind != SectionKind::Certificate { + anyhow::bail!( + "Expected a PEM-encoded root certificate, but found a {} section", + kind2str(section_kind) + ) + } + certs.push(CertificateDer::from(section_data)); + } + ensure!( + !certs.is_empty(), + "Your PEM bundle doesn't contain any root certificate. There should be at least one `BEGIN CERTIFICATE` block" + ); + Ok(certs) +} + +fn kind2str(kind: SectionKind) -> &'static str { + match kind { + SectionKind::Certificate => "CERTIFICATE", + SectionKind::PublicKey => "PUBLIC KEY", + SectionKind::RsaPrivateKey => "RSA PRIVATE KEY", + SectionKind::PrivateKey => "PRIVATE KEY", + SectionKind::EcPrivateKey => "EC PRIVATE KEY", + SectionKind::Crl => "X509 CRL", + SectionKind::Csr => "CERTIFICATE REQUEST", + SectionKind::EchConfigList => "ECHCONFIG", + _ => "unknown", + } +} + +#[derive(Debug, Clone)] +/// A custom verifier that doesn't actually verify server certificates. +struct NoVerify { + provider: Arc, +} + +impl ServerCertVerifier for NoVerify { + fn verify_tls12_signature( + &self, + _message: &[u8], + _cert: &CertificateDer<'_>, + _dss: &rustls::DigitallySignedStruct, + ) -> std::result::Result { + Ok(HandshakeSignatureValid::assertion()) + } + + fn verify_tls13_signature( + &self, + _message: &[u8], + _cert: &CertificateDer<'_>, + _dss: &rustls::DigitallySignedStruct, + ) -> std::result::Result { + Ok(HandshakeSignatureValid::assertion()) + } + + fn supported_verify_schemes(&self) -> Vec { + self.provider + .signature_verification_algorithms + .supported_schemes() + } + + fn verify_server_cert( + &self, + _end_entity: &CertificateDer<'_>, + _intermediates: &[CertificateDer<'_>], + _server_name: &ServerName<'_>, + _ocsp_response: &[u8], + _now: rustls::pki_types::UnixTime, + ) -> std::result::Result { + Ok(ServerCertVerified::assertion()) + } +} diff --git a/libs/pavex/src/tls/mod.rs b/libs/pavex/src/tls/mod.rs new file mode 100644 index 000000000..22f272672 --- /dev/null +++ b/libs/pavex/src/tls/mod.rs @@ -0,0 +1,2 @@ +//! Secure your server and client connections with TLS (Transport Layer Security). +pub mod client; diff --git a/libs/pavex/tests/fixtures/tls_config/additional_roots.yaml b/libs/pavex/tests/fixtures/tls_config/additional_roots.yaml new file mode 100644 index 000000000..7ee79f832 --- /dev/null +++ b/libs/pavex/tests/fixtures/tls_config/additional_roots.yaml @@ -0,0 +1,11 @@ +# In YAML format +certificate_verification: + additional_roots: + - file: + path: "/path/to/certificate.pem" + encoding: "pem" + - inline: + data: | + -----BEGIN CERTIFICATE----- + MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA + -----END CERTIFICATE----- diff --git a/libs/pavex/tests/fixtures/tls_config/default.yaml b/libs/pavex/tests/fixtures/tls_config/default.yaml new file mode 100644 index 000000000..1de64acef --- /dev/null +++ b/libs/pavex/tests/fixtures/tls_config/default.yaml @@ -0,0 +1,10 @@ +# In YAML format +crypto_provider: aws_lc_rs +allowed_versions: + v1_2: true + v1_3: true +certificate_verification: + use_os_verifier: true + additional_roots: [] +insecure: + skip_verification: false diff --git a/libs/pavex/tests/fixtures/tls_config/disable_tls_1_2.yaml b/libs/pavex/tests/fixtures/tls_config/disable_tls_1_2.yaml new file mode 100644 index 000000000..53fc6a179 --- /dev/null +++ b/libs/pavex/tests/fixtures/tls_config/disable_tls_1_2.yaml @@ -0,0 +1,3 @@ +# In YAML format +allowed_versions: + v1_2: false diff --git a/libs/pavex/tests/fixtures/tls_config/skip_verification.yaml b/libs/pavex/tests/fixtures/tls_config/skip_verification.yaml new file mode 100644 index 000000000..9ac9b6325 --- /dev/null +++ b/libs/pavex/tests/fixtures/tls_config/skip_verification.yaml @@ -0,0 +1,3 @@ +# In YAML format +insecure: + skip_verification: true diff --git a/libs/pavex/tests/integration/main.rs b/libs/pavex/tests/integration/main.rs new file mode 100644 index 000000000..2142bf4a9 --- /dev/null +++ b/libs/pavex/tests/integration/main.rs @@ -0,0 +1,2 @@ +mod server; +mod tls; diff --git a/libs/pavex/tests/server.rs b/libs/pavex/tests/integration/server.rs similarity index 100% rename from libs/pavex/tests/server.rs rename to libs/pavex/tests/integration/server.rs diff --git a/libs/pavex/tests/integration/tls/client_config.rs b/libs/pavex/tests/integration/tls/client_config.rs new file mode 100644 index 000000000..3045e8a47 --- /dev/null +++ b/libs/pavex/tests/integration/tls/client_config.rs @@ -0,0 +1,248 @@ +use pavex::tls::client::TlsClientPolicyConfig; +use pavex::tls::client::config::{ + CryptoProviderConfig, RootCertificate, RootCertificateFileEncoding, +}; + +/// Tests that verify the YAML examples from the documentation deserialize correctly. +mod doc_examples { + use super::*; + + #[test] + fn test_default_config() { + let yaml = include_str!("../../fixtures/tls_config/default.yaml"); + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + + // Verify the default config values + assert!(matches!( + config.crypto_provider, + CryptoProviderConfig::AwsLcRs + )); + assert!(config.allowed_versions.v1_2); + assert!(config.allowed_versions.v1_3); + assert!(config.certificate_verification.use_os_verifier); + assert!(config.certificate_verification.additional_roots.is_empty()); + assert!(!config.insecure.skip_verification); + + // Verify it matches what you get from an empty document + let empty_config: TlsClientPolicyConfig = serde_yaml::from_str("").unwrap(); + assert_eq!( + serde_yaml::to_string(&config).unwrap(), + serde_yaml::to_string(&empty_config).unwrap(), + "Default config should match empty document" + ); + } + + #[test] + fn test_disable_tls_1_2() { + let yaml = include_str!("../../fixtures/tls_config/disable_tls_1_2.yaml"); + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + + assert!(!config.allowed_versions.v1_2); + assert!(config.allowed_versions.v1_3); + } + + #[test] + fn test_additional_roots() { + let yaml = include_str!("../../fixtures/tls_config/additional_roots.yaml"); + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + + assert_eq!(config.certificate_verification.additional_roots.len(), 2); + } + + #[test] + fn test_skip_verification() { + let yaml = include_str!("../../fixtures/tls_config/skip_verification.yaml"); + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + + assert!(config.insecure.skip_verification); + } +} + +#[test] +fn test_empty_config_uses_defaults() { + let yaml = ""; + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + + assert!(matches!( + config.crypto_provider, + CryptoProviderConfig::AwsLcRs, + )); + assert!(config.allowed_versions.v1_2); + assert!(config.allowed_versions.v1_3); + assert!(config.certificate_verification.use_os_verifier); + assert!(config.certificate_verification.additional_roots.is_empty()); + assert!(!config.insecure.skip_verification); +} + +#[test] +fn test_disable_tls_1_3() { + let yaml = r#" +allowed_versions: + v1_3: false +"#; + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + + assert!(config.allowed_versions.v1_2); + assert!(!config.allowed_versions.v1_3); +} + +#[test] +fn test_additional_root_from_file_pem() { + let yaml = r#" +certificate_verification: + additional_roots: + - file: + path: /path/to/certificate.pem + encoding: pem +"#; + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + + assert_eq!(config.certificate_verification.additional_roots.len(), 1); + match &config.certificate_verification.additional_roots[0] { + RootCertificate::File { encoding, path } => { + assert!(matches!(encoding, RootCertificateFileEncoding::Pem)); + assert_eq!(path.to_str().unwrap(), "/path/to/certificate.pem"); + } + _ => panic!("Expected File variant"), + } +} + +#[test] +fn test_additional_root_from_file_der() { + let yaml = r#" +certificate_verification: + additional_roots: + - file: + path: /path/to/certificate.der + encoding: der +"#; + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + + assert_eq!(config.certificate_verification.additional_roots.len(), 1); + match &config.certificate_verification.additional_roots[0] { + RootCertificate::File { encoding, path } => { + assert!(matches!(encoding, RootCertificateFileEncoding::Der)); + assert_eq!(path.to_str().unwrap(), "/path/to/certificate.der"); + } + _ => panic!("Expected File variant"), + } +} + +#[test] +fn test_inline_root_pem() { + let yaml = r#" +certificate_verification: + additional_roots: + - inline: + data: | + -----BEGIN CERTIFICATE----- + MIICUTCCAfugAwIBAgIBADANBgkqhkiG9w0BAQQFADBXMQswCQYDVQQGEwJDTjEL + -----END CERTIFICATE----- +"#; + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + + assert_eq!(config.certificate_verification.additional_roots.len(), 1); + match &config.certificate_verification.additional_roots[0] { + RootCertificate::Inline { data } => { + insta::assert_snapshot!(data, @r###" + -----BEGIN CERTIFICATE----- + MIICUTCCAfugAwIBAgIBADANBgkqhkiG9w0BAQQFADBXMQswCQYDVQQGEwJDTjEL + -----END CERTIFICATE----- + "###) + } + _ => panic!("Expected Inline variant"), + } +} + +#[test] +fn test_multiple_additional_roots() { + let yaml = r#" +certificate_verification: + additional_roots: + - file: + path: /path/to/cert1.pem + encoding: pem + - file: + path: /path/to/cert2.der + encoding: "der" + - inline: + data: "-----BEGIN CERTIFICATE-----\ndata\n-----END CERTIFICATE-----" +"#; + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + + assert_eq!(config.certificate_verification.additional_roots.len(), 3); +} + +#[test] +fn test_disable_os_verifier() { + let yaml = r#" +certificate_verification: + use_os_verifier: false +"#; + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + + assert!(!config.certificate_verification.use_os_verifier); +} + +#[test] +fn test_skip_verification_enabled() { + let yaml = r#" +insecure: + skip_verification: true +"#; + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + + assert!(config.insecure.skip_verification); +} + +#[test] +fn test_ring_crypto_provider() { + let yaml = r#" +crypto_provider: ring +"#; + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + + assert!(matches!(config.crypto_provider, CryptoProviderConfig::Ring)); +} + +#[test] +fn test_aws_lc_rs_with_fips() { + let yaml = r#" +crypto_provider: aws_lc_rs_fips +"#; + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + + assert!(matches!( + config.crypto_provider, + CryptoProviderConfig::AwsLcRsFips + )); +} + +#[test] +fn test_complex_config() { + let yaml = r#" +crypto_provider: aws_lc_rs_fips +allowed_versions: + v1_2: false + v1_3: true +certificate_verification: + use_os_verifier: true + additional_roots: + - file: + path: /etc/ssl/certs/custom-ca.pem + encoding: pem +insecure: + skip_verification: false +"#; + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + + assert!(matches!( + config.crypto_provider, + CryptoProviderConfig::AwsLcRsFips + )); + assert!(!config.allowed_versions.v1_2); + assert!(config.allowed_versions.v1_3); + assert!(config.certificate_verification.use_os_verifier); + assert_eq!(config.certificate_verification.additional_roots.len(), 1); + assert!(!config.insecure.skip_verification); +} diff --git a/libs/pavex/tests/integration/tls/mod.rs b/libs/pavex/tests/integration/tls/mod.rs new file mode 100644 index 000000000..b640cff18 --- /dev/null +++ b/libs/pavex/tests/integration/tls/mod.rs @@ -0,0 +1,4 @@ +mod client_config; + +#[cfg(feature = "rustls_0_23")] +mod rustls_0_23; diff --git a/libs/pavex/tests/integration/tls/rustls_0_23/crypto_providers.rs b/libs/pavex/tests/integration/tls/rustls_0_23/crypto_providers.rs new file mode 100644 index 000000000..5a88d430c --- /dev/null +++ b/libs/pavex/tests/integration/tls/rustls_0_23/crypto_providers.rs @@ -0,0 +1,88 @@ +/// Tests for crypto provider feature handling + +#[test] +#[cfg(not(feature = "tls_crypto_provider_aws_lc_rs"))] +fn aws_lc_rs_requires_feature() { + use pavex::tls::client::TlsClientPolicyConfig; + + let yaml = r#" +crypto_provider: aws_lc_rs +"#; + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + let err = config.rustls_0_23_config().unwrap_err(); + + insta::assert_snapshot!(err, @r###" + Your TLS client configuration wants to use `aws_lc_rs` as its cryptography stack, but the corresponding `cargo` feature is not enabled. + Add `tls_crypto_provider_aws_lc_rs` to the `features` array for `pavex` in your Cargo.toml manifest. + "###); +} + +#[test] +#[cfg(not(feature = "tls_crypto_provider_ring"))] +fn ring_requires_feature() { + use pavex::tls::client::TlsClientPolicyConfig; + + let yaml = r#" +crypto_provider: ring +"#; + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + let err = config.rustls_0_23_config().unwrap_err(); + + insta::assert_snapshot!(err, @r###" + Your TLS client configuration wants to use `ring` as its cryptography stack, but the corresponding `cargo` feature is not enabled. + Add `tls_crypto_provider_ring` to the `features` array for `pavex` in your Cargo.toml manifest. + "###); +} + +#[test] +#[cfg(feature = "tls_crypto_provider_aws_lc_rs")] +fn aws_lc_rs_works_when_feature_enabled() { + use pavex::tls::client::TlsClientPolicyConfig; + + let yaml = r#" +crypto_provider: aws_lc_rs +"#; + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + // Should not error when feature is enabled + config.rustls_0_23_config().unwrap(); +} + +#[test] +#[cfg(feature = "tls_crypto_provider_ring")] +fn ring_works_when_feature_enabled() { + use pavex::tls::client::TlsClientPolicyConfig; + + let yaml = r#" +crypto_provider: ring +"#; + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + // Should not error when feature is enabled + config.rustls_0_23_config().unwrap(); +} + +#[test] +#[cfg(all(feature = "tls_crypto_provider_aws_lc_rs", not(feature = "fips")))] +fn fips_required_but_not_enabled() { + use pavex::tls::client::TlsClientPolicyConfig; + + let yaml = r#" +crypto_provider: aws_lc_rs_fips +"#; + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + let err = config.rustls_0_23_config().unwrap_err(); + + insta::assert_snapshot!(err, @"FIPS requested but the `fips` feature is not enabled. Add `fips` to the `features` array for `pavex` in your Cargo.toml manifest."); +} + +#[test] +#[cfg(all(feature = "tls_crypto_provider_aws_lc_rs", feature = "fips"))] +fn fips_works_when_enabled() { + use pavex::tls::client::TlsClientPolicyConfig; + + let yaml = r#" +crypto_provider: aws_lc_rs_fips +"#; + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + // Should not error when FIPS feature is enabled + config.rustls_0_23_config().unwrap(); +} diff --git a/libs/pavex/tests/integration/tls/rustls_0_23/errors.rs b/libs/pavex/tests/integration/tls/rustls_0_23/errors.rs new file mode 100644 index 000000000..389b568e9 --- /dev/null +++ b/libs/pavex/tests/integration/tls/rustls_0_23/errors.rs @@ -0,0 +1,84 @@ +use pavex::tls::client::TlsClientPolicyConfig; + +#[test] +fn both_tls_versions_disabled() { + let yaml = r#" +allowed_versions: + v1_2: false + v1_3: false +"#; + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + let err = config.rustls_0_23_config().unwrap_err(); + + insta::assert_snapshot!(err, @"You disabled both TLS 1.2 and TLS 1.3. At least one of them must be enabled."); +} + +#[test] +fn os_verifier_disabled_with_no_additional_roots() { + let yaml = r#" +certificate_verification: + use_os_verifier: false + additional_roots: [] +"#; + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + let err = config.rustls_0_23_config().unwrap_err(); + + insta::assert_snapshot!(err, @r###" + You disabled OS server certificate verification without providing a list of additional root certificates to trust. + This configuration is invalid: it would cause **all** TLS connections to fail. + Please enable OS certificate verification or provide a list of root certificates to trust. Check out the documentation of `pavex::tls::client::CertificateVerificationConfig` for more information. + "###); +} + +#[test] +fn empty_pem_bundle() { + let yaml = r#" +certificate_verification: + additional_roots: + - inline: + encoding: pem + data: | + # Just a comment, no certificates +"#; + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + let err = config.rustls_0_23_config().unwrap_err(); + + insta::assert_snapshot!(format!("{:#}", err), @"Failed to parse the root certificate at index 0 in your list of `additional_roots`: Your PEM bundle doesn't contain any root certificate. There should be at least one `BEGIN CERTIFICATE` block"); +} + +#[test] +fn pem_with_wrong_section_type() { + // This is a PRIVATE KEY, not a CERTIFICATE + let yaml = r#" +certificate_verification: + additional_roots: + - inline: + encoding: pem + data: | + -----BEGIN PRIVATE KEY----- + MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC7VJTUt9Us8cKj + -----END PRIVATE KEY----- +"#; + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + let err = config.rustls_0_23_config().unwrap_err(); + + insta::assert_snapshot!(format!("{:#}", err), @"Failed to parse the root certificate at index 0 in your list of `additional_roots`: Expected a PEM-encoded root certificate, but found a PRIVATE KEY section"); +} + +#[test] +fn malformed_pem() { + let yaml = r#" +certificate_verification: + additional_roots: + - inline: + encoding: pem + data: | + -----BEGIN CERTIFICATE----- + This is not valid base64 PEM content + -----END CERTIFICATE----- +"#; + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + let err = config.rustls_0_23_config().unwrap_err(); + + insta::assert_snapshot!(format!("{:#}", err), @"Failed to initialize the server certificate verifier: invalid peer certificate: BadEncoding"); +} diff --git a/libs/pavex/tests/integration/tls/rustls_0_23/mod.rs b/libs/pavex/tests/integration/tls/rustls_0_23/mod.rs new file mode 100644 index 000000000..09bfd686b --- /dev/null +++ b/libs/pavex/tests/integration/tls/rustls_0_23/mod.rs @@ -0,0 +1,5 @@ +mod crypto_providers; +#[cfg(feature = "tls_crypto_provider_aws_lc_rs")] +mod errors; +#[cfg(feature = "tls_crypto_provider_aws_lc_rs")] +mod success; diff --git a/libs/pavex/tests/integration/tls/rustls_0_23/success.rs b/libs/pavex/tests/integration/tls/rustls_0_23/success.rs new file mode 100644 index 000000000..19ddc3aad --- /dev/null +++ b/libs/pavex/tests/integration/tls/rustls_0_23/success.rs @@ -0,0 +1,110 @@ +use pavex::tls::client::TlsClientPolicyConfig; + +#[test] +fn default_config_builds_successfully() { + let yaml = include_str!("../../../fixtures/tls_config/default.yaml"); + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + + // Just verify it built successfully - we can't easily inspect internals + config.rustls_0_23_config().unwrap(); +} + +#[test] +fn skip_verification_builds_successfully() { + let yaml = include_str!("../../../fixtures/tls_config/skip_verification.yaml"); + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + + config.rustls_0_23_config().unwrap(); +} + +#[test] +fn only_tls_1_2_builds_successfully() { + let yaml = r#" +allowed_versions: + v1_2: true + v1_3: false +"#; + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + + config.rustls_0_23_config().unwrap(); +} + +#[test] +fn only_tls_1_3_builds_successfully() { + let yaml = r#" +allowed_versions: + v1_2: false + v1_3: true +"#; + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + + config.rustls_0_23_config().unwrap(); +} + +#[test] +fn with_inline_pem_certificate_builds_successfully() { + // Using a real (but expired) certificate for testing + let yaml = r#" +certificate_verification: + use_os_verifier: false + additional_roots: + - inline: + encoding: pem + data: | + -----BEGIN CERTIFICATE----- + MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF + ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 + b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL + MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv + b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj + ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM + 9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw + IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6 + VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L + 93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm + jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC + AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA + A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI + U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs + N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv + o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU + 5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy + rqXRfboQnoZsG4q5WTP468SQvvG5 + -----END CERTIFICATE----- +"#; + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + + config.rustls_0_23_config().unwrap(); +} + +#[test] +fn try_from_succeeds_for_valid_config() { + let yaml = include_str!("../../../fixtures/tls_config/default.yaml"); + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + + let _client_config: rustls::ClientConfig = (&config).try_into().unwrap(); +} + +#[test] +fn try_from_fails_for_invalid_config() { + let yaml = r#" +allowed_versions: + v1_2: false + v1_3: false +"#; + let config: TlsClientPolicyConfig = serde_yaml::from_str(yaml).unwrap(); + + let result: Result = (&config).try_into(); + assert!(result.is_err()); +} + +#[test] +fn reqwest_compatibility() { + let config = TlsClientPolicyConfig::default() + .rustls_0_23_config() + .unwrap(); + reqwest::Client::builder() + .use_preconfigured_tls(config) + .build() + .unwrap(); +} diff --git a/libs/pavex_cli/tests/dependency_tree.rs b/libs/pavex_cli/tests/dependency_tree.rs index f2fde35ad..593f46812 100644 --- a/libs/pavex_cli/tests/dependency_tree.rs +++ b/libs/pavex_cli/tests/dependency_tree.rs @@ -37,6 +37,12 @@ pub fn allowed_sys_crates() { let allowed_sys_crates = BTreeSet::from([ "windows-sys", "libsqlite3-sys", + // It doesn't actually get pulled in, since it's behind an optional feature in `pavex` + // that doesn't get activated by the CLI, but tracking that is messy. + "aws-lc-rs", + "aws-lc-sys", + "aws-lc-fips-sys", + "clang-sys", // We use the `static` feature of `lzma-sys` to avoid linking to the system LZMA library. "lzma-sys", // Various crates in the ecosystem are not proper "*-sys" crates, but they still