diff --git a/.cargo/audit.toml b/.cargo/audit.toml index fe5086a51..70dfc7e62 100644 --- a/.cargo/audit.toml +++ b/.cargo/audit.toml @@ -1,5 +1,6 @@ [advisories] ignore = [ - "RUSTSEC-2024-0436", #paste - "RUSTSEC-2023-0071", #rsa marvin attack - patched in 0.10, we're depending on 0.10.0-rc.0 + "RUSTSEC-2023-0071", # rsa marvin attack - patched in 0.10, we're depending on 0.10.0-rc.0 + "RUSTSEC-2023-0089", # atomic-polyfill unmaintained + "RUSTSEC-2024-0436", # paste unmaintained ] # advisory IDs to ignore e.g. ["RUSTSEC-2019-0001", ...] diff --git a/.github/workflows/mcf.yml b/.github/workflows/mcf.yml index ae96e7886..6fc90467c 100644 --- a/.github/workflows/mcf.yml +++ b/.github/workflows/mcf.yml @@ -37,10 +37,11 @@ jobs: - uses: RustCrypto/actions/cargo-hack-install@master - run: cargo hack build --target ${{ matrix.target }} --feature-powerset - minimal-versions: - uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master - with: - working-directory: ${{ github.workflow }} + # TODO(tarcieri): re-enable after stable release + #minimal-versions: + # uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master + # with: + # working-directory: ${{ github.workflow }} test: runs-on: ubuntu-latest diff --git a/.github/workflows/security-audit.yml b/.github/workflows/security-audit.yml index 8244c203a..24dd7a30f 100644 --- a/.github/workflows/security-audit.yml +++ b/.github/workflows/security-audit.yml @@ -21,10 +21,10 @@ jobs: - uses: dtolnay/rust-toolchain@master with: toolchain: stable - - uses: actions/cache@v4 + - uses: actions/cache@v5 with: path: ~/.cargo/bin - key: ${{ runner.os }}-cargo-audit-v0.21.2 + key: ${{ runner.os }}-cargo-audit-v0.22.0 - uses: rustsec/audit-check@v2 with: token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/tai64_update_leap_seconds.yml b/.github/workflows/tai64_update_leap_seconds.yml index b612c3fa3..31fa3af7f 100644 --- a/.github/workflows/tai64_update_leap_seconds.yml +++ b/.github/workflows/tai64_update_leap_seconds.yml @@ -18,7 +18,7 @@ jobs: sed -i -E 's/(Self\()[0-9]+ \+ \(1 << 62\)\)/\1'"${number}"' + (1 << 62))/' tai64/src/lib.rs rm leap_seconds_list - name: Create Pull Request - uses: peter-evans/create-pull-request@v7 + uses: peter-evans/create-pull-request@v8 with: commit-message: update leap seconds in tai64 title: Update leap seconds in tai64 diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index e1e3ea6bf..b0610b0ba 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -54,4 +54,4 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - - uses: crate-ci/typos@v1.40.0 + - uses: crate-ci/typos@v1.42.1 diff --git a/Cargo.lock b/Cargo.lock index 4fe002e50..ff3c47a6c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 4 [[package]] name = "aead" -version = "0.6.0-rc.3" +version = "0.6.0-rc.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03d2d54c4d9e7006f132f615a167865bff927a79ca63d8f637237575ce0a9795" +checksum = "67a578e7d4edaef88aeb9cdd81556f4a62266ce26601317c006a79e8bc58b5af" dependencies = [ "crypto-common", "inout", @@ -73,9 +73,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 = "arbitrary" @@ -86,6 +86,15 @@ dependencies = [ "derive_arbitrary", ] +[[package]] +name = "atomic-polyfill" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +dependencies = [ + "critical-section", +] + [[package]] name = "autocfg" version = "1.5.0" @@ -94,7 +103,7 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "base16ct" -version = "0.3.0" +version = "1.0.0" [[package]] name = "base32" @@ -118,21 +127,12 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" -version = "1.8.1" +version = "1.8.3" dependencies = [ "base64", "proptest", ] -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - [[package]] name = "bit-set" version = "0.8.0" @@ -213,13 +213,13 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "chacha20" -version = "0.10.0-rc.5" +version = "0.10.0-rc.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99cbf41c6ec3c4b9eaf7f8f5c11a72cd7d3aa0428125c20d5ef4d09907a0f019" +checksum = "f895fb33c1ad22da4bc79d37c0bddff8aee2ba4575705345eb73b8ffbc386074" dependencies = [ "cfg-if", "cpufeatures", - "rand_core 0.10.0-rc-2", + "rand_core 0.10.0-rc-3", ] [[package]] @@ -251,9 +251,9 @@ dependencies = [ [[package]] name = "cipher" -version = "0.5.0-rc.2" +version = "0.5.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "155e4a260750fa4f7754649f049748aacc31db238a358d85fd721002f230f92f" +checksum = "98d708bac5451350d56398433b19a7889022fa9187df1a769c0edbc3b2c03167" dependencies = [ "block-buffer", "crypto-common", @@ -262,18 +262,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.40" +version = "4.5.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" +checksum = "c6e6ff9dcd79cff5cd969a17a545d79e84ab086e444102a591e288a8aa3ce394" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.40" +version = "4.5.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" +checksum = "fa42cf4d2b7a41bc8f663a7cab4031ebafa1bf3875705bfaf8466dc60ab52c00" dependencies = [ "anstyle", "clap_lex", @@ -281,9 +281,15 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.5" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" + +[[package]] +name = "cmov" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" +checksum = "6d5ce5728ecb5285a5dd35f02a6a8e34e0828e0b38e8e632e249a3fe3f320211" [[package]] name = "cmpv2" @@ -300,7 +306,7 @@ dependencies = [ [[package]] name = "cms" -version = "0.3.0-pre.0" +version = "0.3.0-pre.1" dependencies = [ "aes", "aes-kw", @@ -312,13 +318,13 @@ dependencies = [ "digest", "ecdsa", "elliptic-curve", - "getrandom", + "getrandom 0.4.0-rc.0", "hex-literal", "p256", "pbkdf2", "pem-rfc7468", "pkcs5", - "rand 0.10.0-rc.5", + "rand 0.10.0-rc.6", "rsa", "sha1", "sha2", @@ -330,9 +336,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "cobs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" +dependencies = [ + "thiserror", +] + [[package]] name = "const-oid" -version = "0.10.1" +version = "0.10.2" dependencies = [ "arbitrary", "hex-literal", @@ -380,6 +395,12 @@ dependencies = [ "itertools 0.10.5", ] +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + [[package]] name = "crmf" version = "0.3.0-pre.0" @@ -399,13 +420,15 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "crypto-bigint" -version = "0.7.0-rc.10" +version = "0.7.0-rc.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6715836b4946e8585016e80b79c7561476aff3b22f7b756778e7b109d86086c6" +checksum = "fbd828c64d6fecf364ec127641e5ce0f8d6e3264a6c466b4a4bdcbec5b038b9e" dependencies = [ + "ctutils", + "getrandom 0.4.0-rc.0", "hybrid-array", "num-traits", - "rand_core 0.10.0-rc-2", + "rand_core 0.10.0-rc-3", "serdect", "subtle", "zeroize", @@ -413,23 +436,24 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.2.0-rc.5" +version = "0.2.0-rc.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "919bd05924682a5480aec713596b9e2aabed3a0a6022fab6847f85a99e5f190a" +checksum = "41b8986f836d4aeb30ccf4c9d3bd562fd716074cfd7fc4a2948359fbd21ed809" dependencies = [ + "getrandom 0.4.0-rc.0", "hybrid-array", - "rand_core 0.10.0-rc-2", + "rand_core 0.10.0-rc-3", ] [[package]] name = "crypto-primes" -version = "0.7.0-pre.4" +version = "0.7.0-pre.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdd9b2855017318a49714c07ee8895b89d3510d54fa6d86be5835de74c389609" +checksum = "e79c98a281f9441200b24e3151407a629bfbe720399186e50516da939195e482" dependencies = [ "crypto-bigint", "libm", - "rand_core 0.10.0-rc-2", + "rand_core 0.10.0-rc-3", ] [[package]] @@ -441,6 +465,16 @@ dependencies = [ "cipher", ] +[[package]] +name = "ctutils" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c67c81499f542d1dd38c6a2a2fe825f4dd4bca5162965dd2eea0c8119873d3c" +dependencies = [ + "cmov", + "subtle", +] + [[package]] name = "der" version = "0.8.0-rc.10" @@ -450,7 +484,7 @@ dependencies = [ "const-oid", "der_derive", "flagset", - "heapless", + "heapless 0.9.2", "hex-literal", "pem-rfc7468", "proptest", @@ -469,9 +503,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.4.0" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" dependencies = [ "powerfmt", ] @@ -498,9 +532,9 @@ dependencies = [ [[package]] name = "digest" -version = "0.11.0-rc.4" +version = "0.11.0-rc.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea390c940e465846d64775e55e3115d5dc934acb953de6f6e6360bc232fe2bf7" +checksum = "ebf9423bafb058e4142194330c52273c343f8a5beb7176d052f0e73b17dd35b9" dependencies = [ "block-buffer", "const-oid", @@ -510,9 +544,9 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.17.0-rc.9" +version = "0.17.0-rc.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e914ecb8e11a02f42cc05f6b43675d1e5aa4d446cd207f9f818903a1ab34f19f" +checksum = "a18ccb2afbad0782e073b602a7d59dd08966d2b1173e08f96ebffb5446f8446d" dependencies = [ "der", "digest", @@ -531,20 +565,21 @@ checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "elliptic-curve" -version = "0.14.0-rc.17" +version = "0.14.0-rc.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39ecd2903524729de5d0cba7589121744513feadd56d71980cb480c48caceb11" +checksum = "6ee4530cd12af66979d89bf0e555c66d04ed1dc58479d7a69d93c98a650fb738" dependencies = [ "base16ct", "crypto-bigint", + "crypto-common", "digest", - "getrandom", + "getrandom 0.4.0-rc.0", "hkdf", "hybrid-array", "once_cell", "pem-rfc7468", "pkcs8", - "rand_core 0.10.0-rc-2", + "rand_core 0.10.0-rc-3", "rustcrypto-ff", "rustcrypto-group", "sec1", @@ -552,6 +587,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "embedded-io" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + [[package]] name = "equivalent" version = "1.0.2" @@ -641,6 +688,19 @@ dependencies = [ "wasip2", ] +[[package]] +name = "getrandom" +version = "0.4.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b99f0d993a2b9b97b9a201193aa8ad21305cde06a3be9a7e1f8f4201e5cc27e" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "rand_core 0.10.0-rc-3", + "wasip2", +] + [[package]] name = "ghash" version = "0.6.0-rc.3" @@ -677,6 +737,15 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + [[package]] name = "hash32" version = "0.3.1" @@ -726,13 +795,27 @@ dependencies = [ "uuid", ] +[[package]] +name = "heapless" +version = "0.7.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" +dependencies = [ + "atomic-polyfill", + "hash32 0.2.1", + "rustc_version", + "serde", + "spin", + "stable_deref_trait", +] + [[package]] name = "heapless" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2af2455f757db2b292a9b1768c4b70186d443bcb3b316252d6b540aec1cd89ed" dependencies = [ - "hash32", + "hash32 0.3.1", "stable_deref_trait", ] @@ -773,9 +856,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.12.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", "hashbrown", @@ -783,9 +866,9 @@ dependencies = [ [[package]] name = "inout" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7357b6e7aa75618c7864ebd0634b115a7218b0615f4cb1df33ac3eca23943d4" +checksum = "4250ce6452e92010fdf7268ccc5d14faa80bb12fc741938534c58f16804e03c7" dependencies = [ "block-padding", "hybrid-array", @@ -811,9 +894,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.15" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" [[package]] name = "js-sys" @@ -842,9 +925,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.178" +version = "0.2.180" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" +checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" [[package]] name = "libm" @@ -858,6 +941,15 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + [[package]] name = "log" version = "0.4.27" @@ -866,7 +958,7 @@ checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "mcf" -version = "0.6.0-pre" +version = "0.6.0-rc.3" dependencies = [ "base64ct", "hex-literal", @@ -926,9 +1018,9 @@ checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" [[package]] name = "p256" -version = "0.14.0-rc.1" +version = "0.14.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdbe8d6ac92e515ca2179ac331c1e4def09db2217d394683e73dace705c2f0c5" +checksum = "dcb1056e093c065babf1e9b0e28a630bee540cd9f5b905230ddc475175f5e9c8" dependencies = [ "ecdsa", "elliptic-curve", @@ -937,17 +1029,11 @@ dependencies = [ "sha2", ] -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - [[package]] name = "pbkdf2" -version = "0.13.0-rc.3" +version = "0.13.0-rc.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c148c9a0a9a7d256a8ea004fae8356c02ccc44cf8c06e7d68fdbedb48de1beb" +checksum = "eedc1683fe7216d6ce1294e870b994b4418660ad692d55297f631be0b6300666" dependencies = [ "digest", "hmac", @@ -962,11 +1048,11 @@ dependencies = [ [[package]] name = "phc" -version = "0.6.0-rc.0" +version = "0.6.0-rc.1" dependencies = [ "base64ct", - "getrandom", - "rand_core 0.10.0-rc-2", + "getrandom 0.4.0-rc.0", + "rand_core 0.10.0-rc-3", "subtle", ] @@ -995,7 +1081,7 @@ dependencies = [ [[package]] name = "pkcs12" -version = "0.2.0-pre" +version = "0.2.0-pre.0" dependencies = [ "cms", "const-oid", @@ -1013,7 +1099,7 @@ dependencies = [ [[package]] name = "pkcs5" -version = "0.8.0-rc.10" +version = "0.8.0-rc.12" dependencies = [ "aes", "aes-gcm", @@ -1022,7 +1108,7 @@ dependencies = [ "des", "hex-literal", "pbkdf2", - "rand_core 0.10.0-rc-2", + "rand_core 0.10.0-rc-3", "scrypt", "sha1", "sha2", @@ -1031,12 +1117,12 @@ dependencies = [ [[package]] name = "pkcs8" -version = "0.11.0-rc.8" +version = "0.11.0-rc.9" dependencies = [ "der", "hex-literal", "pkcs5", - "rand_core 0.10.0-rc-2", + "rand_core 0.10.0-rc-3", "spki", "subtle", "tempfile", @@ -1053,6 +1139,19 @@ dependencies = [ "universal-hash", ] +[[package]] +name = "postcard" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24" +dependencies = [ + "cobs", + "embedded-io 0.4.0", + "embedded-io 0.6.1", + "heapless 0.7.17", + "serde", +] + [[package]] name = "powerfmt" version = "0.2.0" @@ -1070,12 +1169,13 @@ dependencies = [ [[package]] name = "primefield" -version = "0.14.0-rc.1" +version = "0.14.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c3ad342f52c70a953d95acb09a55450fdc07c2214283b81536c3f83f714568e" +checksum = "bf1f23afb6185c65efc97605dea2d667f6fef71cb9d3198992c1e9002e349f40" dependencies = [ "crypto-bigint", - "rand_core 0.10.0-rc-2", + "crypto-common", + "rand_core 0.10.0-rc-3", "rustcrypto-ff", "subtle", "zeroize", @@ -1083,9 +1183,9 @@ dependencies = [ [[package]] name = "primeorder" -version = "0.14.0-rc.1" +version = "0.14.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5e84a5f07d7a7c85f299e17753a98d8a09f10799894a637c9ce08d834b6ca02" +checksum = "12459f4bdd430002b812017c3e99f5a27a2c2689f1b140cb82a73c23431b71e0" dependencies = [ "elliptic-curve", ] @@ -1096,7 +1196,7 @@ version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" dependencies = [ - "toml_edit 0.23.6", + "toml_edit", ] [[package]] @@ -1123,9 +1223,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.95" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +checksum = "9695f8df41bb4f3d222c95a67532365f569318332d03d5f3f67f37b20e6ebdf0" dependencies = [ "unicode-ident", ] @@ -1157,9 +1257,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.40" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" dependencies = [ "proc-macro2", ] @@ -1182,13 +1282,13 @@ dependencies = [ [[package]] name = "rand" -version = "0.10.0-rc.5" +version = "0.10.0-rc.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be866deebbade98028b705499827ad6967c8bb1e21f96a2609913c8c076e9307" +checksum = "bccc05ac8fad6ee391f3cc6725171817eed960345e2fb42ad229d486c1ca2d98" dependencies = [ "chacha20", - "getrandom", - "rand_core 0.10.0-rc-2", + "getrandom 0.4.0-rc.0", + "rand_core 0.10.0-rc-3", ] [[package]] @@ -1207,14 +1307,14 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom", + "getrandom 0.3.4", ] [[package]] name = "rand_core" -version = "0.10.0-rc-2" +version = "0.10.0-rc-3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "104a23e4e8b77312a823b6b5613edbac78397e2f34320bc7ac4277013ec4478e" +checksum = "f66ee92bc15280519ef199a274fe0cafff4245d31bc39aaa31c011ad56cb1f05" [[package]] name = "rand_xorshift" @@ -1227,9 +1327,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.1" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ "aho-corasick", "memchr", @@ -1272,31 +1372,28 @@ dependencies = [ [[package]] name = "rmp" -version = "0.8.14" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4" +checksum = "4ba8be72d372b2c9b35542551678538b562e7cf86c3315773cae48dfbfe7790c" dependencies = [ - "byteorder", "num-traits", - "paste", ] [[package]] name = "rmp-serde" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db" +checksum = "72f81bee8c8ef9b577d1681a70ebbc962c232461e397b22c208c43c04b67a155" dependencies = [ - "byteorder", "rmp", "serde", ] [[package]] name = "rsa" -version = "0.10.0-rc.10" +version = "0.10.0-rc.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e499c52862d75a86c0024cc99dcb6d7127d15af3beae7b03573d62fab7ade08a" +checksum = "c9a2b1eacbc34fbaf77f6f1db1385518446008d49b9f9f59dc9d1340fce4ca9e" dependencies = [ "const-oid", "crypto-bigint", @@ -1304,11 +1401,10 @@ dependencies = [ "digest", "pkcs1", "pkcs8", - "rand_core 0.10.0-rc-2", + "rand_core 0.10.0-rc-3", "sha2", "signature", "spki", - "subtle", "zeroize", ] @@ -1356,7 +1452,7 @@ version = "0.14.0-pre.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa9cd37111549306f79b09aa2618e15b1e8241b7178c286821e3dd71579db4db" dependencies = [ - "rand_core 0.10.0-rc-2", + "rand_core 0.10.0-rc-3", "subtle", ] @@ -1366,16 +1462,16 @@ version = "0.14.0-pre.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e394cd734b5f97dfc3484fa42aad7acd912961c2bcd96c99aa05b3d6cab7cafd" dependencies = [ - "rand_core 0.10.0-rc-2", + "rand_core 0.10.0-rc-3", "rustcrypto-ff", "subtle", ] [[package]] name = "rustix" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" dependencies = [ "bitflags", "errno", @@ -1404,9 +1500,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984" [[package]] name = "salsa20" @@ -1427,12 +1523,19 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "scrypt" -version = "0.12.0-rc.4" +version = "0.12.0-rc.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167695481f302b1be08d453c6fc266f0c437be29577ee74537385c7243961326" +checksum = "13ac15f5e54b9e1ba72ee618fc8ed94dd9dbe7b09c0eeaed80bced84100d8381" dependencies = [ + "cfg-if", "pbkdf2", "salsa20", "sha2", @@ -1440,15 +1543,15 @@ dependencies = [ [[package]] name = "sec1" -version = "0.8.0-rc.10" +version = "0.8.0-rc.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2568531a8ace88b848310caa98fb2115b151ef924d54aa523e659c21b9d32d71" dependencies = [ "base16ct", + "ctutils", "der", - "hex-literal", "hybrid-array", - "serdect", "subtle", - "tempfile", "zeroize", ] @@ -1460,9 +1563,9 @@ checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" [[package]] name = "serde" -version = "1.0.226" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dca6411025b24b60bfa7ec1fe1f8e710ac09782dca409ee8237ba74b51295fd" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ "serde_core", "serde_derive", @@ -1490,18 +1593,18 @@ dependencies = [ [[package]] name = "serde_core" -version = "1.0.226" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba2ba63999edb9dac981fb34b3e5c0d111a69b0924e253ed29d83f7c99e966a4" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.226" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8db53ae22f34573731bafa1db20f04027b2d25e02d8205921b569171699cdb33" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -1510,33 +1613,34 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.140" +version = "1.0.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" +checksum = "3084b546a1dd6289475996f182a22aba973866ea8e8b02c51d9f46b1336a22da" dependencies = [ "itoa", "memchr", - "ryu", "serde", + "serde_core", + "zmij", ] [[package]] name = "serde_spanned" -version = "0.6.9" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" dependencies = [ - "serde", + "serde_core", ] [[package]] name = "serdect" -version = "0.4.1" +version = "0.4.2" dependencies = [ "base16ct", - "bincode", "ciborium", "hex-literal", + "postcard", "proptest", "rmp-serde", "serde", @@ -1580,12 +1684,12 @@ dependencies = [ [[package]] name = "signature" -version = "3.0.0-rc.5" +version = "3.0.0-rc.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0251c9d6468f4ba853b6352b190fb7c1e405087779917c238445eb03993826" +checksum = "597a96996ccff7dfa16f052bd995b4cecc72af22c35138738dc029f0ead6608d" dependencies = [ "digest", - "rand_core 0.10.0-rc-2", + "rand_core 0.10.0-rc-3", ] [[package]] @@ -1594,6 +1698,15 @@ version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + [[package]] name = "spki" version = "0.8.0-rc.4" @@ -1621,9 +1734,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.101" +version = "2.0.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" +checksum = "678faa00651c9eb72dd2020cbdf275d92eccb2400d568e419efdd64838145cb4" dependencies = [ "proc-macro2", "quote", @@ -1640,18 +1753,18 @@ dependencies = [ [[package]] name = "target-triple" -version = "0.1.4" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ac9aa371f599d22256307c24a9d748c041e548cbf599f35d890f9d365361790" +checksum = "591ef38edfb78ca4771ee32cf494cb8771944bee237a9b91fc9c1424ac4b777b" [[package]] name = "tempfile" -version = "3.20.0" +version = "3.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" +checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" dependencies = [ "fastrand", - "getrandom", + "getrandom 0.3.4", "once_cell", "rustix", "windows-sys", @@ -1666,11 +1779,31 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "thiserror" +version = "2.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[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", "num-conv", @@ -1680,9 +1813,9 @@ 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 = "tinytemplate" @@ -1721,9 +1854,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.48.0" +version = "1.49.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" +checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" dependencies = [ "pin-project-lite", "tokio-macros", @@ -1742,80 +1875,60 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.23" +version = "0.9.11+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +checksum = "f3afc9a848309fe1aaffaed6e1546a7a14de1f935dc9d89d32afd9a44bab7c46" dependencies = [ - "serde", + "indexmap", + "serde_core", "serde_spanned", - "toml_datetime 0.6.11", - "toml_edit 0.22.27", -] - -[[package]] -name = "toml_datetime" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" -dependencies = [ - "serde", + "toml_datetime", + "toml_parser", + "toml_writer", + "winnow", ] [[package]] name = "toml_datetime" -version = "0.7.2" +version = "0.7.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f1085dec27c2b6632b04c80b3bb1b4300d6495d1e129693bdda7d91e72eec1" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" dependencies = [ "serde_core", ] [[package]] name = "toml_edit" -version = "0.22.27" +version = "0.23.10+spec-1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" dependencies = [ "indexmap", - "serde", - "serde_spanned", - "toml_datetime 0.6.11", - "toml_write", - "winnow", -] - -[[package]] -name = "toml_edit" -version = "0.23.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3effe7c0e86fdff4f69cdd2ccc1b96f933e24811c5441d44904e8683e27184b" -dependencies = [ - "indexmap", - "toml_datetime 0.7.2", + "toml_datetime", "toml_parser", "winnow", ] [[package]] name = "toml_parser" -version = "1.0.4" +version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" +checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" dependencies = [ "winnow", ] [[package]] -name = "toml_write" -version = "0.1.2" +name = "toml_writer" +version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" +checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" [[package]] name = "trybuild" -version = "1.0.105" +version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c9bf9513a2f4aeef5fdac8677d7d349c79fdbcc03b9c86da6e9d254f1e43be2" +checksum = "3e17e807bff86d2a06b52bca4276746584a78375055b6e45843925ce2802b335" dependencies = [ "glob", "serde", @@ -1846,9 +1959,9 @@ checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "universal-hash" -version = "0.6.0-rc.3" +version = "0.6.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ad6682ddb0189a4d3c2a5c54b8920ab6231ae911db53fc61a0709507bf1713b" +checksum = "0386f227888b17b65d3e38219a7d41185035471300855c285667811907bb1677" dependencies = [ "crypto-common", "subtle", @@ -1970,78 +2083,20 @@ dependencies = [ ] [[package]] -name = "windows-sys" -version = "0.59.0" +name = "windows-link" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets", -] +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] -name = "windows-targets" -version = "0.52.6" +name = "windows-sys" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows-link", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - [[package]] name = "winnow" version = "0.7.14" @@ -2059,7 +2114,7 @@ checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "x509-cert" -version = "0.3.0-rc.2" +version = "0.3.0-rc.3" dependencies = [ "arbitrary", "const-oid", @@ -2068,7 +2123,7 @@ dependencies = [ "ecdsa", "hex-literal", "p256", - "rand 0.10.0-rc.5", + "rand 0.10.0-rc.6", "rsa", "rstest", "sha1", @@ -2099,8 +2154,8 @@ dependencies = [ "digest", "hex-literal", "lazy_static", - "rand 0.10.0-rc.5", - "rand_core 0.10.0-rc-2", + "rand 0.10.0-rc.6", + "rand_core 0.10.0-rc-3", "rsa", "sha1", "sha2", @@ -2122,18 +2177,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.31" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3" +checksum = "668f5168d10b9ee831de31933dc111a459c97ec93225beb307aed970d1372dfd" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.31" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" +checksum = "2c7962b26b0a8685668b671ee4b54d007a67d4eaf05fda79ac0ecf41e32270f1" dependencies = [ "proc-macro2", "quote", @@ -2151,11 +2206,17 @@ dependencies = [ [[package]] name = "zeroize_derive" -version = "1.4.2" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" dependencies = [ "proc-macro2", "quote", "syn", ] + +[[package]] +name = "zmij" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac93432f5b761b22864c774aac244fa5c0fd877678a4c37ebf6cf42208f9c9ec" diff --git a/Cargo.toml b/Cargo.toml index 866c98d48..77467d1cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ members = [ "pkcs5", "pkcs8", "pkcs12", - "sec1", +# "sec1", "serdect", "spki", "tai64", @@ -29,6 +29,7 @@ members = [ "x509-cert/test-support", "x509-ocsp" ] +exclude = ["sec1"] [profile.dev] opt-level = 2 @@ -51,7 +52,7 @@ pkcs1 = { path = "./pkcs1" } pkcs5 = { path = "./pkcs5" } pkcs8 = { path = "./pkcs8" } pkcs12 = { path = "./pkcs12" } -sec1 = { path = "./sec1" } +#sec1 = { path = "./sec1" } serdect = { path = "./serdect" } spki = { path = "./spki" } tai64 = { path = "./tai64" } diff --git a/base16ct/CHANGELOG.md b/base16ct/CHANGELOG.md index 68cf171e5..2b94325af 100644 --- a/base16ct/CHANGELOG.md +++ b/base16ct/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 1.0.0 (2026-01-03) +### Fixed +- Switch from `doc_auto_cfg` to `doc_cfg` ([#2072]) + +[#2072]: https://github.com/RustCrypto/formats/pull/2072 + ## 0.3.0 (2025-08-20) ### Changed - Upgrade to 2024 edition; MSRV 1.85 ([#1670]) diff --git a/base16ct/Cargo.toml b/base16ct/Cargo.toml index 857215973..d17d08f05 100644 --- a/base16ct/Cargo.toml +++ b/base16ct/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "base16ct" -version = "0.3.0" +version = "1.0.0" description = """ Pure Rust implementation of Base16 a.k.a hexadecimal (RFC 4648) which avoids any usages of data-dependent branches/LUTs and thereby provides portable diff --git a/base64ct/CHANGELOG.md b/base64ct/CHANGELOG.md index c216fb4a3..ec092db56 100644 --- a/base64ct/CHANGELOG.md +++ b/base64ct/CHANGELOG.md @@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 1.8.3 (2026-01-11) +### Added +- `Base64Pbkdf2` alphabet ([#2168]) + +[#2168]: https://github.com/RustCrypto/formats/pull/2168 + +## 1.8.2 (2026-01-03) +### Changed +- Deprecate `Base64Crypt` ([#2135]) + +[#2135]: https://github.com/RustCrypto/formats/pull/2135 + ## 1.8.1 (2025-12-06) ### Added - Notes on `crypt(3)` alphabet variants ([#2073]) diff --git a/base64ct/Cargo.toml b/base64ct/Cargo.toml index 2ff1b957d..133f4f595 100644 --- a/base64ct/Cargo.toml +++ b/base64ct/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "base64ct" -version = "1.8.1" +version = "1.8.3" description = """ Pure Rust implementation of Base64 (RFC 4648) which avoids any usages of data-dependent branches/LUTs and thereby provides portable "best effort" diff --git a/base64ct/README.md b/base64ct/README.md index 252b03612..c6b00541f 100644 --- a/base64ct/README.md +++ b/base64ct/README.md @@ -40,6 +40,7 @@ fixed-width line wrapping. - URL-safe Base64: `[A-Z]`, `[a-z]`, `[0-9]`, `-`, `_` - bcrypt Base64: `.`, `/`, `[A-Z]`, `[a-z]`, `[0-9]` - `crypt(3)` Base64: `.`, `-`, `[0-9]`, `[A-Z]`, `[a-z]` +- PBKDF2 Base64: `[A-Z]`, `[a-z]`, `[0-9]`, `.`, `/` ## Minimum Supported Rust Version (MSRV) Policy diff --git a/base64ct/src/alphabet.rs b/base64ct/src/alphabet.rs index 78d92d7f6..a1753805f 100644 --- a/base64ct/src/alphabet.rs +++ b/base64ct/src/alphabet.rs @@ -7,6 +7,7 @@ use core::{fmt::Debug, ops::RangeInclusive}; pub mod bcrypt; pub mod crypt; +pub mod pbkdf2; pub mod shacrypt; pub mod standard; pub mod url; diff --git a/base64ct/src/alphabet/crypt.rs b/base64ct/src/alphabet/crypt.rs index 24f8dcadb..7e3ccbdcd 100644 --- a/base64ct/src/alphabet/crypt.rs +++ b/base64ct/src/alphabet/crypt.rs @@ -1,16 +1,24 @@ //! `crypt(3)` Base64 encoding. +#![allow(deprecated)] + use super::{Alphabet, DecodeStep, EncodeStep}; -/// `crypt(3)` Base64 encoding. +/// DEPRECATED: non-standard big endian variant of the `crypt(3)` Base64 encoding. /// /// ```text /// [.-9] [A-Z] [a-z] /// 0x2e-0x39, 0x41-0x5a, 0x61-0x7a /// ``` /// -/// Note this encodes using a big endian variant of Base64. Most modern algorithms which can be -/// used via `crypt(3)` use the little endian [`Base64ShaCrypt`][`crate::Base64ShaCrypt`] variant. +///
+/// This encodes using a big endian variant of Base64. Most modern algorithms which can be +/// used via `crypt(3)` use the [`Base64ShaCrypt`][`crate::Base64ShaCrypt`] encoding. +///
+#[deprecated( + since = "1.8.2", + note = "non-standard encoding. Use Base64ShaCrypt for all crypt(3) algorithms" +)] #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct Base64Crypt; diff --git a/base64ct/src/alphabet/pbkdf2.rs b/base64ct/src/alphabet/pbkdf2.rs new file mode 100644 index 000000000..e772794a5 --- /dev/null +++ b/base64ct/src/alphabet/pbkdf2.rs @@ -0,0 +1,33 @@ +use crate::alphabet::{Alphabet, DecodeStep, EncodeStep}; + +/// PBKDF2 Base64: variant of unpadded standard Base64 with `.` instead of `+`. +/// +/// ```text +/// [A-Z] [a-z] [0-9] . / +/// 0x41-0x5a, 0x61-0x7a, 0x30-0x39, 0x2e, 0x2f +/// ``` +#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct Base64Pbkdf2; + +impl Alphabet for Base64Pbkdf2 { + const BASE: u8 = b'A'; + const DECODER: &'static [DecodeStep] = DECODER; + const ENCODER: &'static [EncodeStep] = ENCODER; + const PADDED: bool = false; + type Unpadded = Self; +} + +const DECODER: &[DecodeStep] = &[ + DecodeStep::Range(b'A'..=b'Z', -64), + DecodeStep::Range(b'a'..=b'z', -70), + DecodeStep::Range(b'0'..=b'9', 5), + DecodeStep::Eq(b'.', 63), + DecodeStep::Eq(b'/', 64), +]; + +const ENCODER: &[EncodeStep] = &[ + EncodeStep::Diff(25, 6), + EncodeStep::Diff(51, -75), + EncodeStep::Diff(61, -(b'.' as i16 - 0x22)), + EncodeStep::Diff(62, b'/' as i16 - b'.' as i16 - 1), +]; diff --git a/base64ct/src/alphabet/shacrypt.rs b/base64ct/src/alphabet/shacrypt.rs index bf18b2bf0..53079c5dd 100644 --- a/base64ct/src/alphabet/shacrypt.rs +++ b/base64ct/src/alphabet/shacrypt.rs @@ -2,23 +2,20 @@ use super::{Alphabet, DecodeStep, EncodeStep}; -/// Little endian variant of the `crypt(3)` Base64 encoding. +/// `crypt(3)` Base64 encoding. /// -/// Used by the following schemes: -/// - md5_crypt +/// This is the standard Base64 encoding used by password hashes for the following schemes: +/// - MD5-Crypt /// - scrypt -/// - sha1_crypt -/// - sha256_crypt -/// - sha512_crypt +/// - SHA1-Crypt +/// - SHA256-Crypt +/// - SHA512-Crypt /// - yescrypt /// /// ```text /// [.-9] [A-Z] [a-z] /// 0x2e-0x39, 0x41-0x5a, 0x61-0x7a /// ``` -/// -/// This uses the same alphabet as [`Base64Crypt`][`crate::Base64Crypt`], but uses a little endian -/// variant of Base64. #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct Base64ShaCrypt; diff --git a/base64ct/src/lib.rs b/base64ct/src/lib.rs index 0b107c480..2c44c6132 100644 --- a/base64ct/src/lib.rs +++ b/base64ct/src/lib.rs @@ -89,7 +89,7 @@ mod test_vectors; pub use crate::{ alphabet::{ bcrypt::Base64Bcrypt, - crypt::Base64Crypt, + pbkdf2::Base64Pbkdf2, shacrypt::Base64ShaCrypt, standard::{Base64, Base64Unpadded}, url::{Base64Url, Base64UrlUnpadded}, @@ -101,5 +101,8 @@ pub use crate::{ line_ending::LineEnding, }; +#[allow(deprecated)] +pub use crate::alphabet::crypt::Base64Crypt; + /// Minimum supported line width. const MIN_LINE_WIDTH: usize = 4; diff --git a/base64ct/tests/crypt.rs b/base64ct/tests/crypt.rs index cc285f9bd..b7ec44bb9 100644 --- a/base64ct/tests/crypt.rs +++ b/base64ct/tests/crypt.rs @@ -1,5 +1,7 @@ //! `crypt(3)` Base64 tests +#![allow(deprecated)] + #[macro_use] mod common; diff --git a/base64ct/tests/pbkdf2.rs b/base64ct/tests/pbkdf2.rs new file mode 100644 index 000000000..543a836ab --- /dev/null +++ b/base64ct/tests/pbkdf2.rs @@ -0,0 +1,78 @@ +//! PBKDF2 MCF variant of Base64 + +#[macro_use] +mod common; + +use crate::common::*; +use base64ct::Base64Pbkdf2; + +const TEST_VECTORS: &[TestVector] = &[ + TestVector { raw: b"", b64: "" }, + TestVector { + raw: b"\0", + b64: "AA", + }, + TestVector { + raw: b"***", + b64: "Kioq", + }, + TestVector { + raw: b"\x01\x02\x03\x04", + b64: "AQIDBA", + }, + TestVector { + raw: b"\xAD\xAD\xAD\xAD\xAD", + b64: "ra2tra0", + }, + TestVector { + raw: b"\xFF\xEF\xFE\xFF\xEF\xFE", + b64: "/./././.", + }, + TestVector { + raw: b"\xFF\xFF\xFF\xFF\xFF", + b64: "//////8", + }, + TestVector { + raw: b"\x40\xC1\x3F\xBD\x05\x4C\x72\x2A\xA3\xC2\xF2\x11\x73\xC0\x69\xEA\ + \x49\x7D\x35\x29\x6B\xCC\x24\x65\xF6\xF9\xD0\x41\x08\x7B\xD7\xA9", + b64: "QME/vQVMciqjwvIRc8Bp6kl9NSlrzCRl9vnQQQh716k", + }, + TestVector { + raw: b"\x00\x10\x83\x10Q\x87 \x92\x8B0\xD3\x8FA\x14\x93QU\x97a\x96\x9Bq\ + \xD7\x9F\x82\x18\xA3\x92Y\xA7\xA2\x9A\xAB\xB2\xDB\xAF\xC3\x1C\xB3\ + \xFB\xF0\x00", + b64: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./AA", + }, +]; + +impl_tests!(Base64Pbkdf2); + +#[test] +fn reject_trailing_whitespace() { + let input = "EA2zjEJAQWeXkj6FQw/duYZxBGZfn0FZxjbEEEVvpuY\n"; + let mut buf = [0u8; 1024]; + assert_eq!( + Base64Pbkdf2::decode(input, &mut buf), + Err(Error::InvalidEncoding) + ); +} + +#[test] +fn reject_trailing_equals() { + let input = "EA2zjEJAQWeXkj6FQw/duYZxBGZfn0FZxjbEEEVvpuY="; + let mut buf = [0u8; 1024]; + assert_eq!( + Base64Pbkdf2::decode(input, &mut buf), + Err(Error::InvalidEncoding) + ); +} + +#[test] +fn reject_non_canonical_encoding() { + let input = "Mi"; + let mut buf = [0u8; 8]; + assert_eq!( + Base64Pbkdf2::decode(input, &mut buf), + Err(Error::InvalidEncoding) + ); +} diff --git a/cmpv2/Cargo.toml b/cmpv2/Cargo.toml index e16ac9647..c970795a4 100644 --- a/cmpv2/Cargo.toml +++ b/cmpv2/Cargo.toml @@ -19,10 +19,10 @@ rust-version = "1.85" crmf = "=0.3.0-pre.0" der = { version = "0.8.0-rc.10", features = ["alloc", "derive", "flagset", "oid"] } spki = "0.8.0-rc.4" -x509-cert = { version = "0.3.0-rc.0", default-features = false } +x509-cert = { version = "0.3.0-rc.3", default-features = false } # optional features -digest = { version = "0.11.0-rc.4", optional = true, default-features = false } +digest = { version = "0.11.0-rc.5", optional = true, default-features = false } [dev-dependencies] const-oid = { version = "0.10", features = ["db"] } diff --git a/cms/Cargo.toml b/cms/Cargo.toml index 90ce025fe..c9d11b750 100644 --- a/cms/Cargo.toml +++ b/cms/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cms" -version = "0.3.0-pre.0" +version = "0.3.0-pre.1" description = """ Pure Rust implementation of the Cryptographic Message Syntax (CMS) as described in RFC 5652 and RFC 3274. """ @@ -18,36 +18,36 @@ rust-version = "1.85" const-oid = { version = "0.10", features = ["db"] } der = { version = "0.8.0-rc.10", features = ["ber", "derive", "oid"] } spki = "0.8.0-rc.4" -x509-cert = { version = "0.3.0-rc.2", default-features = false } +x509-cert = { version = "0.3.0-rc.3", default-features = false } # optional dependencies aes = { version = "0.9.0-rc.2", optional = true } aes-kw = { version = "0.3.0-rc.1", optional = true } ansi-x963-kdf = { version = "0.1.0-rc.1", optional = true } cbc = { version = "0.2.0-rc.2", optional = true } -cipher = { version = "0.5.0-rc.2", features = ["alloc", "block-padding", "rand_core"], optional = true } -digest = { version = "0.11.0-rc.4", optional = true } -elliptic-curve = { version = "0.14.0-rc.16", optional = true } -rsa = { version = "0.10.0-rc.10", optional = true } +cipher = { version = "0.5.0-rc.3", features = ["alloc", "block-padding", "rand_core"], optional = true } +digest = { version = "0.11.0-rc.5", optional = true } +elliptic-curve = { version = "0.14.0-rc.21", optional = true } +rsa = { version = "0.10.0-rc.11", optional = true } sha1 = { version = "0.11.0-rc.3", optional = true } sha2 = { version = "0.11.0-rc.3", optional = true } sha3 = { version = "0.11.0-rc.3", optional = true } -signature = { version = "3.0.0-rc.5", features = ["digest", "alloc"], optional = true } +signature = { version = "3.0.0-rc.6", features = ["digest", "alloc"], optional = true } zeroize = { version = "1.8.1", optional = true } [dev-dependencies] aes = "0.9.0-rc.2" -getrandom = "0.3" +getrandom = "0.4.0-rc.0" hex-literal = "1" pem-rfc7468 = "1" -pkcs5 = "0.8.0-rc.10" -pbkdf2 = "0.13.0-rc.2" -rand = "0.10.0-rc.1" -rsa = { version = "0.10.0-rc.10", features = ["sha2"] } -ecdsa = { version = "0.17.0-rc.6", features = ["digest", "pem"] } -p256 = "0.14.0-rc.1" +pkcs5 = "0.8.0-rc.12" +pbkdf2 = "0.13.0-rc.6" +rand = "0.10.0-rc.6" +rsa = { version = "0.10.0-rc.11", features = ["sha2"] } +ecdsa = { version = "0.17.0-rc.12", features = ["digest", "pem"] } +p256 = "0.14.0-rc.4" tokio = { version = "1.45.1", features = ["macros", "rt"] } -x509-cert = { version = "0.3.0-rc.0", features = ["pem"] } +x509-cert = { version = "0.3.0-rc.3", features = ["pem"] } [features] std = ["der/std", "x509-cert/std", "spki/std"] diff --git a/cms/src/builder.rs b/cms/src/builder.rs index e37ae2105..c79fb824e 100644 --- a/cms/src/builder.rs +++ b/cms/src/builder.rs @@ -1,34 +1,43 @@ -#![cfg(feature = "builder")] +//! Cryptographic Message Syntax Builder -//! CMS Builder +#![cfg(feature = "builder")] -use crate::cert::CertificateChoices; -use crate::content_info::{CmsVersion, ContentInfo}; -use crate::enveloped_data::{ - EncryptedContentInfo, EncryptedKey, EnvelopedData, KekIdentifier, KeyTransRecipientInfo, - OriginatorInfo, PasswordRecipientInfo, RecipientIdentifier, RecipientInfo, RecipientInfos, - UserKeyingMaterial, -}; -use crate::revocation::{RevocationInfoChoice, RevocationInfoChoices}; -use crate::signed_data::{ - CertificateSet, DigestAlgorithmIdentifiers, EncapsulatedContentInfo, SignatureValue, - SignedAttributes, SignedData, SignerIdentifier, SignerInfo, SignerInfos, UnsignedAttributes, +use crate::{ + cert::CertificateChoices, + content_info::{CmsVersion, ContentInfo}, + enveloped_data::{ + EncryptedContentInfo, EncryptedKey, EnvelopedData, KekIdentifier, KeyTransRecipientInfo, + OriginatorInfo, PasswordRecipientInfo, RecipientIdentifier, RecipientInfo, RecipientInfos, + UserKeyingMaterial, + }, + revocation::{RevocationInfoChoice, RevocationInfoChoices}, + signed_data::{ + CertificateSet, DigestAlgorithmIdentifiers, EncapsulatedContentInfo, SignatureValue, + SignedAttributes, SignedData, SignerIdentifier, SignerInfo, SignerInfos, + UnsignedAttributes, + }, }; use aes::{Aes128, Aes192, Aes256}; -use alloc::borrow::ToOwned; -use alloc::boxed::Box; -use alloc::string::{String, ToString}; -use alloc::vec::Vec; +use alloc::{ + borrow::ToOwned, + boxed::Box, + string::{String, ToString}, + vec, + vec::Vec, +}; use cipher::{ - BlockModeEncrypt, Key, KeyIvInit, KeySizeUser, block_padding::Pkcs7, rand_core::CryptoRng, + BlockModeEncrypt, Iv, Key, KeyIvInit, + block_padding::Pkcs7, + crypto_common::Generate, + rand_core::{CryptoRng, RngCore}, }; use const_oid::ObjectIdentifier; -use core::cmp::Ordering; -use core::fmt; -use core::marker::PhantomData; -use der::asn1::{BitString, Null, OctetString, OctetStringRef, SetOfVec}; -use der::oid::db::DB; -use der::{Any, AnyRef, Decode, Encode, ErrorKind, Tag}; +use core::{cmp::Ordering, fmt, marker::PhantomData}; +use der::{ + Any, AnyRef, Decode, Encode, ErrorKind, Tag, + asn1::{BitString, Null, OctetString, OctetStringRef, SetOfVec}, + oid::db::DB, +}; use digest::Digest; use rsa::Pkcs1v15Encrypt; use sha2::digest; @@ -39,7 +48,6 @@ use spki::{ AlgorithmIdentifierOwned, DynSignatureAlgorithmIdentifier, EncodePublicKey, SignatureBitStringEncoding, }; -use std::vec; use x509_cert::{ attr::{Attribute, AttributeValue, Attributes}, builder::{self, AsyncBuilder, Builder}, @@ -431,7 +439,7 @@ impl<'s> SignedDataBuilder<'s> { S: RandomizedSigner, S::VerifyingKey: EncodePublicKey, Signature: SignatureBitStringEncoding, - R: CryptoRng + ?Sized, + R: CryptoRng + RngCore + ?Sized, { let signer_info = signer_info_builder .build_with_rng::(signer, rng) @@ -476,7 +484,7 @@ impl<'s> SignedDataBuilder<'s> { S: AsyncRandomizedSigner, S::VerifyingKey: EncodePublicKey, Signature: SignatureBitStringEncoding, - R: CryptoRng + ?Sized, + R: CryptoRng + RngCore + ?Sized, { let signer_info = signer_info_builder .build_with_rng_async::(signer, rng) @@ -600,7 +608,7 @@ impl<'s> SignedDataBuilder<'s> { /// formats. All implementations must implement this trait. pub trait RecipientInfoBuilder { /// Associated Rng type - type Rng: CryptoRng + ?Sized; + type Rng: CryptoRng + RngCore + ?Sized; /// Return the recipient info type fn recipient_info_type(&self) -> RecipientInfoType; @@ -662,9 +670,9 @@ impl KeyTransRecipientInfoBuilder { } } -impl RecipientInfoBuilder for KeyTransRecipientInfoBuilder +impl RecipientInfoBuilder for KeyTransRecipientInfoBuilder where - R: CryptoRng, + R: CryptoRng + RngCore + ?Sized, { type Rng = R; @@ -733,9 +741,9 @@ impl KekRecipientInfoBuilder { } } -impl RecipientInfoBuilder for KekRecipientInfoBuilder +impl RecipientInfoBuilder for KekRecipientInfoBuilder where - R: CryptoRng, + R: CryptoRng + RngCore + ?Sized, { type Rng = R; @@ -776,7 +784,7 @@ pub trait PwriEncryptor { /// including eventual parameters (e.g. the used iv). fn key_encryption_algorithm(&self) -> Result; /// Encrypt the padded content-encryption key twice following RFC 3211, § 2.3.1 - fn encrypt_rfc3211( + fn encrypt_rfc3211( &mut self, padded_content_encryption_key: &[u8], rng: &mut R, @@ -824,10 +832,10 @@ where } } -impl PasswordRecipientInfoBuilder +impl PasswordRecipientInfoBuilder where P: PwriEncryptor, - R: CryptoRng, + R: CryptoRng + RngCore + ?Sized, { /// Wrap the content-encryption key according to [RFC 3211, §2.3.1]: /// .... @@ -868,7 +876,7 @@ where impl RecipientInfoBuilder for PasswordRecipientInfoBuilder where P: PwriEncryptor, - R: CryptoRng + ?Sized, + R: CryptoRng + RngCore + ?Sized, { type Rng = R; @@ -927,7 +935,7 @@ impl OtherRecipientInfoBuilder { impl RecipientInfoBuilder for OtherRecipientInfoBuilder where - R: CryptoRng + ?Sized, + R: CryptoRng + RngCore + ?Sized, { type Rng = R; @@ -1011,7 +1019,7 @@ impl<'c, R> EnvelopedDataBuilder<'c, R> { impl<'c, R> EnvelopedDataBuilder<'c, R> where - R: CryptoRng + ?Sized, + R: CryptoRng + RngCore + ?Sized, { /// Add recipient info. A builder is used, which generates a `RecipientInfo` according to /// RFC 5652 § 6.2, when `EnvelopedData` is built. @@ -1172,18 +1180,16 @@ fn get_hasher( macro_rules! encrypt_block_mode { ($data:expr, $block_mode:ident::$typ:ident<$alg:ident>, $key:expr, $rng:expr, $oid:expr) => {{ let (key, iv) = match $key { - None => $block_mode::$typ::<$alg>::generate_key_iv_with_rng($rng), + None => { + let key = Key::<$block_mode::$typ<$alg>>::generate_from_rng($rng); + let iv = Iv::<$block_mode::$typ<$alg>>::generate_from_rng($rng); + (key, iv) + } Some(key) => { - if key.len() != $alg::key_size() { - return Err(Error::Builder(String::from( - "Invalid key size for chosen algorithm", - ))); - } - ( - Key::<$block_mode::$typ<$alg>>::try_from(key) - .expect("size invariants violation"), - $block_mode::$typ::<$alg>::generate_iv_with_rng($rng), - ) + let key = Key::<$block_mode::$typ<$alg>>::try_from(key) + .map_err(|_| Error::Builder("invalid key size for chosen algorithm".into()))?; + let iv = Iv::<$block_mode::$typ<$alg>>::generate_from_rng($rng); + (key, iv) } }; let encryptor = $block_mode::$typ::<$alg>::new(&key.into(), &iv.into()); @@ -1210,7 +1216,7 @@ fn encrypt_data( rng: &mut R, ) -> Result<(Vec, Vec, AlgorithmIdentifierOwned)> where - R: CryptoRng + ?Sized, + R: CryptoRng + RngCore + ?Sized, { match encryption_algorithm_identifier { ContentEncryptionAlgorithm::Aes128Cbc => encrypt_block_mode!( diff --git a/cms/src/builder/kari.rs b/cms/src/builder/kari.rs index 88564c7ee..15760c5fb 100644 --- a/cms/src/builder/kari.rs +++ b/cms/src/builder/kari.rs @@ -8,7 +8,7 @@ // Super imports use super::{ - AlgorithmIdentifierOwned, CryptoRng, RecipientInfoBuilder, RecipientInfoType, Result, + AlgorithmIdentifierOwned, CryptoRng, RecipientInfoBuilder, RecipientInfoType, Result, RngCore, UserKeyingMaterial, utils::kw::{KeyWrapAlgorithm, WrappedKey}, }; @@ -45,7 +45,7 @@ use aes::cipher::{ }; use digest::{Digest, FixedOutputReset}; use elliptic_curve::{ - AffinePoint, Curve, CurveArithmetic, FieldBytesSize, PublicKey, + AffinePoint, Curve, CurveArithmetic, FieldBytesSize, Generate, PublicKey, ecdh::{EphemeralSecret, SharedSecret}, point::PointCompression, sec1::{FromEncodedPoint, ModulusSize, ToEncodedPoint}, @@ -250,10 +250,9 @@ where }) } } -impl RecipientInfoBuilder - for KeyAgreeRecipientInfoBuilder +impl RecipientInfoBuilder for KeyAgreeRecipientInfoBuilder where - R: CryptoRng, + R: CryptoRng + RngCore + ?Sized, KA: KeyAgreementAlgorithm + AssociatedOid, C: CurveArithmetic + AssociatedOid + PointCompression, AffinePoint: FromEncodedPoint + ToEncodedPoint, @@ -305,7 +304,7 @@ where ) = match self.eckey_encryption_info { EcKeyEncryptionInfo::Ec(recipient_public_key) => { // Generate ephemeral key using ecdh - let Ok(ephemeral_secret) = EphemeralSecret::try_from_rng(rng); + let ephemeral_secret = EphemeralSecret::generate_from_rng(rng); let ephemeral_public_key_encoded_point = ephemeral_secret.public_key().to_encoded_point(false); diff --git a/cms/tests/builder.rs b/cms/tests/builder.rs index 4fb3bc209..eae6ac47c 100644 --- a/cms/tests/builder.rs +++ b/cms/tests/builder.rs @@ -21,9 +21,9 @@ use der::{Any, AnyRef, Decode, DecodePem, Encode, Tag, Tagged}; use p256::{NistP256, pkcs8::DecodePrivateKey}; use pem_rfc7468::LineEnding; use pkcs5::pbes2::Pbkdf2Params; -use rand::rngs::OsRng; +use rand::rngs::SysRng; use rsa::pkcs1::DecodeRsaPrivateKey; -use rsa::rand_core::{CryptoRng, TryRngCore}; +use rsa::rand_core::{CryptoRng, RngCore, TryRngCore}; use rsa::{Pkcs1v15Encrypt, RsaPrivateKey, RsaPublicKey}; use rsa::{pkcs1v15, pss}; use sha2::Sha256; @@ -159,7 +159,7 @@ fn test_build_signed_data() { .add_signer_info_with_rng::, pss::Signature, _>( signer_info_builder_3, &signer_3, - &mut OsRng.unwrap_err(), + &mut SysRng.unwrap_err(), ) .expect("error adding PKCS1v15 RSA signer info") .build() @@ -183,7 +183,7 @@ fn test_build_signed_data() { #[test] fn test_build_enveloped_data() { let recipient_identifier = recipient_identifier(1); - let mut rng = OsRng.unwrap_err(); + let mut rng = SysRng.unwrap_err(); let bits = 2048; let recipient_private_key = RsaPrivateKey::new(&mut rng, bits).expect("failed to generate a key"); @@ -195,7 +195,7 @@ fn test_build_enveloped_data() { ) .expect("Could not create a KeyTransRecipientInfoBuilder"); - let mut rng = OsRng.unwrap_err(); + let mut rng = SysRng.unwrap_err(); let mut builder = EnvelopedDataBuilder::new( None, "Arbitrary unencrypted content".as_bytes(), @@ -657,7 +657,7 @@ async fn async_builder() { .add_signer_info_with_rng_async::, pss::Signature, _>( signer_info_builder_3, &signer_3, - &mut OsRng.unwrap_err(), + &mut SysRng.unwrap_err(), ) .await .expect("error adding PKCS1v15 RSA signer info") @@ -690,7 +690,10 @@ fn test_create_password_recipient_info() { key_derivation_params: pkcs5::pbes2::Pbkdf2Params, } impl<'a> Aes128CbcPwriEncryptor<'a> { - pub fn new(challenge_password: &'a [u8], rng: &mut R) -> Self { + pub fn new( + challenge_password: &'a [u8], + rng: &mut R, + ) -> Self { let mut key_encryption_iv = [0u8; 16]; rng.fill_bytes(key_encryption_iv.as_mut_slice()); let key_encryption_iv = key_encryption_iv.into(); @@ -708,7 +711,7 @@ fn test_create_password_recipient_info() { } impl PwriEncryptor for Aes128CbcPwriEncryptor<'_> { const BLOCK_LENGTH_BITS: usize = 128; // AES block length - fn encrypt_rfc3211( + fn encrypt_rfc3211( &mut self, padded_content_encryption_key: &[u8], _rng: &mut R, @@ -897,7 +900,7 @@ fn test_create_password_recipient_info() { content_encryption_key } - let mut the_one_and_only_rng = OsRng.unwrap_err(); + let mut the_one_and_only_rng = SysRng.unwrap_err(); // Encrypt the content-encryption key (CEK) using custom encryptor // of type `Aes128CbcPwriEncryptor`: diff --git a/cms/tests/builder/kari.rs b/cms/tests/builder/kari.rs index 0f2d7f930..ff627b0aa 100644 --- a/cms/tests/builder/kari.rs +++ b/cms/tests/builder/kari.rs @@ -11,7 +11,7 @@ use cms::{ use der::{Any, AnyRef, Encode}; use p256::{SecretKey, pkcs8::DecodePrivateKey}; use pem_rfc7468::LineEnding; -use rand::{TryRngCore, rngs::OsRng}; +use rand::{TryRngCore, rngs::SysRng}; use x509_cert::serial_number::SerialNumber; fn key_agreement_recipient_identifier(id: i32) -> KeyAgreeRecipientIdentifier { @@ -55,7 +55,7 @@ fn test_build_enveloped_data_ec() { .expect("Could not create a KeyAgreeRecipientInfoBuilder"); // Enveloped data builder - let mut rng = OsRng.unwrap_err(); + let mut rng = SysRng.unwrap_err(); let mut builder = EnvelopedDataBuilder::new( None, "Arbitrary unencrypted content, encrypted using ECC".as_bytes(), diff --git a/const-oid/CHANGELOG.md b/const-oid/CHANGELOG.md index c9867ea26..26f1558dc 100644 --- a/const-oid/CHANGELOG.md +++ b/const-oid/CHANGELOG.md @@ -4,6 +4,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.10.2 (2026-01-07) +### Added +- `ObjectIdentifier::from_bytes_sized` which ensures OIDs use all available space in the backing + array ([#1852]) +- Microsoft and Kerberos OIDs ([#2035]) + +### Fixed +- Switch from `doc_auto_cfg` to `doc_cfg` ([#2072]) + +[#1852]: https://github.com/RustCrypto/formats/pull/1852 +[#2035]: https://github.com/RustCrypto/formats/pull/2035 +[#2072]: https://github.com/RustCrypto/formats/pull/2072 + ## 0.10.1 (2025-04-08) ### Added - RFC9688 OIDs ([#1692]) diff --git a/const-oid/Cargo.toml b/const-oid/Cargo.toml index 73e394870..32c598d27 100644 --- a/const-oid/Cargo.toml +++ b/const-oid/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "const-oid" -version = "0.10.1" +version = "0.10.2" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" description = """ diff --git a/const-oid/LICENSE-MIT b/const-oid/LICENSE-MIT index 0cd648f76..b135e18de 100644 --- a/const-oid/LICENSE-MIT +++ b/const-oid/LICENSE-MIT @@ -1,4 +1,4 @@ -Copyright (c) 2020-2025 The RustCrypto Project Developers +Copyright (c) 2020-2026 The RustCrypto Project Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated diff --git a/crmf/Cargo.toml b/crmf/Cargo.toml index 0e0629aba..fb992edb2 100644 --- a/crmf/Cargo.toml +++ b/crmf/Cargo.toml @@ -16,10 +16,10 @@ edition = "2024" rust-version = "1.85" [dependencies] -cms = "=0.3.0-pre.0" +cms = "=0.3.0-pre.1" der = { version = "0.8.0-rc.10", features = ["alloc", "derive"] } spki = "0.8.0-rc.3" -x509-cert = { version = "0.3.0-rc.0", default-features = false } +x509-cert = { version = "0.3.0-rc.3", default-features = false } [dev-dependencies] const-oid = "0.10" diff --git a/der/src/decode.rs b/der/src/decode.rs index b003bec1f..12fc538d5 100644 --- a/der/src/decode.rs +++ b/der/src/decode.rs @@ -54,7 +54,7 @@ use crate::EncodingRules; )] pub trait Decode<'a>: Sized + 'a { /// Type returned in the event of a decoding error. - type Error: From + 'static; + type Error: core::error::Error + From + 'static; /// Attempt to decode this TLV message using the provided decoder. fn decode>(decoder: &mut R) -> Result; @@ -193,7 +193,7 @@ impl + PemLabel> DecodePem for T { /// ``` pub trait DecodeValue<'a>: Sized { /// Type returned in the event of a decoding error. - type Error: From + 'static; + type Error: core::error::Error + From + 'static; /// Attempt to decode this value using the provided [`Reader`]. fn decode_value>(reader: &mut R, header: Header) -> Result; @@ -217,7 +217,7 @@ where T: ToOwned + ?Sized, &'a T: DecodeValue<'a, Error = E>, T::Owned: for<'b> DecodeValue<'b, Error = E>, - E: From + 'static, + E: core::error::Error + From + 'static, { type Error = E; diff --git a/der/tests/derive.rs b/der/tests/derive.rs index ebb71bfe0..69d701dec 100644 --- a/der/tests/derive.rs +++ b/der/tests/derive.rs @@ -15,13 +15,21 @@ #[allow(dead_code)] pub struct CustomError(der::Error); +impl core::error::Error for CustomError {} + +impl core::fmt::Display for CustomError { + fn fmt(&self, _: &mut core::fmt::Formatter) -> core::fmt::Result { + unimplemented!() + } +} + impl From for CustomError { fn from(value: der::Error) -> Self { Self(value) } } -impl From for CustomError { +impl From for CustomError { fn from(_value: std::convert::Infallible) -> Self { unreachable!() } diff --git a/gss-api/Cargo.toml b/gss-api/Cargo.toml index a0a674db4..6ab03f1d9 100644 --- a/gss-api/Cargo.toml +++ b/gss-api/Cargo.toml @@ -18,12 +18,12 @@ rust-version = "1.85" [dependencies] der = { version = "0.8.0-rc.10", features = ["oid", "alloc"] } spki = "0.8.0-rc.4" -x509-cert = { version = "0.3.0-rc.0", default-features = false } +x509-cert = { version = "0.3.0-rc.3", default-features = false } [dev-dependencies] der = { version = "0.8.0-rc.10", features = ["oid", "pem", "alloc"] } hex-literal = "1" -x509-cert = { version = "0.3.0-rc.0", default-features = false, features = ["pem"] } +x509-cert = { version = "0.3.0-rc.3", default-features = false, features = ["pem"] } [features] rfc2478 = [] diff --git a/mcf/Cargo.toml b/mcf/Cargo.toml index dd0c6fe01..bbd8f77c6 100644 --- a/mcf/Cargo.toml +++ b/mcf/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mcf" -version = "0.6.0-pre" +version = "0.6.0-rc.3" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" @@ -15,7 +15,7 @@ in the form `${id}$...` """ [dependencies] -base64ct = { version = "1.7", optional = true } +base64ct = { version = "1.8.3", optional = true } [dev-dependencies] hex-literal = "1" diff --git a/mcf/src/base64.rs b/mcf/src/base64.rs index 50196c6e1..a08e2835a 100644 --- a/mcf/src/base64.rs +++ b/mcf/src/base64.rs @@ -2,7 +2,10 @@ #![cfg(feature = "base64")] -use base64ct::{Base64Bcrypt, Base64Crypt, Base64ShaCrypt, Encoding as _, Error as B64Error}; +use base64ct::{ + Base64Bcrypt, Base64Pbkdf2, Base64ShaCrypt, Base64Unpadded as B64, Encoding as _, + Error as B64Error, +}; #[cfg(feature = "alloc")] use alloc::{string::String, vec::Vec}; @@ -11,6 +14,15 @@ use alloc::{string::String, vec::Vec}; #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] #[non_exhaustive] pub enum Base64 { + /// "B64" encoding: standard Base64 without padding, as used by the PHC string format. + /// + /// ```text + /// [A-Z] [a-z] [0-9] + / + /// 0x41-0x5a, 0x61-0x7a, 0x30-0x39, 0x2b, 0x2f + /// ``` + /// + B64, + /// bcrypt encoding. /// /// ```text @@ -19,7 +31,15 @@ pub enum Base64 { /// ``` Bcrypt, - /// `crypt(3)` encoding. + /// `crypt(3)` Base64 encoding. + /// + /// Used by the following schemes: + /// - MD5-Crypt + /// - scrypt + /// - SHA1-Crypt + /// - SHA256-Crypt + /// - SHA512-Crypt + /// - yescrypt /// /// ```text /// [.-9] [A-Z] [a-z] @@ -27,26 +47,25 @@ pub enum Base64 { /// ``` Crypt, - /// `crypt(3)` Base64 encoding for the following schemes: - /// - sha1_crypt, - /// - sha256_crypt, - /// - sha512_crypt, - /// - md5_crypt + /// PBKDF2 Base64 encoding. + /// + /// This is a variant of the unpadded standard Base64 with `.` in place of `+`: /// /// ```text - /// [.-9] [A-Z] [a-z] - /// 0x2e-0x39, 0x41-0x5a, 0x61-0x7a + /// [A-Z] [a-z] [0-9] . / + /// 0x41-0x5a, 0x61-0x7a, 0x30-0x39, 0x2e, 0x2f /// ``` - ShaCrypt, + Pbkdf2, } impl Base64 { /// Decode a Base64 string into the provided destination buffer. pub fn decode(self, src: impl AsRef<[u8]>, dst: &mut [u8]) -> Result<&[u8], B64Error> { match self { + Self::B64 => B64::decode(src, dst), Self::Bcrypt => Base64Bcrypt::decode(src, dst), - Self::Crypt => Base64Crypt::decode(src, dst), - Self::ShaCrypt => Base64ShaCrypt::decode(src, dst), + Self::Crypt => Base64ShaCrypt::decode(src, dst), + Self::Pbkdf2 => Base64Pbkdf2::decode(src, dst), } } @@ -54,9 +73,10 @@ impl Base64 { #[cfg(feature = "alloc")] pub fn decode_vec(self, input: &str) -> Result, B64Error> { match self { + Self::B64 => B64::decode_vec(input), Self::Bcrypt => Base64Bcrypt::decode_vec(input), - Self::Crypt => Base64Crypt::decode_vec(input), - Self::ShaCrypt => Base64ShaCrypt::decode_vec(input), + Self::Crypt => Base64ShaCrypt::decode_vec(input), + Self::Pbkdf2 => Base64Pbkdf2::decode_vec(input), } } @@ -66,9 +86,10 @@ impl Base64 { /// ASCII-encoded Base64 string value. pub fn encode<'a>(self, src: &[u8], dst: &'a mut [u8]) -> Result<&'a str, B64Error> { match self { + Self::B64 => B64::encode(src, dst), Self::Bcrypt => Base64Bcrypt::encode(src, dst), - Self::Crypt => Base64Crypt::encode(src, dst), - Self::ShaCrypt => Base64ShaCrypt::encode(src, dst), + Self::Crypt => Base64ShaCrypt::encode(src, dst), + Self::Pbkdf2 => Base64Pbkdf2::encode(src, dst), } .map_err(Into::into) } @@ -80,18 +101,20 @@ impl Base64 { #[cfg(feature = "alloc")] pub fn encode_string(self, input: &[u8]) -> String { match self { + Self::B64 => B64::encode_string(input), Self::Bcrypt => Base64Bcrypt::encode_string(input), - Self::Crypt => Base64Crypt::encode_string(input), - Self::ShaCrypt => Base64ShaCrypt::encode_string(input), + Self::Crypt => Base64ShaCrypt::encode_string(input), + Self::Pbkdf2 => Base64Pbkdf2::encode_string(input), } } /// Get the length of Base64 produced by encoding the given bytes. pub fn encoded_len(self, bytes: &[u8]) -> usize { match self { + Self::B64 => B64::encoded_len(bytes), Self::Bcrypt => Base64Bcrypt::encoded_len(bytes), - Self::Crypt => Base64Crypt::encoded_len(bytes), - Self::ShaCrypt => Base64ShaCrypt::encoded_len(bytes), + Self::Crypt => Base64ShaCrypt::encoded_len(bytes), + Self::Pbkdf2 => Base64Pbkdf2::encoded_len(bytes), } } } diff --git a/mcf/src/error.rs b/mcf/src/error.rs index c6807f5a5..80b313c96 100644 --- a/mcf/src/error.rs +++ b/mcf/src/error.rs @@ -2,24 +2,69 @@ use core::fmt; +#[cfg(feature = "base64")] +use base64ct::Error as B64Error; + /// Result type for `mcf`. pub type Result = core::result::Result; /// Error type. #[derive(Copy, Clone, Debug, Eq, PartialEq)] #[non_exhaustive] -pub struct Error {} +pub enum Error { + /// Base64 encoding errors. + #[cfg(feature = "base64")] + Base64(B64Error), + + /// `$` delimiter either missing or in an unexpected place + DelimiterInvalid, + + /// Encoding validation failure or error during encode time + EncodingInvalid, + + /// MCF field (between `$` characters) is not well-formed + FieldInvalid, + + /// MCF identifier missing + IdentifierMissing, + + /// MCF identifier invalid (must be `a-z`, `0-9`, or `-`) + IdentifierInvalid, +} -impl core::error::Error for Error {} +impl core::error::Error for Error { + fn source(&self) -> Option<&(dyn core::error::Error + 'static)> { + match self { + #[cfg(feature = "base64")] + Error::Base64(e) => Some(e), + _ => None, + } + } +} impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("modular crypt format error") + match self { + #[cfg(feature = "base64")] + Error::Base64(base64_err) => write!(f, "{base64_err}"), + Error::DelimiterInvalid => write!(f, "invalid use of `$` delimiter"), + Error::EncodingInvalid => write!(f, "invalid MCF encoding"), + Error::FieldInvalid => write!(f, "invalid MCF field (between `$` characters)"), + Error::IdentifierMissing => write!(f, "MCF identifier missing"), + Error::IdentifierInvalid => write!(f, "MCF identifier invalid"), + } + } +} + +#[cfg(feature = "base64")] +impl From for Error { + fn from(base64_err: B64Error) -> Self { + Error::Base64(base64_err) } } impl From for Error { fn from(_: fmt::Error) -> Self { - Error {} + Error::EncodingInvalid } } diff --git a/mcf/src/fields.rs b/mcf/src/fields.rs index 52e47728d..f1447b7a5 100644 --- a/mcf/src/fields.rs +++ b/mcf/src/fields.rs @@ -74,25 +74,25 @@ impl<'a> Field<'a> { /// Decode Base64 into the provided output buffer. #[cfg(feature = "base64")] pub fn decode_base64_into(self, base64_variant: Base64, out: &mut [u8]) -> Result<&[u8]> { - base64_variant.decode(self.0, out).map_err(|_| Error {}) + Ok(base64_variant.decode(self.0, out)?) } /// Decode this field as the provided Base64 variant. #[cfg(all(feature = "alloc", feature = "base64"))] pub fn decode_base64(self, base64_variant: Base64) -> Result> { - base64_variant.decode_vec(self.0).map_err(|_| Error {}) + Ok(base64_variant.decode_vec(self.0)?) } /// Validate a field in the password hash is well-formed. pub(crate) fn validate(self) -> Result<()> { if self.0.is_empty() { - return Err(Error {}); + return Err(Error::FieldInvalid); } for c in self.0.chars() { match c { 'A'..='Z' | 'a'..='z' | '0'..='9' | '.' | '/' | '+' | '=' | ',' | '-' => (), - _ => return Err(Error {}), + _ => return Err(Error::EncodingInvalid), } } diff --git a/mcf/src/lib.rs b/mcf/src/lib.rs index bf02f16c1..4fe79d992 100644 --- a/mcf/src/lib.rs +++ b/mcf/src/lib.rs @@ -113,7 +113,12 @@ impl<'a> TryFrom<&'a str> for &'a PasswordHashRef { mod allocating { use crate::{Error, Field, PasswordHashRef, Result, fields, validate, validate_id}; use alloc::{borrow::ToOwned, string::String}; - use core::{borrow::Borrow, fmt, ops::Deref, str::FromStr}; + use core::{ + borrow::Borrow, + fmt::{self, Write as _}, + ops::Deref, + str::FromStr, + }; #[cfg(feature = "base64")] use crate::Base64; @@ -181,11 +186,27 @@ mod allocating { /// Push a type which impls [`fmt::Display`], first adding a `$` delimiter and ensuring the /// added characters comprise a valid field. + /// + /// # Errors + /// - If the added field fails to validate as a [`Field`] (i.e. contains characters outside + /// the allowed set) + /// - If the [`fmt::Display`] impl returns [`fmt::Error`]. pub fn push_displayable(&mut self, displayable: D) -> Result<()> { - // TODO(tarcieri): avoid intermediate allocation? - let mut buf = String::new(); - fmt::write(&mut buf, format_args!("{}", displayable))?; - self.push_str(&buf) + // Cache original length to truncate back to on error + let old_len = self.0.len(); + self.0.push(fields::DELIMITER); + + if let Err(e) = write!(&mut self.0, "{displayable}") { + self.0.truncate(old_len); + return Err(e.into()); + } + + if let Err(e) = Field::new(&self.0[(old_len + 1)..]) { + self.0.truncate(old_len); + return Err(e); + } + + Ok(()) } /// Push an additional field onto the password hash string, first adding a `$` delimiter. @@ -310,19 +331,19 @@ mod allocating { fn validate(s: &str) -> Result<()> { // Require leading `$` if !s.starts_with(fields::DELIMITER) { - return Err(Error {}); + return Err(Error::DelimiterInvalid); } // Disallow trailing `$` if s.ends_with(fields::DELIMITER) { - return Err(Error {}); + return Err(Error::DelimiterInvalid); } // Validates the hash begins with a leading `$` let mut fields = Fields::new(s); // Validate characters in the identifier field - let id = fields.next().ok_or(Error {})?; + let id = fields.next().ok_or(Error::IdentifierMissing)?; validate_id(id.as_str())?; // Validate the remaining fields have an appropriate format @@ -338,22 +359,122 @@ fn validate(s: &str) -> Result<()> { /// Allowed characters match the regex: `[a-z0-9\-]`, where the first and last characters do NOT /// contain a `-`. fn validate_id(id: &str) -> Result<()> { - let first = id.chars().next().ok_or(Error {})?; - let last = id.chars().last().ok_or(Error {})?; + let first = id.chars().next().ok_or(Error::IdentifierInvalid)?; + let last = id.chars().last().ok_or(Error::IdentifierInvalid)?; for c in [first, last] { match c { 'a'..='z' | '0'..='9' => (), - _ => return Err(Error {}), + _ => return Err(Error::IdentifierInvalid), } } for c in id.chars() { match c { 'a'..='z' | '0'..='9' | '-' => (), - _ => return Err(Error {}), + _ => return Err(Error::IdentifierInvalid), } } Ok(()) } + +#[cfg(all(test, feature = "alloc"))] +#[allow(clippy::unwrap_used)] +mod tests { + use crate::{Error, PasswordHash}; + + #[cfg(feature = "base64")] + use {crate::Base64, hex_literal::hex}; + + const SHA512_HASH: &str = "$6$rounds=100000$exn6tVc2j/MZD8uG$BI1Xh8qQSK9J4m14uwy7abn.ctj/TIAzlaVCto0MQrOFIeTXsc1iwzH16XEWo/a7c7Y9eVJvufVzYAs4EsPOy0"; + + #[cfg(feature = "base64")] + const EXAMPLE_SALT: &[u8] = &hex!("6a3f237988126f80958fa24b"); + #[cfg(feature = "base64")] + const EXAMPLE_HASH: &[u8] = &hex!( + "0d358cad62739eb554863c183aef27e6390368fe061fc5fcb1193a392d60dcad4594fa8d383ab8fc3f0dc8088974602668422e6a58edfa1afe24831b10be69be" + ); + + #[test] + fn from_id() { + let mcf_hash = PasswordHash::from_id("6").unwrap(); + assert_eq!("$6", mcf_hash.as_str()); + } + + #[test] + fn parse_malformed() { + assert!("Hello, world!".parse::().is_err()); + assert!("$".parse::().is_err()); + assert!("$$".parse::().is_err()); + assert!("$$foo".parse::().is_err()); + assert!("$foo$".parse::().is_err()); + assert!("$-$foo".parse::().is_err()); + assert!("$foo-$bar".parse::().is_err()); + assert!("$-foo$bar".parse::().is_err()); + } + + #[test] + fn parse_id_only() { + let hash: PasswordHash = "$6".parse().unwrap(); + assert_eq!("6", hash.id()); + } + + #[test] + fn parse_sha512_hash() { + let hash: PasswordHash = SHA512_HASH.parse().unwrap(); + assert_eq!("6", hash.id()); + + let mut fields = hash.fields(); + assert_eq!("rounds=100000", fields.next().unwrap().as_str()); + + let salt = fields.next().unwrap(); + assert_eq!("exn6tVc2j/MZD8uG", salt.as_str()); + + #[cfg(feature = "base64")] + { + let salt_bytes = salt.decode_base64(Base64::Crypt).unwrap(); + assert_eq!(EXAMPLE_SALT, salt_bytes.as_slice()); + } + + let hash = fields.next().unwrap(); + assert_eq!( + "BI1Xh8qQSK9J4m14uwy7abn.ctj/TIAzlaVCto0MQrOFIeTXsc1iwzH16XEWo/a7c7Y9eVJvufVzYAs4EsPOy0", + hash.as_str() + ); + + #[cfg(feature = "base64")] + { + let hash_bytes = hash.decode_base64(Base64::Crypt).unwrap(); + assert_eq!(EXAMPLE_HASH, hash_bytes.as_slice()); + } + + assert_eq!(None, fields.next()); + } + + #[cfg(feature = "base64")] + #[test] + fn push_base64() { + let mut hash = PasswordHash::new("$6$rounds=100000").unwrap(); + hash.push_base64(EXAMPLE_SALT, Base64::Crypt); + hash.push_base64(EXAMPLE_HASH, Base64::Crypt); + assert_eq!(SHA512_HASH, hash.as_str()); + } + + #[test] + fn push_displayable() { + let mut hash = PasswordHash::from_id("6").unwrap(); + hash.push_displayable("rounds=100000").unwrap(); + assert_eq!("$6$rounds=100000", hash.as_str()); + } + + #[test] + fn push_displayable_malformed() { + let mut hash = PasswordHash::from_id("6").unwrap(); + assert_eq!( + hash.push_displayable("$$$").unwrap_err(), + Error::EncodingInvalid + ); + assert_eq!("$6", hash.as_str()); + } +} diff --git a/mcf/tests/mcf.rs b/mcf/tests/mcf.rs deleted file mode 100644 index d809410f1..000000000 --- a/mcf/tests/mcf.rs +++ /dev/null @@ -1,89 +0,0 @@ -//! Modular Crypt Format integration tests. - -#![cfg(feature = "alloc")] - -use mcf::PasswordHash; - -#[cfg(feature = "base64")] -use {hex_literal::hex, mcf::Base64}; - -const SHA512_HASH: &str = "$6$rounds=100000$exn6tVc2j/MZD8uG$BI1Xh8qQSK9J4m14uwy7abn.ctj/TIAzlaVCto0MQrOFIeTXsc1iwzH16XEWo/a7c7Y9eVJvufVzYAs4EsPOy0"; - -#[cfg(feature = "base64")] -const EXAMPLE_SALT: &[u8] = &hex!("6a3f237988126f80958fa24b"); -#[cfg(feature = "base64")] -const EXAMPLE_HASH: &[u8] = &hex!( - "0d358cad62739eb554863c183aef27e6390368fe061fc5fcb1193a392d60dcad4594fa8d383ab8fc3f0dc8088974602668422e6a58edfa1afe24831b10be69be" -); - -#[test] -fn from_id() { - let mcf_hash = PasswordHash::from_id("6").unwrap(); - assert_eq!("$6", mcf_hash.as_str()); -} - -#[test] -fn parse_malformed() { - assert!("Hello, world!".parse::().is_err()); - assert!("$".parse::().is_err()); - assert!("$$".parse::().is_err()); - assert!("$$foo".parse::().is_err()); - assert!("$foo$".parse::().is_err()); - assert!("$-$foo".parse::().is_err()); - assert!("$foo-$bar".parse::().is_err()); - assert!("$-foo$bar".parse::().is_err()); -} - -#[test] -fn parse_id_only() { - let hash: PasswordHash = "$6".parse().unwrap(); - assert_eq!("6", hash.id()); -} - -#[test] -fn parse_sha512_hash() { - let hash: PasswordHash = SHA512_HASH.parse().unwrap(); - assert_eq!("6", hash.id()); - - let mut fields = hash.fields(); - assert_eq!("rounds=100000", fields.next().unwrap().as_str()); - - let salt = fields.next().unwrap(); - assert_eq!("exn6tVc2j/MZD8uG", salt.as_str()); - - #[cfg(feature = "base64")] - { - let salt_bytes = salt.decode_base64(Base64::ShaCrypt).unwrap(); - assert_eq!(EXAMPLE_SALT, salt_bytes.as_slice()); - } - - let hash = fields.next().unwrap(); - assert_eq!( - "BI1Xh8qQSK9J4m14uwy7abn.ctj/TIAzlaVCto0MQrOFIeTXsc1iwzH16XEWo/a7c7Y9eVJvufVzYAs4EsPOy0", - hash.as_str() - ); - - #[cfg(feature = "base64")] - { - let hash_bytes = hash.decode_base64(Base64::ShaCrypt).unwrap(); - assert_eq!(EXAMPLE_HASH, hash_bytes.as_slice()); - } - - assert_eq!(None, fields.next()); -} - -#[cfg(feature = "base64")] -#[test] -fn push_base64() { - let mut hash = PasswordHash::new("$6$rounds=100000").unwrap(); - hash.push_base64(EXAMPLE_SALT, Base64::ShaCrypt); - hash.push_base64(EXAMPLE_HASH, Base64::ShaCrypt); - assert_eq!(SHA512_HASH, hash.as_str()); -} - -#[test] -fn push_displayable() { - let mut hash = PasswordHash::from_id("6").unwrap(); - hash.push_displayable("rounds=100000").unwrap(); - assert_eq!("$6$rounds=100000", hash.as_str()); -} diff --git a/phc/Cargo.toml b/phc/Cargo.toml index cf80da060..eb94fcc74 100644 --- a/phc/Cargo.toml +++ b/phc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "phc" -version = "0.6.0-rc.0" +version = "0.6.0-rc.1" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" @@ -19,8 +19,8 @@ base64ct = "1.7" subtle = { version = "2", default-features = false } # optional dependencies -getrandom = { version = "0.3", optional = true, default-features = false } -rand_core = { version = "0.10.0-rc-2", optional = true, default-features = false } +getrandom = { version = "0.4.0-rc.0", optional = true, default-features = false } +rand_core = { version = "0.10.0-rc-3", optional = true, default-features = false } [features] default = ["rand_core"] diff --git a/phc/src/error.rs b/phc/src/error.rs index 4d1d528ae..d0a3e08b8 100644 --- a/phc/src/error.rs +++ b/phc/src/error.rs @@ -12,7 +12,7 @@ pub type Result = core::result::Result; #[non_exhaustive] pub enum Error { /// "B64" encoding error. - B64Encoding(B64Error), + Base64(B64Error), /// Password hash string invalid. MissingField, @@ -25,6 +25,7 @@ pub enum Error { /// - [`Ordering::Equal`]: Size is not exactly as `expected`. /// - [`Ordering::Greater`]: Size is too long. provided: Ordering, + /// Expected output size in relation to `provided`. /// /// - [`Ordering::Less`]: Minimum size. @@ -64,7 +65,7 @@ pub enum Error { impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> core::result::Result<(), fmt::Error> { match self { - Self::B64Encoding(err) => write!(f, "{err}"), + Self::Base64(err) => write!(f, "{err}"), Self::MissingField => write!(f, "password hash string missing field"), Self::OutputSize { provided, expected } => match provided { Ordering::Less => write!( @@ -92,7 +93,7 @@ impl fmt::Display for Error { impl core::error::Error for Error { fn source(&self) -> Option<&(dyn core::error::Error + 'static)> { match self { - Self::B64Encoding(err) => Some(err), + Self::Base64(err) => Some(err), _ => None, } } @@ -100,12 +101,12 @@ impl core::error::Error for Error { impl From for Error { fn from(err: B64Error) -> Error { - Error::B64Encoding(err) + Error::Base64(err) } } impl From for Error { fn from(_: base64ct::InvalidLengthError) -> Error { - Error::B64Encoding(B64Error::InvalidLength) + Error::Base64(B64Error::InvalidLength) } } diff --git a/phc/src/salt.rs b/phc/src/salt.rs index 1d64e45ff..086140d82 100644 --- a/phc/src/salt.rs +++ b/phc/src/salt.rs @@ -8,7 +8,7 @@ use core::{ str::{self, FromStr}, }; #[cfg(feature = "rand_core")] -use rand_core::{CryptoRng, TryCryptoRng}; +use rand_core::{CryptoRng, RngCore, TryCryptoRng, TryRngCore}; /// Error message used with `expect` for when internal invariants are violated /// (i.e. the contents of a [`Salt`] should always be valid) @@ -117,14 +117,14 @@ impl Salt { /// Generate a random [`Salt`] from the given [`CryptoRng`]. #[cfg(feature = "rand_core")] - pub fn from_rng(rng: &mut R) -> Self { + pub fn from_rng(rng: &mut R) -> Self { let Ok(out) = Self::try_from_rng(rng); out } /// Generate a random [`Salt`] from the given [`TryCryptoRng`]. #[cfg(feature = "rand_core")] - pub fn try_from_rng( + pub fn try_from_rng( rng: &mut R, ) -> core::result::Result { let mut bytes = [0u8; Self::RECOMMENDED_LENGTH]; @@ -256,14 +256,14 @@ impl SaltString { /// Generate a random B64-encoded [`SaltString`] from [`CryptoRng`]. #[cfg(feature = "rand_core")] - pub fn from_rng(rng: &mut R) -> Self { + pub fn from_rng(rng: &mut R) -> Self { let Ok(out) = Self::try_from_rng(rng); out } /// Generate a random B64-encoded [`SaltString`] from [`TryCryptoRng`]. #[cfg(feature = "rand_core")] - pub fn try_from_rng( + pub fn try_from_rng( rng: &mut R, ) -> core::result::Result { Ok(Salt::try_from_rng(rng)?.to_salt_string()) @@ -398,6 +398,6 @@ mod tests { fn reject_new_invalid_char() { let s = "01234_abcde"; let err = Salt::from_b64(s).err().unwrap(); - assert_eq!(err, Error::B64Encoding(base64ct::Error::InvalidEncoding)); + assert_eq!(err, Error::Base64(base64ct::Error::InvalidEncoding)); } } diff --git a/pkcs12/Cargo.toml b/pkcs12/Cargo.toml index 7e32794ad..0cfcd62bb 100644 --- a/pkcs12/Cargo.toml +++ b/pkcs12/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pkcs12" -version = "0.2.0-pre" +version = "0.2.0-pre.0" description = """ Pure Rust implementation of Public-Key Cryptography Standards (PKCS) #12: Personal Information Exchange Syntax v1.1 (RFC7292) @@ -18,18 +18,18 @@ rust-version = "1.85" [dependencies] der = { version = "0.8.0-rc.10", features = ["alloc", "derive", "oid"], default-features = false } spki = { version = "0.8.0-rc.4", default-features = false } -x509-cert = { version = "0.3.0-rc.0", default-features = false } +x509-cert = { version = "0.3.0-rc.3", default-features = false } const-oid = { version = "0.10", features = ["db"], default-features = false } -cms = { version = "=0.3.0-pre.0", default-features = false } +cms = { version = "=0.3.0-pre.1", default-features = false } # optional dependencies -digest = { version = "0.11.0-rc.4", features = ["alloc"], optional = true } +digest = { version = "0.11.0-rc.5", features = ["alloc"], optional = true } zeroize = { version = "1.8.1", optional = true, default-features = false } [dev-dependencies] hex-literal = "1" -pkcs8 = { version = "0.11.0-rc.8", features = ["pkcs5"] } -pkcs5 = { version = "0.8.0-rc.10", features = ["pbes2", "3des"] } +pkcs8 = { version = "0.11.0-rc.9", features = ["pkcs5"] } +pkcs5 = { version = "0.8.0-rc.12", features = ["pbes2", "3des"] } sha2 = "0.11.0-rc.3" whirlpool = "0.11.0-rc.3" @@ -41,4 +41,3 @@ pem = ["der/pem", "x509-cert/pem"] [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "docsrs"] - diff --git a/pkcs5/Cargo.toml b/pkcs5/Cargo.toml index fe7dcf136..8c9cd8f19 100644 --- a/pkcs5/Cargo.toml +++ b/pkcs5/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pkcs5" -version = "0.8.0-rc.10" +version = "0.8.0-rc.12" description = """ Pure Rust implementation of Public-Key Cryptography Standards (PKCS) #5: Password-Based Cryptography Specification Version 2.1 (RFC 8018) @@ -24,9 +24,9 @@ cbc = { version = "0.2.0-rc.2", optional = true } aes = { version = "0.9.0-rc.2", optional = true, default-features = false } aes-gcm = { version = "0.11.0-rc.2", optional = true, default-features = false, features = ["aes"] } des = { version = "0.9.0-rc.2", optional = true, default-features = false } -pbkdf2 = { version = "0.13.0-rc.2", optional = true, default-features = false, features = ["hmac"] } -rand_core = { version = "0.10.0-rc-2", optional = true, default-features = false } -scrypt = { version = "0.12.0-rc.3", optional = true, default-features = false } +pbkdf2 = { version = "0.13.0-rc.6", optional = true, default-features = false, features = ["hmac"] } +rand_core = { version = "0.10.0-rc-3", optional = true, default-features = false } +scrypt = { version = "0.12.0-rc.8", optional = true, default-features = false } sha1 = { version = "0.11.0-rc.3", optional = true, default-features = false } sha2 = { version = "0.11.0-rc.3", optional = true, default-features = false } diff --git a/pkcs5/src/pbes2.rs b/pkcs5/src/pbes2.rs index 29b8bfce0..86b7fa5b3 100644 --- a/pkcs5/src/pbes2.rs +++ b/pkcs5/src/pbes2.rs @@ -19,7 +19,7 @@ use der::{ }; #[cfg(feature = "rand_core")] -use rand_core::CryptoRng; +use rand_core::{CryptoRng, RngCore}; #[cfg(all(feature = "alloc", feature = "pbes2"))] use alloc::vec::Vec; @@ -106,7 +106,7 @@ impl Parameters { /// This is currently an alias for [`Parameters::scrypt`]. See that method /// for more information. #[cfg(all(feature = "pbes2", feature = "rand_core"))] - pub fn recommended(rng: &mut R) -> Self { + pub fn recommended(rng: &mut R) -> Self { Self::scrypt(rng) } @@ -118,7 +118,7 @@ impl Parameters { /// This will use AES-256-CBC as the encryption algorithm and SHA-256 as /// the hash function for PBKDF2. #[cfg(feature = "rand_core")] - pub fn pbkdf2(rng: &mut R) -> Self { + pub fn pbkdf2(rng: &mut R) -> Self { let mut iv = [0u8; Self::DEFAULT_IV_LEN]; rng.fill_bytes(&mut iv); @@ -169,7 +169,7 @@ impl Parameters { /// /// [RustCrypto/formats#1205]: https://github.com/RustCrypto/formats/issues/1205 #[cfg(all(feature = "pbes2", feature = "rand_core"))] - pub fn scrypt(rng: &mut R) -> Self { + pub fn scrypt(rng: &mut R) -> Self { let mut iv = [0u8; Self::DEFAULT_IV_LEN]; rng.fill_bytes(&mut iv); diff --git a/pkcs8/Cargo.toml b/pkcs8/Cargo.toml index c59d95a79..38e0f26ec 100644 --- a/pkcs8/Cargo.toml +++ b/pkcs8/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pkcs8" -version = "0.11.0-rc.8" +version = "0.11.0-rc.9" description = """ Pure Rust implementation of Public-Key Cryptography Standards (PKCS) #8: Private-Key Information Syntax Specification (RFC 5208), with additional @@ -21,8 +21,8 @@ der = { version = "0.8.0-rc.10", features = ["oid"] } spki = "0.8.0-rc.4" # optional dependencies -rand_core = { version = "0.10.0-rc-2", optional = true, default-features = false } -pkcs5 = { version = "0.8.0-rc.10", optional = true, features = ["rand_core"] } +rand_core = { version = "0.10.0-rc-3", optional = true, default-features = false } +pkcs5 = { version = "0.8.0-rc.12", optional = true, features = ["rand_core"] } subtle = { version = "2", optional = true, default-features = false } [dev-dependencies] diff --git a/pkcs8/src/encrypted_private_key_info.rs b/pkcs8/src/encrypted_private_key_info.rs index 1f84c1f2c..1be7622f4 100644 --- a/pkcs8/src/encrypted_private_key_info.rs +++ b/pkcs8/src/encrypted_private_key_info.rs @@ -12,7 +12,10 @@ use pkcs5::EncryptionScheme; use der::{SecretDocument, asn1::OctetString}; #[cfg(feature = "encryption")] -use {pkcs5::pbes2, rand_core::CryptoRng}; +use { + pkcs5::pbes2, + rand_core::{CryptoRng, RngCore}, +}; #[cfg(feature = "pem")] use der::pem::PemLabel; @@ -64,7 +67,7 @@ where /// Encrypt the given ASN.1 DER document using a symmetric encryption key /// derived from the provided password. #[cfg(feature = "encryption")] - pub(crate) fn encrypt( + pub(crate) fn encrypt( rng: &mut R, password: impl AsRef<[u8]>, doc: &[u8], diff --git a/pkcs8/src/private_key_info.rs b/pkcs8/src/private_key_info.rs index e41a7a28e..cb0d02833 100644 --- a/pkcs8/src/private_key_info.rs +++ b/pkcs8/src/private_key_info.rs @@ -17,7 +17,10 @@ use der::{ #[cfg(feature = "encryption")] use { - crate::EncryptedPrivateKeyInfoRef, der::zeroize::Zeroizing, pkcs5::pbes2, rand_core::CryptoRng, + crate::EncryptedPrivateKeyInfoRef, + der::zeroize::Zeroizing, + pkcs5::pbes2, + rand_core::{CryptoRng, RngCore}, }; #[cfg(feature = "pem")] @@ -148,7 +151,7 @@ where /// - p: 1 /// - Cipher: AES-256-CBC (best available option for PKCS#5 encryption) #[cfg(feature = "encryption")] - pub fn encrypt( + pub fn encrypt( &self, rng: &mut R, password: impl AsRef<[u8]>, diff --git a/pkcs8/src/traits.rs b/pkcs8/src/traits.rs index 394089ee3..51da2e255 100644 --- a/pkcs8/src/traits.rs +++ b/pkcs8/src/traits.rs @@ -6,7 +6,10 @@ use crate::{Error, PrivateKeyInfoRef, Result}; use der::SecretDocument; #[cfg(feature = "encryption")] -use {crate::EncryptedPrivateKeyInfoRef, rand_core::CryptoRng}; +use { + crate::EncryptedPrivateKeyInfoRef, + rand_core::{CryptoRng, RngCore}, +}; #[cfg(feature = "pem")] use { @@ -101,7 +104,7 @@ pub trait EncodePrivateKey { /// Create an [`SecretDocument`] containing the ciphertext of /// a PKCS#8 encoded private key encrypted under the given `password`. #[cfg(feature = "encryption")] - fn to_pkcs8_encrypted_der( + fn to_pkcs8_encrypted_der( &self, rng: &mut R, password: impl AsRef<[u8]>, @@ -119,7 +122,7 @@ pub trait EncodePrivateKey { /// Serialize this private key as an encrypted PEM-encoded PKCS#8 private /// key using the `provided` to derive an encryption key. #[cfg(all(feature = "encryption", feature = "pem"))] - fn to_pkcs8_encrypted_pem( + fn to_pkcs8_encrypted_pem( &self, rng: &mut R, password: impl AsRef<[u8]>, diff --git a/sec1/Cargo.toml b/sec1/Cargo.toml index 982e2a0bb..51affee53 100644 --- a/sec1/Cargo.toml +++ b/sec1/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sec1" -version = "0.8.0-rc.10" +version = "0.8.0-rc.12" description = """ Pure Rust implementation of SEC1: Elliptic Curve Cryptography encoding formats including ASN.1 DER-serialized private keys as well as the @@ -17,7 +17,8 @@ edition = "2024" rust-version = "1.85" [dependencies] -base16ct = { version = "0.3", optional = true, default-features = false } +base16ct = { version = "1", optional = true, default-features = false } +ctutils = { version = "0.4", optional = true } der = { version = "0.8.0-rc.10", optional = true, features = ["oid"] } hybrid-array = { version = "0.4", optional = true, default-features = false } serdect = { version = "0.4", optional = true, default-features = false, features = ["alloc"] } diff --git a/sec1/src/point.rs b/sec1/src/point.rs index 4a2ff43e8..9aa63d595 100644 --- a/sec1/src/point.rs +++ b/sec1/src/point.rs @@ -19,12 +19,12 @@ use hybrid_array::{Array, ArraySize, typenum::U1}; #[cfg(feature = "alloc")] use alloc::boxed::Box; +#[cfg(feature = "ctutils")] +use ctutils::{Choice, CtSelect}; + #[cfg(feature = "serde")] use serdect::serde::{Deserialize, Serialize, de, ser}; -#[cfg(feature = "subtle")] -use subtle::{Choice, ConditionallySelectable}; - #[cfg(feature = "zeroize")] use zeroize::Zeroize; @@ -254,23 +254,6 @@ where } } -#[cfg(feature = "subtle")] -impl ConditionallySelectable for EncodedPoint -where - Size: ModulusSize, - ::ArrayType: Copy, -{ - fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { - let mut bytes = Array::default(); - - for (i, byte) in bytes.iter_mut().enumerate() { - *byte = u8::conditional_select(&a.bytes[i], &b.bytes[i], choice); - } - - Self { bytes } - } -} - impl Copy for EncodedPoint where Size: ModulusSize, @@ -336,17 +319,6 @@ where } } -#[cfg(feature = "zeroize")] -impl Zeroize for EncodedPoint -where - Size: ModulusSize, -{ - fn zeroize(&mut self) { - self.bytes.zeroize(); - *self = Self::identity(); - } -} - impl fmt::Display for EncodedPoint where Size: ModulusSize, @@ -392,6 +364,40 @@ where } } +// TODO(tarcieri): add `ctutils` support to `hybrid-array` +#[cfg(feature = "ctutils")] +impl CtSelect for EncodedPoint +where + Size: ModulusSize, +{ + fn ct_select(&self, other: &Self, choice: Choice) -> Self { + let mut bytes = Array::default(); + + for (i, byte) in bytes.iter_mut().enumerate() { + *byte = self.bytes[i].ct_select(&other.bytes[i], choice); + } + + Self { bytes } + } +} + +#[cfg(feature = "subtle")] +impl subtle::ConditionallySelectable for EncodedPoint +where + Size: ModulusSize, + ::ArrayType: Copy, +{ + fn conditional_select(a: &Self, b: &Self, choice: subtle::Choice) -> Self { + let mut bytes = Array::default(); + + for (i, byte) in bytes.iter_mut().enumerate() { + *byte = u8::conditional_select(&a.bytes[i], &b.bytes[i], choice); + } + + Self { bytes } + } +} + #[cfg(feature = "serde")] impl Serialize for EncodedPoint where @@ -419,6 +425,17 @@ where } } +#[cfg(feature = "zeroize")] +impl Zeroize for EncodedPoint +where + Size: ModulusSize, +{ + fn zeroize(&mut self) { + self.bytes.zeroize(); + *self = Self::identity(); + } +} + /// Enum representing the coordinates of either compressed or uncompressed /// SEC1-encoded elliptic curve points. #[derive(Copy, Clone, Debug, Eq, PartialEq)] diff --git a/serdect/CHANGELOG.md b/serdect/CHANGELOG.md index 812e920de..7cfa4f01b 100644 --- a/serdect/CHANGELOG.md +++ b/serdect/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.4.2 (2026-01-03) +### Changed +- Bump `base16ct` to v1 ([#2145]) + +[#2145]: https://github.com/RustCrypto/formats/pull/2145 + ## 0.4.1 (2025-09-01) ### Changed - Bump `base16ct` to v0.3 ([#2017]) diff --git a/serdect/Cargo.toml b/serdect/Cargo.toml index e933522c0..ee790a039 100644 --- a/serdect/Cargo.toml +++ b/serdect/Cargo.toml @@ -4,7 +4,7 @@ description = """ Constant-time serde serializer/deserializer helpers for data that potentially contains secrets (e.g. cryptographic keys) """ -version = "0.4.1" +version = "0.4.2" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" homepage = "https://github.com/RustCrypto/formats/tree/master/serdect" @@ -16,22 +16,22 @@ edition = "2024" rust-version = "1.85" [dependencies] -base16ct = { version = "0.3", default-features = false } +base16ct = { version = "1", default-features = false } serde = { version = "1.0.184", default-features = false } -# optional featuresw +# optional features zeroize = { version = "1", optional = true, default-features = false } [dev-dependencies] -bincode = "1" ciborium = "0.2" hex-literal = "1" +postcard = { version = "1", features = ["use-std"] } proptest = "1" rmp-serde = "1" serde = { version = "1.0.184", default-features = false, features = ["derive"] } serde_json = "1" serde-json-core = { version = "0.6", default-features = false, features = ["std"] } -toml = "0.8" +toml = "0.9" [features] default = ["alloc"] diff --git a/serdect/src/lib.rs b/serdect/src/lib.rs index a3cc6ec4a..c866fe07d 100644 --- a/serdect/src/lib.rs +++ b/serdect/src/lib.rs @@ -48,20 +48,10 @@ //! //! let data = SecretData([42; 32]); //! -//! let serialized = bincode::serialize(&data).unwrap(); -//! // bincode, a binary serialization format is serialized into bytes. -//! assert_eq!( -//! serialized.as_slice(), -//! [ -//! // Array size. -//! 32, 0, 0, 0, 0, 0, 0, 0, -//! // Actual data. -//! 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, -//! 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, -//! ] -//! ); -//! # let deserialized: SecretData = bincode::deserialize(&serialized).unwrap(); -//! # assert_eq!(deserialized, data); +//! // postcard: an embedded-friendly binary serialization format +//! let serialized = postcard::to_stdvec(&data).unwrap(); +//! let deserialized: SecretData = postcard::from_bytes(&serialized).unwrap(); +//! assert_eq!(deserialized, data); //! //! let serialized = serde_json::to_string(&data).unwrap(); //! // JSON, a human-readable serialization format, is serialized into lower-case HEX. @@ -102,20 +92,10 @@ //! //! let data = SecretData(vec![42; 32]); //! -//! let serialized = bincode::serialize(&data).unwrap(); -//! // bincode, a binary serialization format is serialized into bytes. -//! assert_eq!( -//! serialized.as_slice(), -//! [ -//! // Slice size. -//! 32, 0, 0, 0, 0, 0, 0, 0, -//! // Actual data. -//! 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, -//! 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, -//! ] -//! ); -//! # let deserialized: SecretData = bincode::deserialize(&serialized).unwrap(); -//! # assert_eq!(deserialized, data); +//! // postcard: an embedded-friendly binary serialization format +//! let serialized = postcard::to_stdvec(&data).unwrap(); +//! let deserialized: SecretData = postcard::from_bytes(&serialized).unwrap(); +//! assert_eq!(deserialized, data); //! //! let serialized = serde_json::to_string(&data).unwrap(); //! // JSON, a human-readable serialization format is serialized into lower-case HEX. diff --git a/serdect/tests/bincode.rs b/serdect/tests/bincode.rs deleted file mode 100644 index 85c0289a7..000000000 --- a/serdect/tests/bincode.rs +++ /dev/null @@ -1,71 +0,0 @@ -//! bincode-specific tests. - -#![cfg(feature = "alloc")] - -use hex_literal::hex; -use proptest::{array::*, collection::vec, prelude::*}; -use serdect::{array, slice}; - -/// Example input to be serialized. -/// Last byte is `0xFF` to test that no packing is performed for values under 128. -const EXAMPLE_BYTES: [u8; 16] = hex!("000102030405060708090A0B0C0D0EFF"); - -/// bincode serialization of [`EXAMPLE_BYTES`] as a slice. -const BINCODE_SLICE: [u8; 24] = hex!("1000000000000000000102030405060708090A0B0C0D0EFF"); - -#[test] -fn deserialize_slice() { - let deserialized = bincode::deserialize::(&BINCODE_SLICE).unwrap(); - assert_eq!(deserialized.0, EXAMPLE_BYTES); -} - -#[test] -fn deserialize_slice_owned() { - let deserialized = - bincode::deserialize_from::<_, slice::HexUpperOrBin>(BINCODE_SLICE.as_ref()).unwrap(); - assert_eq!(deserialized.0, EXAMPLE_BYTES); -} - -#[test] -fn deserialize_array() { - let deserialized = bincode::deserialize::>(&BINCODE_SLICE).unwrap(); - assert_eq!(deserialized.0, EXAMPLE_BYTES); -} - -#[test] -fn deserialize_array_owned() { - let deserialized = - bincode::deserialize_from::<_, array::HexUpperOrBin<16>>(BINCODE_SLICE.as_ref()).unwrap(); - assert_eq!(deserialized.0, EXAMPLE_BYTES); -} - -#[test] -fn serialize_slice() { - let serialized = - bincode::serialize(&slice::HexUpperOrBin::from(EXAMPLE_BYTES.as_ref())).unwrap(); - assert_eq!(&serialized, &BINCODE_SLICE); -} - -#[test] -fn serialize_array() { - let serialized = bincode::serialize(&array::HexUpperOrBin::from(EXAMPLE_BYTES)).unwrap(); - assert_eq!(&serialized, &BINCODE_SLICE); -} - -proptest! { - #[test] - fn round_trip_slice(bytes in vec(any::(), 0..1024)) { - let serialized = bincode::serialize(&slice::HexUpperOrBin::from(bytes.as_ref())).unwrap(); - let deserialized = bincode::deserialize::(&serialized).unwrap(); - prop_assert_eq!(bytes, deserialized.0); - } - - #[test] - fn round_trip_array(bytes in uniform32(0u8..)) { - let serialized = bincode::serialize(&array::HexUpperOrBin::from(bytes)).unwrap(); - let deserialized = bincode::deserialize::>(&serialized).unwrap(); - prop_assert_eq!(bytes, deserialized.0); - // 8 bytes for the length tag + 32 bytes of data - prop_assert_eq!(serialized.len(), 8 + 32); - } -} diff --git a/x509-cert/Cargo.toml b/x509-cert/Cargo.toml index 5f60f486d..bd023879b 100644 --- a/x509-cert/Cargo.toml +++ b/x509-cert/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "x509-cert" -version = "0.3.0-rc.2" +version = "0.3.0-rc.3" description = """ Pure Rust implementation of the X.509 Public Key Infrastructure Certificate format as described in RFC 5280 @@ -29,10 +29,10 @@ tls_codec = { version = "0.4", default-features = false, features = ["derive"], [dev-dependencies] hex-literal = "1" -rand = "0.10.0-rc.1" -rsa = { version = "0.10.0-rc.10", features = ["sha2"] } -ecdsa = { version = "0.17.0-rc.6", features = ["digest", "pem"] } -p256 = "0.14.0-rc.1" +rand = "0.10.0-rc.6" +rsa = { version = "0.10.0-rc.11", features = ["sha2"] } +ecdsa = { version = "0.17.0-rc.9", features = ["digest", "pem"] } +p256 = "0.14.0-rc.4" rstest = "0.26" sha2 = { version = "0.11.0-rc.3", features = ["oid"] } tempfile = "3.5" diff --git a/x509-cert/src/builder.rs b/x509-cert/src/builder.rs index 29037748d..ec657852f 100644 --- a/x509-cert/src/builder.rs +++ b/x509-cert/src/builder.rs @@ -4,7 +4,8 @@ use alloc::vec; use core::fmt; use der::{Encode, asn1::BitString, referenced::OwnedToRef}; use signature::{ - AsyncRandomizedSigner, AsyncSigner, Keypair, RandomizedSigner, Signer, rand_core::CryptoRng, + AsyncRandomizedSigner, AsyncSigner, Keypair, RandomizedSigner, Signer, + rand_core::{CryptoRng, RngCore}, }; use spki::{ DynSignatureAlgorithmIdentifier, EncodePublicKey, ObjectIdentifier, SignatureBitStringEncoding, @@ -15,7 +16,7 @@ use crate::{ certificate::{self, Certificate, TbsCertificate, Version}, crl::{CertificateList, RevokedCert, TbsCertList}, ext::{ - AsExtension, Extensions, + Extensions, ToExtension, pkix::{AuthorityKeyIdentifier, CrlNumber, SubjectKeyIdentifier}, }, serial_number::SerialNumber, @@ -216,12 +217,12 @@ where /// Add an extension to this certificate /// - /// Extensions need to implement [`AsExtension`], examples may be found in - /// in [`AsExtension` documentation](../ext/trait.AsExtension.html#examples) or - /// [the implementors](../ext/trait.AsExtension.html#implementors). - pub fn add_extension( + /// Extensions need to implement [`ToExtension`], examples may be found in + /// in [`ToExtension` documentation](../ext/trait.ToExtension.html#examples) or + /// [the implementors](../ext/trait.ToExtension.html#implementors). + pub fn add_extension( &mut self, - extension: &E, + extension: E, ) -> core::result::Result<(), E::Error> { let ext = extension.to_extension(&self.tbs.subject, &self.extensions)?; self.extensions.push(ext); @@ -259,6 +260,7 @@ pub trait Builder: Sized { /// This would look like: #[cfg_attr(feature = "std", doc = "```no_run")] #[cfg_attr(not(feature = "std"), doc = "```ignore")] + /// # use p256::elliptic_curve::Generate; /// # use rand::rng; /// # use std::{ /// # str::FromStr, @@ -273,7 +275,7 @@ pub trait Builder: Sized { /// # }; /// # /// # let mut rng = rng(); - /// # let signer = p256::ecdsa::SigningKey::try_from_rng(&mut rng).unwrap(); + /// # let signer = p256::ecdsa::SigningKey::generate_from_rng(&mut rng); /// # let builder = CertificateBuilder::new( /// # builder::profile::cabf::Root::new( /// # false, @@ -310,6 +312,7 @@ pub trait Builder: Sized { /// This would look like: #[cfg_attr(feature = "std", doc = "```no_run")] #[cfg_attr(not(feature = "std"), doc = "```ignore")] + /// # use p256::elliptic_curve::Generate; /// # use rand::rng; /// # use std::{ /// # str::FromStr, @@ -324,7 +327,7 @@ pub trait Builder: Sized { /// # }; /// # /// # let mut rng = rng(); - /// # let signer = p256::ecdsa::SigningKey::try_from_rng(&mut rng).unwrap(); + /// # let signer = p256::ecdsa::SigningKey::generate_from_rng(&mut rng); /// # let builder = CertificateBuilder::new( /// # builder::profile::cabf::Root::new( /// # false, @@ -345,7 +348,7 @@ pub trait Builder: Sized { S: Keypair + DynSignatureAlgorithmIdentifier, S::VerifyingKey: EncodePublicKey, Signature: SignatureBitStringEncoding, - R: CryptoRng + ?Sized, + R: CryptoRng + RngCore + ?Sized, { let blob = self.finalize(signer)?; @@ -442,6 +445,7 @@ pub trait AsyncBuilder: Sized { /// This would look like: #[cfg_attr(feature = "std", doc = "```no_run")] #[cfg_attr(not(feature = "std"), doc = "```ignore")] + /// # use p256::elliptic_curve::Generate; /// # use rand::rng; /// # use std::{ /// # str::FromStr, @@ -457,7 +461,7 @@ pub trait AsyncBuilder: Sized { /// # /// # async fn build() -> builder::Result<()> { /// # let mut rng = rng(); - /// # let signer = p256::ecdsa::SigningKey::try_from_rng(&mut rng).unwrap(); + /// # let signer = p256::ecdsa::SigningKey::generate_from_rng(&mut rng); /// # let builder = CertificateBuilder::new( /// # builder::profile::cabf::Root::new( /// # false, @@ -496,6 +500,7 @@ pub trait AsyncBuilder: Sized { /// This would look like: #[cfg_attr(feature = "std", doc = "```no_run")] #[cfg_attr(not(feature = "std"), doc = "```ignore")] + /// # use p256::elliptic_curve::Generate; /// # use rand::rng; /// # use std::{ /// # str::FromStr, @@ -511,7 +516,7 @@ pub trait AsyncBuilder: Sized { /// # /// # async fn build() -> builder::Result<()> { /// # let mut rng = rng(); - /// # let signer = p256::ecdsa::SigningKey::try_from_rng(&mut rng).unwrap(); + /// # let signer = p256::ecdsa::SigningKey::generate_from_rng(&mut rng); /// # let builder = CertificateBuilder::new( /// # builder::profile::cabf::Root::new( /// # false, @@ -535,7 +540,7 @@ pub trait AsyncBuilder: Sized { S: Keypair + DynSignatureAlgorithmIdentifier, S::VerifyingKey: EncodePublicKey, Signature: SignatureBitStringEncoding, - R: CryptoRng + ?Sized, + R: CryptoRng + RngCore + ?Sized, { let blob = self.finalize(signer)?; diff --git a/x509-cert/src/builder/profile/cabf.rs b/x509-cert/src/builder/profile/cabf.rs index d69b0c2b1..2b6050376 100644 --- a/x509-cert/src/builder/profile/cabf.rs +++ b/x509-cert/src/builder/profile/cabf.rs @@ -8,7 +8,7 @@ use crate::{ builder::{BuilderProfile, Error, Result}, certificate::TbsCertificate, ext::{ - AsExtension, Extension, + Extension, ToExtension, pkix::{ AuthorityKeyIdentifier, BasicConstraints, KeyUsage, KeyUsages, SubjectKeyIdentifier, }, diff --git a/x509-cert/src/builder/profile/cabf/tls.rs b/x509-cert/src/builder/profile/cabf/tls.rs index 4b28d5544..9cf64a283 100644 --- a/x509-cert/src/builder/profile/cabf/tls.rs +++ b/x509-cert/src/builder/profile/cabf/tls.rs @@ -16,7 +16,7 @@ use crate::{ builder::{BuilderProfile, Result}, certificate::TbsCertificate, ext::{ - AsExtension, Extension, + Extension, ToExtension, pkix::{ AuthorityKeyIdentifier, BasicConstraints, ExtendedKeyUsage, KeyUsage, KeyUsages, SubjectKeyIdentifier, name::GeneralNames, diff --git a/x509-cert/src/builder/profile/devid.rs b/x509-cert/src/builder/profile/devid.rs index 14582cb6b..0d7e884a5 100644 --- a/x509-cert/src/builder/profile/devid.rs +++ b/x509-cert/src/builder/profile/devid.rs @@ -19,7 +19,7 @@ use crate::{ builder::{BuilderProfile, Result}, certificate::TbsCertificate, ext::{ - AsExtension, Extension, + Extension, ToExtension, pkix::{ AuthorityKeyIdentifier, KeyUsage, KeyUsages, SubjectAltName, name::{GeneralName, GeneralNames, HardwareModuleName, OtherName}, diff --git a/x509-cert/src/ext.rs b/x509-cert/src/ext.rs index 511659304..da92b237d 100644 --- a/x509-cert/src/ext.rs +++ b/x509-cert/src/ext.rs @@ -35,6 +35,18 @@ pub struct Extension { pub extn_value: OctetString, } +impl ToExtension for Extension { + type Error = der::Error; + + fn to_extension( + self, + _subject: &crate::name::Name, + _extensions: &[Extension], + ) -> Result { + Ok(self) + } +} + /// Extensions as defined in [RFC 5280 Section 4.1.2.9]. /// /// ```text @@ -91,44 +103,68 @@ pub trait Criticality { /// } /// } /// ``` -pub trait AsExtension { +pub trait ToExtension { /// The error type returned when encoding the extension. type Error; /// Returns the Extension with the content encoded. fn to_extension( - &self, + self, subject: &crate::name::Name, extensions: &[Extension], ) -> Result; } -impl AsExtension for T { +impl ToExtension for &T { type Error = der::Error; fn to_extension( - &self, + self, subject: &crate::name::Name, extensions: &[Extension], ) -> Result { - Ok(Extension { - extn_id: ::OID, - critical: self.criticality(subject, extensions), - extn_value: OctetString::new(self.to_der()?)?, - }) + let criticality = self.criticality(subject, extensions); + (criticality, self).to_extension(subject, extensions) + } +} + +impl ToExtension for (ObjectIdentifier, &T) { + type Error = der::Error; + + fn to_extension( + self, + subject: &crate::name::Name, + extensions: &[Extension], + ) -> Result { + let criticality = self.1.criticality(subject, extensions); + (self.0, criticality, self.1).to_extension(subject, extensions) } } -impl AsExtension for (bool, T) { - type Error = T::Error; +impl ToExtension for (bool, &T) { + type Error = der::Error; fn to_extension( - &self, + self, subject: &crate::name::Name, extensions: &[Extension], ) -> Result { - let mut extension = self.1.to_extension(subject, extensions)?; - extension.critical = self.0; - Ok(extension) + (T::OID, self.0, self.1).to_extension(subject, extensions) + } +} + +impl ToExtension for (ObjectIdentifier, bool, &T) { + type Error = der::Error; + + fn to_extension( + self, + _subject: &crate::name::Name, + _extensions: &[Extension], + ) -> Result { + Ok(Extension { + extn_id: self.0, + critical: self.1, + extn_value: OctetString::new(self.2.to_der()?)?, + }) } } diff --git a/x509-cert/src/request/builder.rs b/x509-cert/src/request/builder.rs index db26fda57..84ae5c96c 100644 --- a/x509-cert/src/request/builder.rs +++ b/x509-cert/src/request/builder.rs @@ -8,7 +8,7 @@ use spki::{ use crate::{ builder::{Builder, Error, NULL_OID, Result}, - ext::AsExtension, + ext::ToExtension, name::Name, request::{CertReq, CertReqInfo, ExtensionReq, attributes::AsAttribute}, }; @@ -77,12 +77,12 @@ impl RequestBuilder { /// Add an extension to this certificate request /// - /// Extensions need to implement [`AsExtension`], examples may be found in - /// in [`AsExtension` documentation](../ext/trait.AsExtension.html#examples) or - /// [the implementors](../ext/trait.AsExtension.html#implementors). - pub fn add_extension( + /// Extensions need to implement [`ToExtension`], examples may be found in + /// in [`ToExtension` documentation](../ext/trait.ToExtension.html#examples) or + /// [the implementors](../ext/trait.ToExtension.html#implementors). + pub fn add_extension( &mut self, - extension: &E, + extension: E, ) -> core::result::Result<(), E::Error> { let ext = extension.to_extension(&self.info.subject, &self.extension_req.0)?; diff --git a/x509-cert/src/serial_number.rs b/x509-cert/src/serial_number.rs index ce286ed88..18e9f6f06 100644 --- a/x509-cert/src/serial_number.rs +++ b/x509-cert/src/serial_number.rs @@ -8,7 +8,10 @@ use der::{ asn1::{self, Int}, }; #[cfg(feature = "builder")] -use {alloc::vec, signature::rand_core::CryptoRng}; +use { + alloc::vec, + signature::rand_core::{CryptoRng, RngCore}, +}; use crate::certificate::{Profile, Rfc5280}; @@ -77,7 +80,7 @@ impl SerialNumber

{ /// of output from the CSPRNG. This currently defaults to a 17-bytes long serial number. /// /// [ballot 164]: https://cabforum.org/2016/03/31/ballot-164/ - pub fn generate(rng: &mut R) -> Self { + pub fn generate(rng: &mut R) -> Self { Self::generate_with_prefix(&[], 17, rng) .expect("a random of 17 is acceptable, and rng may not fail") } @@ -91,7 +94,7 @@ impl SerialNumber

{ /// equal or below 19 (to account for leading sign disambiguation, and the maximum length of 20). /// /// [ballot 164]: https://cabforum.org/2016/03/31/ballot-164/ - pub fn generate_with_prefix( + pub fn generate_with_prefix( prefix: &[u8], rand_len: usize, rng: &mut R, diff --git a/x509-cert/tests/builder.rs b/x509-cert/tests/builder.rs index 15b33ab55..c88ca91f6 100644 --- a/x509-cert/tests/builder.rs +++ b/x509-cert/tests/builder.rs @@ -5,8 +5,7 @@ use der::{ asn1::{Ia5String, PrintableString}, pem::LineEnding, }; -use p256::{NistP256, ecdsa::DerSignature, pkcs8::DecodePrivateKey}; -use rand::rngs::OsRng; +use p256::{NistP256, ecdsa::DerSignature, elliptic_curve::Generate, pkcs8::DecodePrivateKey}; use rsa::pkcs1::DecodeRsaPrivateKey; use rsa::pkcs1v15::SigningKey; use sha2::Sha256; @@ -314,9 +313,10 @@ fn dynamic_signer() { let subject = Name::from_str("CN=Test").expect("parse common name"); let csr_builder = RequestBuilder::new(subject).expect("construct builder"); + let mut rng = rand::rng(); let csr = if true { - let req_signer = p256::ecdsa::SigningKey::try_from_rng(&mut OsRng).unwrap(); + let req_signer = p256::ecdsa::SigningKey::generate_from_rng(&mut rng); csr_builder .build::<_, p256::ecdsa::DerSignature>(&req_signer) .expect("Sign request") diff --git a/x509-cert/tests/builder_crl.rs b/x509-cert/tests/builder_crl.rs index 2a8f81726..41f8ecd41 100644 --- a/x509-cert/tests/builder_crl.rs +++ b/x509-cert/tests/builder_crl.rs @@ -17,7 +17,7 @@ use x509_cert::{ certificate::Rfc5280, crl::RevokedCert, ext::{ - AsExtension, + ToExtension, pkix::{CrlNumber, CrlReason, name::GeneralName}, }, name::Name, diff --git a/x509-ocsp/Cargo.toml b/x509-ocsp/Cargo.toml index 0c9e20dd0..1d4bf8eab 100644 --- a/x509-ocsp/Cargo.toml +++ b/x509-ocsp/Cargo.toml @@ -19,18 +19,18 @@ rust-version = "1.85" const-oid = { version = "0.10", default-features = false, features = ["db"] } der = { version = "0.8.0-rc.10", features = ["alloc", "derive", "oid"] } spki = { version = "0.8.0-rc.4", features = ["alloc"] } -x509-cert = { version = "0.3.0-rc.0", default-features = false } +x509-cert = { version = "0.3.0-rc.3", default-features = false } # Optional digest = { version = "0.11.0-rc.4", optional = true, default-features = false, features = ["oid"] } -rand_core = { version = "0.10.0-rc-2", optional = true, default-features = false } +rand_core = { version = "0.10.0-rc-3", optional = true, default-features = false } signature = { version = "3.0.0-rc.5", optional = true, default-features = false, features = ["digest", "rand_core"] } [dev-dependencies] hex-literal = "1" lazy_static = "1.5.0" -rand = "0.10.0-rc.1" -rsa = { version = "0.10.0-rc.10", default-features = false, features = ["encoding", "sha2"] } +rand = "0.10.0-rc.6" +rsa = { version = "0.10.0-rc.11", default-features = false, features = ["encoding", "sha2"] } sha1 = { version = "0.11.0-rc.3", default-features = false, features = ["oid"] } sha2 = { version = "0.11.0-rc.3", default-features = false, features = ["oid"] } diff --git a/x509-ocsp/src/basic.rs b/x509-ocsp/src/basic.rs index e4dfb72b2..3c3cf2d43 100644 --- a/x509-ocsp/src/basic.rs +++ b/x509-ocsp/src/basic.rs @@ -130,7 +130,7 @@ mod builder { use const_oid::AssociatedOid; use digest::Digest; use x509_cert::{ - Certificate, crl::CertificateList, ext::AsExtension, name::Name, + Certificate, crl::CertificateList, ext::ToExtension, name::Name, serial_number::SerialNumber, }; @@ -171,7 +171,7 @@ mod builder { /// extension encoding fails. /// /// [RFC 6960 Section 4.4]: https://datatracker.ietf.org/doc/html/rfc6960#section-4.4 - pub fn with_extension(mut self, ext: E) -> Result { + pub fn with_extension(mut self, ext: E) -> Result { let ext = ext.to_extension(&Name::default(), &[])?; match self.single_extensions { Some(ref mut exts) => exts.push(ext), diff --git a/x509-ocsp/src/builder/request.rs b/x509-ocsp/src/builder/request.rs index 1b9bc54f7..0a0d72073 100644 --- a/x509-ocsp/src/builder/request.rs +++ b/x509-ocsp/src/builder/request.rs @@ -3,13 +3,13 @@ use crate::{OcspRequest, Request, Signature, TbsRequest, Version, builder::Error}; use alloc::vec::Vec; use der::Encode; -use rand_core::CryptoRng; +use rand_core::{CryptoRng, RngCore}; use signature::{RandomizedSigner, Signer}; use spki::{DynSignatureAlgorithmIdentifier, SignatureBitStringEncoding}; use x509_cert::{ Certificate, certificate::Rfc5280, - ext::{AsExtension, pkix::name::GeneralName}, + ext::{ToExtension, pkix::name::GeneralName}, name::Name, }; @@ -45,7 +45,7 @@ use x509_cert::{ /// .with_request(Request::from_issuer::(&issuer, SerialNumber::from(2usize)).unwrap()) /// .with_request(Request::from_issuer::(&issuer, SerialNumber::from(3usize)).unwrap()) /// .with_request(Request::from_issuer::(&issuer, SerialNumber::from(4usize)).unwrap()) -/// .with_extension(Nonce::generate(&mut rng, 32).unwrap()) +/// .with_extension(&Nonce::generate(&mut rng, 32).unwrap()) /// .unwrap() /// .build(); /// @@ -53,7 +53,7 @@ use x509_cert::{ /// let signer_cert_chain = vec![cert.clone()]; /// let req = OcspRequestBuilder::default() /// .with_request(Request::from_cert::(&issuer, &cert).unwrap()) -/// .with_extension(Nonce::generate(&mut rng, 32).unwrap()) +/// .with_extension(&Nonce::generate(&mut rng, 32).unwrap()) /// .unwrap() /// .sign(&mut signer, Some(signer_cert_chain)) /// .unwrap(); @@ -96,7 +96,7 @@ impl OcspRequestBuilder { /// extension encoding fails. /// /// [RFC 6960 Section 4.4]: https://datatracker.ietf.org/doc/html/rfc6960#section-4.4 - pub fn with_extension(mut self, ext: E) -> Result { + pub fn with_extension(mut self, ext: E) -> Result { let ext = ext.to_extension(&Name::default(), &[])?; match self.tbs.request_extensions { Some(ref mut exts) => exts.push(ext), @@ -148,7 +148,7 @@ impl OcspRequestBuilder { where S: RandomizedSigner + DynSignatureAlgorithmIdentifier, Sig: SignatureBitStringEncoding, - R: CryptoRng + ?Sized, + R: CryptoRng + RngCore + ?Sized, { let signature_algorithm = signer.signature_algorithm_identifier()?; let signature = signer diff --git a/x509-ocsp/src/builder/response.rs b/x509-ocsp/src/builder/response.rs index 06061ac74..776ac3305 100644 --- a/x509-ocsp/src/builder/response.rs +++ b/x509-ocsp/src/builder/response.rs @@ -6,12 +6,12 @@ use crate::{ }; use alloc::vec::Vec; use der::Encode; -use rand_core::CryptoRng; +use rand_core::{CryptoRng, RngCore}; use signature::{RandomizedSigner, Signer}; use spki::{DynSignatureAlgorithmIdentifier, SignatureBitStringEncoding}; use x509_cert::{ Certificate, - ext::{AsExtension, Extensions}, + ext::{Extensions, ToExtension}, name::Name, }; @@ -53,7 +53,7 @@ use x509_cert::{ /// ); /// /// if let Some(nonce) = req.nonce() { -/// builder = builder.with_extension(nonce).unwrap(); +/// builder = builder.with_extension(&nonce).unwrap(); /// } /// /// #[cfg(feature = "std")] @@ -101,7 +101,7 @@ impl OcspResponseBuilder { /// extension encoding fails. /// /// [RFC 6960 Section 4.4]: https://datatracker.ietf.org/doc/html/rfc6960#section-4.4 - pub fn with_extension(mut self, ext: E) -> Result { + pub fn with_extension(mut self, ext: E) -> Result { let ext = ext.to_extension(&Name::default(), &[])?; match self.response_extensions { Some(ref mut exts) => exts.push(ext), @@ -168,7 +168,7 @@ impl OcspResponseBuilder { where S: RandomizedSigner + DynSignatureAlgorithmIdentifier, Sig: SignatureBitStringEncoding, - R: CryptoRng + ?Sized, + R: CryptoRng + RngCore + ?Sized, { let tbs_response_data = self.into_response_data(produced_at); let signature_algorithm = signer.signature_algorithm_identifier()?; diff --git a/x509-ocsp/src/ext.rs b/x509-ocsp/src/ext.rs index 457a8f4a5..601784e8c 100644 --- a/x509-ocsp/src/ext.rs +++ b/x509-ocsp/src/ext.rs @@ -21,7 +21,7 @@ use x509_cert::{ }; #[cfg(feature = "rand")] -use rand_core::CryptoRng; +use rand_core::{CryptoRng, RngCore}; // x509-cert's is not exported macro_rules! impl_extension { @@ -64,7 +64,7 @@ impl Nonce { #[cfg(feature = "rand")] pub fn generate(rng: &mut R, length: usize) -> Result where - R: CryptoRng + ?Sized, + R: CryptoRng + RngCore + ?Sized, { let mut bytes = alloc::vec![0; length]; rng.fill_bytes(&mut bytes); diff --git a/x509-ocsp/src/request.rs b/x509-ocsp/src/request.rs index 53b67f432..f6a3f71f3 100644 --- a/x509-ocsp/src/request.rs +++ b/x509-ocsp/src/request.rs @@ -127,7 +127,7 @@ mod builder { use crate::{CertId, Request, builder::Error}; use const_oid::AssociatedOid; use digest::Digest; - use x509_cert::{Certificate, ext::AsExtension, name::Name, serial_number::SerialNumber}; + use x509_cert::{Certificate, ext::ToExtension, name::Name, serial_number::SerialNumber}; impl Request { /// Returns a new `Request` with the specified `CertID` @@ -172,7 +172,7 @@ mod builder { /// extension encoding fails. /// /// [RFC 6960 Section 4.4]: https://datatracker.ietf.org/doc/html/rfc6960#section-4.4 - pub fn with_extension(mut self, ext: E) -> Result { + pub fn with_extension(mut self, ext: E) -> Result { let ext = ext.to_extension(&Name::default(), &[])?; match self.single_request_extensions { Some(ref mut exts) => exts.push(ext), diff --git a/x509-ocsp/tests/builder.rs b/x509-ocsp/tests/builder.rs index fe85c6090..6c91b94a5 100644 --- a/x509-ocsp/tests/builder.rs +++ b/x509-ocsp/tests/builder.rs @@ -126,12 +126,12 @@ fn encode_ocsp_req_multiple_extensions() { .with_request( Request::from_issuer::(&ISSUER, SerialNumber::from(0x10001usize)) .unwrap() - .with_extension(single_ext1) + .with_extension(&single_ext1) .unwrap(), ) - .with_extension(ext1) + .with_extension(&ext1) .unwrap() - .with_extension(ext2) + .with_extension(&ext2) .unwrap() .build(); assert_eq!(&req.to_der().unwrap(), &req_der); @@ -296,12 +296,12 @@ fn encode_ocsp_resp_multiple_extensions() { .with_next_update(OcspGeneralizedTime::from( DateTime::new(2020, 1, 1, 0, 0, 0).unwrap(), )) - .with_extension(single_ext1) + .with_extension(&single_ext1) .unwrap() - .with_extension(single_ext2) + .with_extension(&single_ext2) .unwrap(), ) - .with_extension(ext1) + .with_extension(&ext1) .unwrap() .sign( &mut signer, diff --git a/x509-tsp/Cargo.toml b/x509-tsp/Cargo.toml index cf655c54d..f9fcd28e8 100644 --- a/x509-tsp/Cargo.toml +++ b/x509-tsp/Cargo.toml @@ -16,9 +16,9 @@ rust-version = "1.85" [dependencies] der = { version = "0.8.0-rc.10", features = ["alloc", "derive", "oid", "pem"] } -cms = { version = "=0.3.0-pre.0" } +cms = { version = "=0.3.0-pre.1" } cmpv2 = { version = "=0.3.0-pre.0", features = ["alloc"] } -x509-cert = { version = "0.3.0-rc.0", default-features = false } +x509-cert = { version = "0.3.0-rc.3", default-features = false } [dev-dependencies] hex-literal = "1"