diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index 61c41cc..0000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,65 +0,0 @@ -name: CI - -on: - push: - branches: [master] - pull_request: - -env: - CARGO_TERM_COLOR: always - # The example workspace config points the type-map build script at this file. - MTP_TYPE_MAPS: example-type-maps.yaml - -jobs: - fmt: - name: rustfmt - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable - with: - components: rustfmt - - run: cargo fmt --all --check - - clippy: - name: clippy - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable - with: - components: clippy - - uses: Swatinem/rust-cache@v2 - - run: cargo clippy --workspace --exclude mtp-wasm --all-targets --all-features -- -D warnings - - test: - name: test - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable - - uses: Swatinem/rust-cache@v2 - - run: cargo test --workspace --exclude mtp-wasm --all-features - - wasm: - name: wasm build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable - with: - targets: wasm32-unknown-unknown - - uses: Swatinem/rust-cache@v2 - # The WebTransport bindings in web-sys are still gated behind this cfg. - - run: cargo build -p mtp-wasm --target wasm32-unknown-unknown - env: - RUSTFLAGS: --cfg=web_sys_unstable_apis - - deny: - name: cargo-deny - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: EmbarkStudios/cargo-deny-action@v2 - with: - command: check diff --git a/.gitignore b/.gitignore index f74d910..fdb1a18 100644 --- a/.gitignore +++ b/.gitignore @@ -1,18 +1,4 @@ **target/ +**Cargo.lock *.pem *.key -example-usage/dev-cert/ - -# The root Cargo.lock and the example-usage workspace lockfile are committed: -# the workspace ships binaries (example-usage/*) and a committed lockfile keeps -# their builds reproducible. Workspace members do not own a lockfile (the root -# one governs them); ignore any stray per-member lockfiles so they are not -# committed by accident. -/client/Cargo.lock -/codec/Cargo.lock -/common/Cargo.lock -/crypto/Cargo.lock -/host/Cargo.lock -/transport/Cargo.lock -/type-map/Cargo.lock -/wasm/Cargo.lock diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index c85e323..0000000 --- a/Cargo.lock +++ /dev/null @@ -1,2576 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "aead" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" -dependencies = [ - "crypto-common 0.1.7", - "generic-array", -] - -[[package]] -name = "aes" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures 0.2.17", -] - -[[package]] -name = "aes-gcm" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" -dependencies = [ - "aead", - "aes", - "cipher", - "ctr", - "ghash", - "subtle", -] - -[[package]] -name = "asn1-rs" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f43a50ac4fdca5df8e885c21b835997f0a1cdee65494a6847694a98652d9d8" -dependencies = [ - "asn1-rs-derive", - "asn1-rs-impl", - "displaydoc", - "nom", - "num-traits", - "rusticata-macros", - "thiserror", - "time", -] - -[[package]] -name = "asn1-rs-derive" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "asn1-rs-impl" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "async-trait" -version = "0.1.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "autocfg" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" - -[[package]] -name = "aws-lc-rs" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ec2f1fc3ec205783a5da9a7e6c1509cc69dedf09a1949e412c1e18469326d00" -dependencies = [ - "aws-lc-sys", - "untrusted 0.7.1", - "zeroize", -] - -[[package]] -name = "aws-lc-sys" -version = "0.41.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a2f9779ce85b93ab6170dd940ad0169b5766ff848247aff13bb788b832fe3f4" -dependencies = [ - "cc", - "cmake", - "dunce", - "fs_extra", -] - -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - -[[package]] -name = "base64ct" -version = "1.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" - -[[package]] -name = "bit-vec" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71798fca2c1fe1086445a7258a4bc81e6e49dcd24c8d0dd9a1e57395b603f51" -dependencies = [ - "serde", -] - -[[package]] -name = "bitflags" -version = "2.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "block-buffer" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" -dependencies = [ - "hybrid-array", -] - -[[package]] -name = "bumpalo" -version = "3.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593" - -[[package]] -name = "cast" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" - -[[package]] -name = "cc" -version = "1.2.65" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96" -dependencies = [ - "find-msvc-tools", - "jobserver", - "libc", - "shlex", -] - -[[package]] -name = "cfg-if" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" - -[[package]] -name = "cfg_aliases" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" - -[[package]] -name = "chacha20" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures 0.2.17", -] - -[[package]] -name = "chacha20poly1305" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" -dependencies = [ - "aead", - "chacha20", - "cipher", - "poly1305", - "zeroize", -] - -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common 0.1.7", - "inout", - "zeroize", -] - -[[package]] -name = "cmake" -version = "0.1.58" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" -dependencies = [ - "cc", -] - -[[package]] -name = "cmov" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a" - -[[package]] -name = "console_error_panic_hook" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" -dependencies = [ - "cfg-if", - "wasm-bindgen", -] - -[[package]] -name = "const-oid" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" - -[[package]] -name = "const-oid" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" - -[[package]] -name = "core-foundation" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "cpufeatures" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] - -[[package]] -name = "cpufeatures" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" -dependencies = [ - "libc", -] - -[[package]] -name = "crypto-common" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" -dependencies = [ - "generic-array", - "rand_core 0.6.4", - "typenum", -] - -[[package]] -name = "crypto-common" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" -dependencies = [ - "getrandom 0.4.3", - "hybrid-array", - "rand_core 0.10.1", -] - -[[package]] -name = "ctr" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" -dependencies = [ - "cipher", -] - -[[package]] -name = "ctutils" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" -dependencies = [ - "cmov", -] - -[[package]] -name = "curve25519-dalek" -version = "4.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" -dependencies = [ - "cfg-if", - "cpufeatures 0.2.17", - "curve25519-dalek-derive", - "digest 0.10.7", - "fiat-crypto", - "rustc_version", - "subtle", - "zeroize", -] - -[[package]] -name = "curve25519-dalek-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "data-encoding" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8" - -[[package]] -name = "der" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" -dependencies = [ - "const-oid 0.9.6", - "pem-rfc7468", - "zeroize", -] - -[[package]] -name = "der" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71fd89660b2dc699704064e59e9dba0147b903e85319429e131620d022be411b" -dependencies = [ - "const-oid 0.10.2", - "zeroize", -] - -[[package]] -name = "der-parser" -version = "10.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07da5016415d5a3c4dd39b11ed26f915f52fc4e0dc197d87908bc916e51bc1a6" -dependencies = [ - "asn1-rs", - "displaydoc", - "nom", - "num-bigint", - "num-traits", - "rusticata-macros", -] - -[[package]] -name = "deranged" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer 0.10.4", - "crypto-common 0.1.7", -] - -[[package]] -name = "digest" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" -dependencies = [ - "block-buffer 0.12.1", - "const-oid 0.10.2", - "crypto-common 0.2.2", - "ctutils", -] - -[[package]] -name = "displaydoc" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "dunce" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" - -[[package]] -name = "ed25519" -version = "2.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" -dependencies = [ - "pkcs8 0.10.2", - "signature 2.2.0", -] - -[[package]] -name = "ed25519-dalek" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" -dependencies = [ - "curve25519-dalek", - "ed25519", - "serde", - "sha2 0.10.9", - "subtle", - "zeroize", -] - -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "errno" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" -dependencies = [ - "libc", - "windows-sys 0.61.2", -] - -[[package]] -name = "fiat-crypto" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" - -[[package]] -name = "find-msvc-tools" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" - -[[package]] -name = "form_urlencoded" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "fs_extra" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" - -[[package]] -name = "futures-core" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" - -[[package]] -name = "futures-task" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" - -[[package]] -name = "futures-util" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" -dependencies = [ - "futures-core", - "futures-task", - "pin-project-lite", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi", - "wasm-bindgen", -] - -[[package]] -name = "getrandom" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "r-efi 5.3.0", - "wasip2", - "wasm-bindgen", -] - -[[package]] -name = "getrandom" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "r-efi 6.0.0", - "rand_core 0.10.1", - "wasm-bindgen", -] - -[[package]] -name = "ghash" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" -dependencies = [ - "opaque-debug", - "polyval", -] - -[[package]] -name = "hashbrown" -version = "0.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hkdf" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4aaa26c720c68b866f2c96ef5c1264b3e6f473fe5d4ce61cd44bbe913e553018" -dependencies = [ - "hmac", -] - -[[package]] -name = "hmac" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" -dependencies = [ - "digest 0.11.3", -] - -[[package]] -name = "httlib-huffman" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a9fcbcc408c5526c3ab80d534e5c86e7967c1fb7aa0a8c76abd1edc27deb877" - -[[package]] -name = "hybrid-array" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da" -dependencies = [ - "ctutils", - "typenum", -] - -[[package]] -name = "icu_collections" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" -dependencies = [ - "displaydoc", - "potential_utf", - "utf8_iter", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locale_core" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_normalizer" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" -dependencies = [ - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" - -[[package]] -name = "icu_properties" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" -dependencies = [ - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "zerotrie", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" - -[[package]] -name = "icu_provider" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" -dependencies = [ - "displaydoc", - "icu_locale_core", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", -] - -[[package]] -name = "idna" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - -[[package]] -name = "indexmap" -version = "2.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" -dependencies = [ - "equivalent", - "hashbrown", -] - -[[package]] -name = "inout" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" -dependencies = [ - "generic-array", -] - -[[package]] -name = "itoa" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" - -[[package]] -name = "jobserver" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" -dependencies = [ - "getrandom 0.3.4", - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.103" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" -dependencies = [ - "cfg-if", - "futures-util", - "wasm-bindgen", -] - -[[package]] -name = "keccak" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" -dependencies = [ - "cpufeatures 0.2.17", -] - -[[package]] -name = "keccak" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e24a010dd405bd7ed803e5253182815b41bf2e6a80cc3bfc066658e03a198aa" -dependencies = [ - "cfg-if", - "cpufeatures 0.3.0", -] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "libc" -version = "0.2.186" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" - -[[package]] -name = "libm" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" - -[[package]] -name = "litemap" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" - -[[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.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" - -[[package]] -name = "lru-slab" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" - -[[package]] -name = "memchr" -version = "2.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" - -[[package]] -name = "minicov" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4869b6a491569605d66d3952bcdf03df789e5b536e5f0cf7758a7f08a55ae24d" -dependencies = [ - "cc", - "walkdir", -] - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "mio" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" -dependencies = [ - "libc", - "wasi", - "windows-sys 0.61.2", -] - -[[package]] -name = "ml-dsa" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add6b9d92e496f16f4526d68ff29da1483aba4b119baeab8bed3b9e3544a6f3d" -dependencies = [ - "const-oid 0.10.2", - "crypto-common 0.2.2", - "ctutils", - "hybrid-array", - "module-lattice", - "pkcs8 0.11.0", - "shake", - "signature 3.0.0", -] - -[[package]] -name = "mlkem-rs" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b0965b8b081668ff0398dc5e9dc3f2ebb9e833393f4ab5b9f725ddce11acef8" -dependencies = [ - "rand_core 0.6.4", - "serde", - "sha3", - "subtle", - "zeroize", -] - -[[package]] -name = "mlkem-tls" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77b205d031298adf904d88efd6a57862d8650a4ab754aade19a9b5e87040bf4e" -dependencies = [ - "mlkem-rs", - "rand_core 0.6.4", - "subtle", - "x25519-dalek", - "zeroize", -] - -[[package]] -name = "module-lattice" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c61b87c9683ab7cb1c6871d261ad5479b6b10ceb52c4352aaca3b5d35a8febe" -dependencies = [ - "ctutils", - "hybrid-array", - "num-traits", -] - -[[package]] -name = "mtp" -version = "0.1.0" -dependencies = [ - "mtp-client", - "mtp-codec", - "mtp-common", - "mtp-crypto", - "mtp-host", - "mtp-transport", - "mtp-type-map", -] - -[[package]] -name = "mtp-client" -version = "0.1.0" -dependencies = [ - "mtp-codec", - "mtp-common", - "mtp-crypto", - "mtp-transport", - "rand 0.8.6", - "tokio", -] - -[[package]] -name = "mtp-codec" -version = "0.1.0" -dependencies = [ - "base64", - "byteorder", - "mtp-common", - "mtp-crypto", - "mtp-type-map", - "rand 0.8.6", -] - -[[package]] -name = "mtp-common" -version = "0.1.0" -dependencies = [ - "quinn", - "rustls", - "thiserror", - "wtransport", -] - -[[package]] -name = "mtp-crypto" -version = "0.1.0" -dependencies = [ - "aes-gcm", - "chacha20poly1305", - "ed25519-dalek", - "getrandom 0.4.3", - "hkdf", - "ml-dsa", - "mlkem-tls", - "rand_core 0.6.4", - "serde", - "sha2 0.11.0", - "zeroize", -] - -[[package]] -name = "mtp-host" -version = "0.1.0" -dependencies = [ - "mtp-codec", - "mtp-common", - "mtp-crypto", - "mtp-transport", - "rand 0.8.6", - "tokio", -] - -[[package]] -name = "mtp-transport" -version = "0.1.0" -dependencies = [ - "log", - "mtp-codec", - "mtp-common", - "quinn", - "rcgen", - "rustls", - "rustls-native-certs", - "thiserror", - "tokio", - "wtransport", -] - -[[package]] -name = "mtp-type-map" -version = "0.1.0" -dependencies = [ - "serde", - "serde_yaml", -] - -[[package]] -name = "mtp-wasm" -version = "0.1.0" -dependencies = [ - "console_error_panic_hook", - "getrandom 0.2.17", - "getrandom 0.4.3", - "hex", - "js-sys", - "mtp-codec", - "mtp-common", - "mtp-crypto", - "mtp-type-map", - "serde", - "serde-wasm-bindgen", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test", - "web-sys", -] - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "nu-ansi-term" -version = "0.50.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "num-bigint" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" -dependencies = [ - "num-integer", - "num-traits", -] - -[[package]] -name = "num-conv" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", - "libm", -] - -[[package]] -name = "octets" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8311fa8ab7a57759b4ff1f851a3048d9ef0effaa0130726426b742d26d8a88e7" - -[[package]] -name = "oid-registry" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f40cff3dde1b6087cc5d5f5d4d65712f34016a03ed60e9c08dcc392736b5b7" -dependencies = [ - "asn1-rs", -] - -[[package]] -name = "once_cell" -version = "1.21.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" - -[[package]] -name = "oorandom" -version = "11.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" - -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - -[[package]] -name = "openssl-probe" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" - -[[package]] -name = "parking_lot" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-link", -] - -[[package]] -name = "pem" -version = "3.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be" -dependencies = [ - "base64", - "serde_core", -] - -[[package]] -name = "pem-rfc7468" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" -dependencies = [ - "base64ct", -] - -[[package]] -name = "percent-encoding" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" - -[[package]] -name = "pin-project-lite" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" - -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der 0.7.10", - "spki 0.7.3", -] - -[[package]] -name = "pkcs8" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "451913da69c775a56034ea8d9003d27ee8948e12443eae7c038ba100a4f21cb7" -dependencies = [ - "der 0.8.0", - "spki 0.8.0", -] - -[[package]] -name = "poly1305" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" -dependencies = [ - "cpufeatures 0.2.17", - "opaque-debug", - "universal-hash", -] - -[[package]] -name = "polyval" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" -dependencies = [ - "cfg-if", - "cpufeatures 0.2.17", - "opaque-debug", - "universal-hash", -] - -[[package]] -name = "potential_utf" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" -dependencies = [ - "zerovec", -] - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "proc-macro2" -version = "1.0.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quinn" -version = "0.11.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8" -dependencies = [ - "bytes", - "cfg_aliases", - "pin-project-lite", - "quinn-proto", - "quinn-udp", - "rustc-hash", - "rustls", - "socket2", - "thiserror", - "tokio", - "tracing", - "web-time", -] - -[[package]] -name = "quinn-proto" -version = "0.11.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fcb935c5bec503c2f0e306bdd3e58bb9029dcb14fa8d9ac76e3a5256ac0763e" -dependencies = [ - "aws-lc-rs", - "bytes", - "getrandom 0.3.4", - "lru-slab", - "rand 0.9.4", - "ring", - "rustc-hash", - "rustls", - "rustls-pki-types", - "slab", - "thiserror", - "tinyvec", - "tracing", - "web-time", -] - -[[package]] -name = "quinn-udp" -version = "0.5.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" -dependencies = [ - "cfg_aliases", - "libc", - "once_cell", - "socket2", - "tracing", - "windows-sys 0.60.2", -] - -[[package]] -name = "quote" -version = "1.0.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "r-efi" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" - -[[package]] -name = "r-efi" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" - -[[package]] -name = "rand" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" -dependencies = [ - "rand_chacha 0.9.0", - "rand_core 0.9.5", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" -dependencies = [ - "ppv-lite86", - "rand_core 0.9.5", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.17", -] - -[[package]] -name = "rand_core" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" -dependencies = [ - "getrandom 0.3.4", -] - -[[package]] -name = "rand_core" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" - -[[package]] -name = "rcgen" -version = "0.14.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57f6d249aad744e274e682777a50283a225a32705394ee6d5fcc01efa25e4055" -dependencies = [ - "aws-lc-rs", - "pem", - "ring", - "rustls-pki-types", - "time", - "x509-parser", - "yasna", -] - -[[package]] -name = "redox_syscall" -version = "0.5.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" -dependencies = [ - "bitflags", -] - -[[package]] -name = "ring" -version = "0.17.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" -dependencies = [ - "cc", - "cfg-if", - "getrandom 0.2.17", - "libc", - "untrusted 0.9.0", - "windows-sys 0.52.0", -] - -[[package]] -name = "rustc-hash" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" - -[[package]] -name = "rustc_version" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver", -] - -[[package]] -name = "rusticata-macros" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" -dependencies = [ - "nom", -] - -[[package]] -name = "rustls" -version = "0.23.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b92b125634d9b795e7beca796cc790df15a7fb38323bf3196fda83292d06b1f" -dependencies = [ - "aws-lc-rs", - "log", - "once_cell", - "ring", - "rustls-pki-types", - "rustls-webpki", - "subtle", - "zeroize", -] - -[[package]] -name = "rustls-native-certs" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d" -dependencies = [ - "openssl-probe", - "rustls-pki-types", - "schannel", - "security-framework", -] - -[[package]] -name = "rustls-pki-types" -version = "1.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" -dependencies = [ - "web-time", - "zeroize", -] - -[[package]] -name = "rustls-webpki" -version = "0.103.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" -dependencies = [ - "aws-lc-rs", - "ring", - "rustls-pki-types", - "untrusted 0.9.0", -] - -[[package]] -name = "rustversion" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" - -[[package]] -name = "ryu" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "schannel" -version = "0.1.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "security-framework" -version = "3.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "semver" -version = "1.0.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" - -[[package]] -name = "serde" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" -dependencies = [ - "serde_core", - "serde_derive", -] - -[[package]] -name = "serde-wasm-bindgen" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" -dependencies = [ - "js-sys", - "serde", - "wasm-bindgen", -] - -[[package]] -name = "serde_core" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.150" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" -dependencies = [ - "itoa", - "memchr", - "serde", - "serde_core", - "zmij", -] - -[[package]] -name = "serde_yaml" -version = "0.9.34+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" -dependencies = [ - "indexmap", - "itoa", - "ryu", - "serde", - "unsafe-libyaml", -] - -[[package]] -name = "sha2" -version = "0.10.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" -dependencies = [ - "cfg-if", - "cpufeatures 0.2.17", - "digest 0.10.7", -] - -[[package]] -name = "sha2" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" -dependencies = [ - "cfg-if", - "cpufeatures 0.3.0", - "digest 0.11.3", -] - -[[package]] -name = "sha3" -version = "0.10.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77fd7028345d415a4034cf8777cd4f8ab1851274233b45f84e3d955502d93874" -dependencies = [ - "digest 0.10.7", - "keccak 0.1.6", -] - -[[package]] -name = "shake" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09057cb2149ad4cbd2da1e26b351f9a4c354219421229c69c3063e6f61947c4a" -dependencies = [ - "digest 0.11.3", - "keccak 0.2.0", - "sponge-cursor", -] - -[[package]] -name = "shlex" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" - -[[package]] -name = "signal-hook-registry" -version = "1.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" -dependencies = [ - "errno", - "libc", -] - -[[package]] -name = "signature" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" -dependencies = [ - "rand_core 0.6.4", -] - -[[package]] -name = "signature" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d567dcbaf0049cb8ac2608a76cd95ff9e4412e1899d389ee400918ca7537f5" -dependencies = [ - "digest 0.11.3", - "rand_core 0.10.1", -] - -[[package]] -name = "slab" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" - -[[package]] -name = "smallvec" -version = "1.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" - -[[package]] -name = "socket2" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" -dependencies = [ - "libc", - "windows-sys 0.61.2", -] - -[[package]] -name = "spki" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" -dependencies = [ - "base64ct", - "der 0.7.10", -] - -[[package]] -name = "spki" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d9efca8738c78ee9484207732f728b1ef517bbb1833d6fc0879ca898a522f6f" -dependencies = [ - "base64ct", - "der 0.8.0", -] - -[[package]] -name = "sponge-cursor" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a0219bd7d979d58245a4f41f695e1ac9f8befdffadd7f61f1bae9e39abc6620" - -[[package]] -name = "stable_deref_trait" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "syn" -version = "2.0.118" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "synstructure" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "thiserror" -version = "2.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "2.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "time" -version = "0.3.51" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c17d80feb7334b40c484e45ed1a5273dfd8bfda537c3be2e74a06a6686f327" -dependencies = [ - "deranged", - "num-conv", - "powerfmt", - "serde_core", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" - -[[package]] -name = "time-macros" -version = "0.2.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcef1a61bdb119096e153208ec5cbec23944ce8bca13be5c7f60c634f7403935" -dependencies = [ - "num-conv", - "time-core", -] - -[[package]] -name = "tinystr" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" -dependencies = [ - "displaydoc", - "zerovec", -] - -[[package]] -name = "tinyvec" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "tokio" -version = "1.52.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" -dependencies = [ - "bytes", - "libc", - "mio", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "windows-sys 0.61.2", -] - -[[package]] -name = "tokio-macros" -version = "2.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tracing" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tracing-core" -version = "0.1.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" -dependencies = [ - "once_cell", -] - -[[package]] -name = "typenum" -version = "1.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" - -[[package]] -name = "unicode-ident" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" - -[[package]] -name = "universal-hash" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" -dependencies = [ - "crypto-common 0.1.7", - "subtle", -] - -[[package]] -name = "unsafe-libyaml" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" - -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - -[[package]] -name = "url" -version = "2.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", - "serde", -] - -[[package]] -name = "utf8_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - -[[package]] -name = "wasip2" -version = "1.0.4+wasi-0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" -dependencies = [ - "wit-bindgen", -] - -[[package]] -name = "wasm-bindgen" -version = "0.2.126" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" -dependencies = [ - "cfg-if", - "once_cell", - "rustversion", - "wasm-bindgen-macro", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.76" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62df1340f32221cb9c54d6a27b030e3dba64361d4a95bed55f9aacb44da291d" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.126" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.126" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" -dependencies = [ - "bumpalo", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.126" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "wasm-bindgen-test" -version = "0.3.76" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0d555ca874445df8d314f94f5c948a4e74e5418f332c89f660a3d8310a96f4" -dependencies = [ - "async-trait", - "cast", - "js-sys", - "libm", - "minicov", - "nu-ansi-term", - "num-traits", - "oorandom", - "serde", - "serde_json", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test-macro", - "wasm-bindgen-test-shared", -] - -[[package]] -name = "wasm-bindgen-test-macro" -version = "0.3.76" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94eb68555b95bcea5e8cf4abe280b529049479fa995bfc23734af96a6aedc120" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "wasm-bindgen-test-shared" -version = "0.2.126" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31d56021e873866c968588ed85ccdf56db5c426e44afdb4618c39895104b920" - -[[package]] -name = "web-sys" -version = "0.3.103" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "web-time" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "winapi-util" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "windows-link" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.5", -] - -[[package]] -name = "windows-sys" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", -] - -[[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_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - -[[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_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - -[[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_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - -[[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_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - -[[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_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - -[[package]] -name = "wit-bindgen" -version = "0.57.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" - -[[package]] -name = "writeable" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" - -[[package]] -name = "wtransport" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea4aacf790813ee1956751491800537f4e04af7557b7b370501ccbfbc85963e4" -dependencies = [ - "bytes", - "pem", - "quinn", - "rcgen", - "rustls", - "rustls-native-certs", - "rustls-pki-types", - "sha2 0.11.0", - "socket2", - "thiserror", - "time", - "tokio", - "tracing", - "url", - "wtransport-proto", - "x509-parser", -] - -[[package]] -name = "wtransport-proto" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5867c629e4252f7439d82315923daaf27f4fa442410d51b78ab93ef4c432a11" -dependencies = [ - "httlib-huffman", - "octets", - "thiserror", - "url", -] - -[[package]] -name = "x25519-dalek" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" -dependencies = [ - "curve25519-dalek", - "rand_core 0.6.4", - "serde", - "zeroize", -] - -[[package]] -name = "x509-parser" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d43b0f71ce057da06bc0851b23ee24f3f86190b07203dd8f567d0b706a185202" -dependencies = [ - "asn1-rs", - "aws-lc-rs", - "data-encoding", - "der-parser", - "lazy_static", - "nom", - "oid-registry", - "ring", - "rusticata-macros", - "thiserror", - "time", -] - -[[package]] -name = "yasna" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5f6765e852b9b4dc8e2a76843e4d64d1cea8e79bcde0b6901aea8e7c7f08282" -dependencies = [ - "bit-vec", - "time", -] - -[[package]] -name = "yoke" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" -dependencies = [ - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zerocopy" -version = "0.8.52" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.52" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "zerofrom" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zeroize" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "zerotrie" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", -] - -[[package]] -name = "zerovec" -version = "0.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "zmij" -version = "1.0.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/Cargo.toml b/Cargo.toml index 8cc74c0..255d8e6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,24 +9,6 @@ members = [ "client", "wasm", ] -# `wasm` is a wasm32-only crate: it relies on web-sys unstable APIs -# (`--cfg=web_sys_unstable_apis`, set in wasm/.cargo/config.toml) and the -# wasm32 target. Cargo only reads .cargo/config.toml from the invocation -# directory and its ancestors, so building it for the host target from the -# workspace root fails. Exclude it from the default set so a bare -# `cargo build`/`test`/`clippy` at the root matches CI, which always uses -# `--exclude mtp-wasm`. Build it explicitly with: -# cargo build -p mtp-wasm --target wasm32-unknown-unknown -default-members = [ - ".", - "common", - "crypto", - "type-map", - "codec", - "transport", - "host", - "client", -] resolver = "3" # ============================================================================= diff --git a/NATIVE-CLIENT.md b/NATIVE-CLIENT.md index 3e54f5a..8f09062 100644 --- a/NATIVE-CLIENT.md +++ b/NATIVE-CLIENT.md @@ -151,12 +151,12 @@ A `Keyring` bundles all secret and public key material for one identity: ```rust pub struct Keyring { - pub kem_public_key: KemPublicKey, pub kem_secret_key: KemPrivateKey, - pub sig_pq_public_key: SignaturePqPublicKey, // ML-DSA-65 - pub sig_pq_secret_key: SignaturePqPrivateKey, + pub kem_public_key: KemPublicKey, + pub sig_cl_secret_key: SignaturePrivateKey, // Ed25519 pub sig_cl_public_key: SignaturePublicKey, // Ed25519 - pub sig_cl_secret_key: SignaturePrivateKey, + pub sig_pq_secret_key: SignaturePqPrivateKey, // ML-DSA-65 + pub sig_pq_public_key: SignaturePqPublicKey, // ML-DSA-65 } ``` @@ -238,24 +238,19 @@ force-closes the QUIC connection if the peer has not already done so. ## Crypto Containers With the `crypto` feature, `DataValue` supports encrypted, signed, and -signed+encrypted containers. Encryption uses ML-KEM to encapsulate to a -recipient's KEM public key (from their `PublicKeyBundle`); only the holder of -the matching `Keyring` can decrypt. Signing uses the sender's Ed25519 key. +signed+encrypted containers: ```rust -use mtp::crypto::{EncryptionType, Ed25519Signer, SigAlgorithm}; +use mtp::crypto::{ChaCha20Poly1305, Ed25519Signer, SigAlgorithm}; -let enc_type = EncryptionType::MlKemChaCha20Poly1305; +let cipher = ChaCha20Poly1305::new(derive_encryption_key(...)); let signer = Ed25519Signer::new(&keyring.sig_cl_secret_key)?; -// `recipient` is the PublicKeyBundle of whoever should be able to decrypt -// (e.g. the host's bundle, obtained out of band). - // Encrypted container let mut enc = DataValue::Container(vec![ (DataTypeId(1), DataValue::Str("secret".into())), ]); -enc.encrypt_container(enc_type, &recipient, b"aad"); +enc.encrypt_container(&cipher, b"aad"); // Signed container let mut sig = DataValue::Container(vec![ @@ -267,18 +262,11 @@ sig.sign_container(SigAlgorithm::ED25519, &signer); let mut sec = DataValue::Container(vec![ (DataTypeId(1), DataValue::Str("both".into())), ]); -sec.sign_and_encrypt_container(SigAlgorithm::ED25519, &signer, enc_type, &recipient, b"aad"); +sec.sign_and_encrypt_container(SigAlgorithm::ED25519, &signer, &cipher, b"aad"); ``` -On the receiving side, the recipient decrypts with its own `Keyring` (each blob -is self-describing — its leading byte selects the algorithm and the matching KEM -key from the keyring): - -```rust -enc.decrypt_into_container(&keyring, b"aad"); // -> Container -sig.verify_into_container(&verifier); // verifier: impl SignatureScheme -sec.decrypt_signed_encrypted_container(&keyring, b"aad"); // -> SignedContainer, then verify_into_container -``` +On the receiving side, use the corresponding `decrypt_into_container`, +`verify_into_container`, or `decrypt_signed_encrypted_container` methods. ## Policy Configuration @@ -333,3 +321,5 @@ version and expects the host to negotiate a compatible version. | `AuthenticationFailed` | Nonce mismatch or invalid host signature | | `ConnectionError` | QUIC connection failure | | `UseAfterClosed` | Attempted send/receive after close | + + diff --git a/WASM-CLIENT.md b/WASM-CLIENT.md index b27b45e..1638892 100644 --- a/WASM-CLIENT.md +++ b/WASM-CLIENT.md @@ -37,7 +37,7 @@ if (!WasmClient.is_supported()) { const config = new ConnectionConfig("https://host.example.com:4433"); config.client_id = 12345n; // optional, for re-authentication config.server_certificate_hashes = [ // optional, for certificate pinning - "sha-256:abc123...", + "sha256:abc123...", ]; ``` @@ -55,12 +55,11 @@ providing its hash: ```typescript config.server_certificate_hashes = [ - "sha-256:abcd1234...", // hex-encoded hash value + "sha256:abcd1234...", // hex-encoded hash value ]; ``` -The hash format is `":"`, where the only algorithm -the browser's WebTransport API currently accepts is `sha-256`. When hashes are +The hash format is `":"`. When hashes are provided, the browser **only** trusts certificates matching one of the given hashes and ignores its root store for this connection. @@ -173,16 +172,13 @@ binary payload. Useful for health checks and simple messaging. function build_demo_message( clientId: bigint, keyringBytes: Uint8Array, - hostBundleBytes: Uint8Array, ): Uint8Array; ``` Constructs a `Ping` frame that demonstrates encrypted, signed, and -signed+encrypted containers. The containers are ML-KEM-encrypted to the host's -`PublicKeyBundle` (`hostBundleBytes`, the same bytes passed to `auth_connect` / -`auth_register`), so the host decrypts them with its own keyring; signatures use -the client keyring's Ed25519 key. The client keyring only needs its Ed25519 -signing key for this demo. +signed+encrypted containers using a deterministic demo key. The paired host +handler can decrypt and verify these containers if it knows the same shared +secret. ### `parse_auth_response` diff --git a/client/src/lib.rs b/client/src/lib.rs index 9226838..0df6e7e 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -1,21 +1,9 @@ -use mtp_codec::{CommunicationValue, DataType, DataValue, PROTOCOL_VERSION, Version}; +#[cfg(feature = "crypto")] +use mtp_codec::DataType; +use mtp_codec::{CommunicationValue, DataTypeId, DataValue, PROTOCOL_VERSION, Version}; use mtp_common::CommunicationError; use mtp_transport::{Policy, Receiver, Sender}; -#[cfg(feature = "crypto")] -fn unexpected_response_type_error( - context: &str, - expected_type: mtp_codec::CommunicationTypeId, - response: &CommunicationValue, -) -> CommunicationError { - CommunicationError::AuthenticationFailed(format!( - "unexpected response type during {context}: expected {:?}, got {:?}; parsed {}", - expected_type, - response.get_type(), - response - )) -} - pub struct ClientConfig { pub url: String, pub server_cert: Option>, @@ -57,9 +45,9 @@ impl MTPClient { // Build the initial identification message with the protocol version. let version_str = format!("{}", PROTOCOL_VERSION); let ident = CommunicationValue::new(mtp_codec::CommunicationType::Identification) - .add_typed_default(DataType::Version, DataValue::Str(version_str)) - .add_typed_default( - DataType::Id, + .add_data(DataTypeId(3), DataValue::Str(version_str)) + .add_data( + DataTypeId(6), DataValue::UnsignedNumber(config.client_id.into()), ); @@ -136,18 +124,7 @@ impl MTPClient { // 2. Receive host response (single message) let response = receiver.receive().await?; - let tm = mtp_codec::TypeMap::latest(); - - let expected_type = mtp_codec::CommunicationType::IdentificationResponse.to_id(&tm); - if response.get_type() != expected_type { - return Err(unexpected_response_type_error( - "auth_connect", - expected_type, - &response, - )); - } - - let connected = response.get_data(DataType::Connected.to_id(&tm)); + let connected = response.get_data(DataTypeId(11)); match connected { DataValue::BoolTrue => {} DataValue::BoolFalse => { @@ -162,7 +139,7 @@ impl MTPClient { } } - let echo_nonce = response.get_data(DataType::ClientNonce.to_id(&tm)); + let echo_nonce = response.get_data(DataTypeId(7)); match echo_nonce { DataValue::UnsignedNumber(n) if *n == client_nonce as u128 => {} _ => { @@ -172,8 +149,8 @@ impl MTPClient { } } - let host_new_nonce = match response.get_data(DataType::Timestamp.to_id(&tm)) { - DataValue::UnsignedNumber(n) => *n, + let host_new_nonce = match response.get_data(DataTypeId(5)) { + DataValue::UnsignedNumber(n) => *n as u128, _ => { return Err(CommunicationError::AuthenticationFailed( "Missing new nonce".into(), @@ -181,7 +158,7 @@ impl MTPClient { } }; - let host_sig = match response.get_data(DataType::Signature.to_id(&tm)) { + let host_sig = match response.get_data(DataTypeId(10)) { DataValue::Bytes(b) => b.clone(), _ => { return Err(CommunicationError::AuthenticationFailed( @@ -190,7 +167,7 @@ impl MTPClient { } }; - let host_pq_sig = match response.get_data(DataType::PqSignature.to_id(&tm)) { + let host_pq_sig = match response.get_data(DataTypeId(12)) { DataValue::Bytes(b) => b.clone(), _ => vec![], }; @@ -287,18 +264,7 @@ impl MTPClient { // 2. Receive host response (single message) let response = receiver.receive().await?; - let tm = mtp_codec::TypeMap::latest(); - - let expected_type = mtp_codec::CommunicationType::RegisterResponse.to_id(&tm); - if response.get_type() != expected_type { - return Err(unexpected_response_type_error( - "auth_register", - expected_type, - &response, - )); - } - - let connected = response.get_data(DataType::Connected.to_id(&tm)); + let connected = response.get_data(DataTypeId(11)); match connected { DataValue::BoolTrue => {} DataValue::BoolFalse => { @@ -313,8 +279,8 @@ impl MTPClient { } } - let assigned_id = match response.get_data(DataType::Id.to_id(&tm)) { - DataValue::UnsignedNumber(n) => *n, + let assigned_id = match response.get_data(DataTypeId(6)) { + DataValue::UnsignedNumber(n) => *n as u128, _ => { return Err(CommunicationError::AuthenticationFailed( "Missing assigned ID".into(), @@ -322,7 +288,7 @@ impl MTPClient { } }; - let echo_nonce = response.get_data(DataType::ClientNonce.to_id(&tm)); + let echo_nonce = response.get_data(DataTypeId(7)); match echo_nonce { DataValue::UnsignedNumber(n) if *n == client_nonce as u128 => {} _ => { @@ -332,8 +298,8 @@ impl MTPClient { } } - let host_new_nonce = match response.get_data(DataType::Timestamp.to_id(&tm)) { - DataValue::UnsignedNumber(n) => *n, + let host_new_nonce = match response.get_data(DataTypeId(5)) { + DataValue::UnsignedNumber(n) => *n as u128, _ => { return Err(CommunicationError::AuthenticationFailed( "Missing new nonce".into(), @@ -341,7 +307,7 @@ impl MTPClient { } }; - let host_sig = match response.get_data(DataType::Signature.to_id(&tm)) { + let host_sig = match response.get_data(DataTypeId(10)) { DataValue::Bytes(b) => b.clone(), _ => { return Err(CommunicationError::AuthenticationFailed( @@ -350,7 +316,7 @@ impl MTPClient { } }; - let host_pq_sig = match response.get_data(DataType::PqSignature.to_id(&tm)) { + let host_pq_sig = match response.get_data(DataTypeId(12)) { DataValue::Bytes(b) => b.clone(), _ => vec![], }; diff --git a/codec/Cargo.toml b/codec/Cargo.toml index 6dc27bd..6e91169 100644 --- a/codec/Cargo.toml +++ b/codec/Cargo.toml @@ -14,4 +14,4 @@ rand = { version = "0.8", features = ["std", "std_rng"] } [features] default = [] registry = ["mtp-type-map/registry"] -crypto = ["dep:mtp-crypto", "mtp-crypto/mlkem-tls"] +crypto = ["dep:mtp-crypto"] diff --git a/codec/src/communication_value.rs b/codec/src/communication_value.rs index 7dbfec0..0721398 100644 --- a/codec/src/communication_value.rs +++ b/codec/src/communication_value.rs @@ -146,35 +146,18 @@ impl CommunicationValue { * bit3 => is data encrypted If so data bytes will be an encrypted container * bit4 => is communication value signed */ - /* - * Build the canonical metadata header and data payload shared by both - * `to_bytes` and `build_signed_payload`. Keeping a single source here - * guarantees the serialized frame and the signed-over bytes stay in sync. - * - * Returns `(metadata, data_bytes)` where - * metadata = comm_type || flags || id? || sender? || receiver? - * - * `force_signed` forces the `FLAG_SIGNED` bit on regardless of whether a - * signature is currently attached. The signed-payload path passes `true` so - * that the bytes signed by `sign_frame` (before the signature is stored) and - * the bytes verified by `verify_frame` (after it is stored) are identical. - */ - fn build_metadata_and_data( - &self, - force_signed: bool, - ) -> Result<(Vec, Vec), CodecError> { + pub fn to_bytes(&self) -> Vec { let has_sender = self.sender != 0; let has_receiver = self.receiver != 0; let has_id = self.id != 0; #[cfg(feature = "crypto")] - let is_encrypted = self.data.len() == 1 - && self.data.values().any(|v| { - matches!( - v, - DataValue::EncryptedContainer(_) | DataValue::SignedEncryptedContainer(_) - ) - }); + let is_encrypted = self.data.len() == 1 && self.data.values().any(|v| { + matches!( + v, + DataValue::EncryptedContainer(_) | DataValue::SignedEncryptedContainer(_) + ) + }); #[cfg(not(feature = "crypto"))] let is_encrypted = false; @@ -196,7 +179,7 @@ impl CommunicationValue { if is_encrypted { flags |= FLAG_ENCRYPTED; } - if has_frame_sig || force_signed { + if has_frame_sig { flags |= FLAG_SIGNED; } @@ -229,39 +212,34 @@ impl CommunicationValue { }) .unwrap_or_default() } else { - DataValue::container_from_map(&self.data).to_bytes()? + let container_value = DataValue::container_from_map(&self.data); + container_value.to_bytes() }; #[cfg(not(feature = "crypto"))] - let data_bytes = DataValue::container_from_map(&self.data).to_bytes()?; - - Ok((metadata, data_bytes)) - } - - pub fn to_bytes(&self) -> Result, CodecError> { - let (metadata, data_bytes) = self.build_metadata_and_data(false)?; + let data_bytes = { + let container_value = DataValue::container_from_map(&self.data); + container_value.to_bytes() + }; let mut payload = Vec::new(); payload.extend_from_slice(&metadata); #[cfg(feature = "crypto")] - if let Some((alg, sig)) = &self.frame_signature { + if let Some((_alg, _sig)) = &self.frame_signature { // algorithm and signature are computed by sign_frame() and stored. // The frame bytes are built by using the pre-computed signature. - payload.push(*alg); - payload.extend_from_slice(sig); + payload.push(*_alg); + payload.extend_from_slice(_sig); } payload.extend_from_slice(&data_bytes); - let len = u32::try_from(payload.len()).map_err(|_| CodecError::TooManyEntries)?; let mut frame = Vec::with_capacity(4 + payload.len()); - frame - .write_u32::(len) - .map_err(|_| CodecError::InvalidEncoding)?; + let _ = frame.write_u32::(payload.len() as u32); frame.extend_from_slice(&payload); - Ok(frame) + frame } pub fn from_bytes(bytes: &[u8]) -> Result { @@ -324,7 +302,8 @@ impl CommunicationValue { #[cfg(feature = "crypto")] let frame_signature = if is_signed { let alg = cursor.read_u8().map_err(|_| CodecError::InvalidEncoding)?; - let sig_len = SigAlgorithm::length(alg).ok_or(CodecError::InvalidEncoding)?; + let sig_len = + SigAlgorithm::length(alg).ok_or(CodecError::InvalidEncoding)?; let mut sig = vec![0u8; sig_len]; cursor .read_exact(&mut sig) @@ -388,8 +367,12 @@ impl CommunicationValue { * signature before the data payload. */ #[cfg(feature = "crypto")] - pub fn sign_frame(&mut self, algorithm: u8, signer: &impl SignatureScheme) -> Option<()> { - let signed_payload = self.build_signed_payload().ok()?; + pub fn sign_frame( + &mut self, + algorithm: u8, + signer: &impl SignatureScheme, + ) -> Option<()> { + let signed_payload = self.build_signed_payload(); let sig = signer.sign(&signed_payload).ok()?; self.frame_signature = Some((algorithm, sig)); Some(()) @@ -406,7 +389,7 @@ impl CommunicationValue { .as_ref() .ok_or(CodecError::InvalidEncoding)?; - let signed_payload = self.build_signed_payload()?; + let signed_payload = self.build_signed_payload(); verifier .verify(&signed_payload, sig) .map_err(|_| CodecError::InvalidEncoding) @@ -417,11 +400,75 @@ impl CommunicationValue { * comm_type || flags || id? || sender? || receiver? || data_bytes */ #[cfg(feature = "crypto")] - fn build_signed_payload(&self) -> Result, CodecError> { - // Force FLAG_SIGNED on so the signed bytes match whether or not the - // signature has been attached yet (sign_frame runs before storing it). - let (metadata, data_bytes) = self.build_metadata_and_data(true)?; - Ok([metadata, data_bytes].concat()) + fn build_signed_payload(&self) -> Vec { + let has_sender = self.sender != 0; + let has_receiver = self.receiver != 0; + let has_id = self.id != 0; + + let is_encrypted = self.data.len() == 1 && self.data.values().any(|v| { + matches!( + v, + DataValue::EncryptedContainer(_) | DataValue::SignedEncryptedContainer(_) + ) + }); + + let mut flags: u8 = 0; + if has_sender { + flags |= FLAG_HAS_SENDER; + } + if has_receiver { + flags |= FLAG_HAS_RECEIVER; + } + if has_id { + flags |= FLAG_HAS_ID; + } + if is_encrypted { + flags |= FLAG_ENCRYPTED; + } + if self.frame_signature.is_some() { + flags |= FLAG_SIGNED; + } + + let mut metadata = Vec::new(); + let _ = metadata.write_u16::(self.comm_type.0); + metadata.push(flags); + + if has_id { + let _ = metadata.write_u32::(self.id); + } + + if has_sender { + let sender_be = self.sender.to_be_bytes(); + metadata.extend_from_slice(&sender_be[2..]); + } + + if has_receiver { + let receiver_be = self.receiver.to_be_bytes(); + metadata.extend_from_slice(&receiver_be[2..]); + } + + #[cfg(feature = "crypto")] + let data_bytes = if is_encrypted { + self.data + .values() + .find_map(|v| match v { + DataValue::EncryptedContainer(ct) => Some(ct.clone()), + DataValue::SignedEncryptedContainer(ct) => Some(ct.clone()), + _ => None, + }) + .unwrap_or_default() + } else { + let container_value = DataValue::container_from_map(&self.data); + container_value.to_bytes() + }; + + #[cfg(not(feature = "crypto"))] + let data_bytes = { + let container_value = DataValue::container_from_map(&self.data); + container_value.to_bytes() + }; + + [metadata, data_bytes].concat() } #[cfg(feature = "crypto")] @@ -563,9 +610,9 @@ mod tests { use crate::data_value::DataValue; fn roundtrip(cv: CommunicationValue) -> CommunicationValue { - let bytes = cv.to_bytes().expect("encode failed"); + let bytes = cv.to_bytes(); let decoded = CommunicationValue::from_bytes(&bytes).expect("failed to deserialize"); - let bytes2 = decoded.to_bytes().expect("encode failed"); + let bytes2 = decoded.to_bytes(); assert_eq!(bytes, bytes2); decoded } @@ -573,7 +620,7 @@ mod tests { #[test] fn test_flags_and_order_without_optional() { let cv = CommunicationValue::new(CommunicationType::ErrorParsing).with_id(0); - let bytes = cv.to_bytes().expect("encode failed"); + let bytes = cv.to_bytes(); // [u32 len][u16 type][flags]... assert!(bytes.len() >= 7); @@ -595,7 +642,7 @@ mod tests { .with_sender(0x0000_1122_3344_5566) .with_receiver(0x0000_6677_8899_AABB); - let bytes = cv.to_bytes().expect("encode failed"); + let bytes = cv.to_bytes(); let mut c = Cursor::new(bytes.as_slice()); let total_len = c.read_u32::().expect("len"); @@ -656,45 +703,4 @@ mod tests { bad[0..4].copy_from_slice(&(1000u32.to_be_bytes())); assert!(CommunicationValue::from_bytes(&bad).is_err()); } - - #[cfg(feature = "crypto")] - #[test] - fn test_sign_verify_frame_roundtrip() { - use mtp_crypto::{Ed25519Signer, SigAlgorithm}; - - let (signer, sk, _pk) = Ed25519Signer::generate(); - - let mut cv = CommunicationValue::new(CommunicationType::Ping) - .with_id(7) - .with_sender(1) - .with_receiver(2) - .add_data(DataTypeId(6), DataValue::UnsignedNumber(42)); - - assert!(cv.sign_frame(SigAlgorithm::ED25519, &signer).is_some()); - - // Same in-memory value verifies (FLAG_SIGNED forced on both sides). - let verifier = Ed25519Signer::new(&sk).unwrap(); - assert!(cv.verify_frame(&verifier).is_ok()); - - // Survives a wire round-trip. - let bytes = cv.to_bytes().expect("encode failed"); - let decoded = CommunicationValue::from_bytes(&bytes).expect("decode failed"); - assert!(decoded.verify_frame(&verifier).is_ok()); - } - - #[cfg(feature = "crypto")] - #[test] - fn test_verify_frame_wrong_key_fails() { - use mtp_crypto::{Ed25519Signer, SigAlgorithm}; - - let (signer, _, _) = Ed25519Signer::generate(); - let (_, other_sk, _) = Ed25519Signer::generate(); - - let mut cv = CommunicationValue::new(CommunicationType::Ping) - .add_data(DataTypeId(6), DataValue::UnsignedNumber(42)); - assert!(cv.sign_frame(SigAlgorithm::ED25519, &signer).is_some()); - - let wrong = Ed25519Signer::new(&other_sk).unwrap(); - assert!(cv.verify_frame(&wrong).is_err()); - } } diff --git a/codec/src/data_value.rs b/codec/src/data_value.rs index 9c2c21b..7ccff8d 100644 --- a/codec/src/data_value.rs +++ b/codec/src/data_value.rs @@ -6,11 +6,10 @@ use std::fmt; use std::hash::{Hash, Hasher}; use std::io::Cursor; -use mtp_common::CodecError; use mtp_type_map::DataTypeId; #[cfg(feature = "crypto")] -use mtp_crypto::{EncryptionType, Keyring, PublicKeyBundle, SigAlgorithm, SignatureScheme}; +use mtp_crypto::{AeadDecrypt, AeadEncrypt, SigAlgorithm, SignatureScheme}; #[derive(Debug, Clone, PartialEq, Eq)] pub enum DataKind { @@ -125,9 +124,9 @@ impl DataValue { * 0x07 => Bytes * 0x08 => Array * 0x09 => Container - * 0x0A => EncryptedContainer (1 byte EncryptionType + KEM ciphertext + AEAD payload) - * 0x0B => SignedContainer (1 byte SigAlgorithm + signature + serialized container) - * 0x0C => SignedEncryptedContainer (encrypted blob that decrypts to a SignedContainer) + * 0x0A => EncryptedContainer (4 bytes u32 len + encrypted bytes) + * 0x0B => SignedContainer (4 bytes u32 len + 3373 bytes signature) + * 0x0C => SignedEncryptedContainer (4 bytes u32 len + 3373 bytes signature + encrypted bytes) * 0xFF => Null */ const KIND_BOOL_TRUE: u8 = 0x01; @@ -151,17 +150,10 @@ impl DataValue { const KIND_NULL: u8 = 0xFF; - /// Smallest possible encoded entry, used to cap pre-reservation when - /// decoding containers/arrays so a small frame cannot force a huge - /// allocation from an attacker-controlled count. A bool/null entry in a - /// container is 3 bytes (1 kind + 2 key); a bare value in an array is 1 - /// byte, so 1 is the safe lower bound shared by both. - const MIN_ENTRY_BYTES: usize = 1; - pub fn container_from_map(map: &BTreeMap) -> DataValue { let mut container = Vec::new(); for (key, value) in map { - container.push((*key, value.clone())); + container.push((key.clone(), value.clone())); } DataValue::Container(container) } @@ -280,14 +272,13 @@ impl DataValue { /* * Decrypt an `EncryptedContainer` in-place, replacing it with the - * deserialized `Container`. The algorithm (and which keypair to use) is read - * from the blob's leading `EncryptionType` byte; the matching key is taken - * from `keyring`. Returns `None` if decryption or deserialization fails. + * deserialized `Container`. Returns `None` if decryption or + * deserialization fails. */ #[cfg(feature = "crypto")] - pub fn decrypt_into_container(&mut self, keyring: &Keyring, aad: &[u8]) -> Option<()> { + pub fn decrypt_into_container(&mut self, cipher: &impl AeadDecrypt, aad: &[u8]) -> Option<()> { let data = self.as_encrypted_container()?; - let plaintext = mtp_crypto::decrypt_with(&data, keyring, aad).ok()?; + let plaintext = cipher.decrypt(&data, aad).ok()?; let dv = DataValue::from_bytes(&plaintext)?; match dv { DataValue::Container(entries) => { @@ -300,21 +291,13 @@ impl DataValue { /* * Encrypt a `Container` into an `EncryptedContainer` in-place. - * `enc_type` selects the algorithm and `recipient` provides the public key - * encapsulated to. The resulting blob is self-describing: its leading byte - * is `enc_type`, so `decrypt_into_container` needs only a `Keyring`. * Returns `None` if the value is not a `Container` or encryption fails. */ #[cfg(feature = "crypto")] - pub fn encrypt_container( - &mut self, - enc_type: EncryptionType, - recipient: &PublicKeyBundle, - aad: &[u8], - ) -> Option<()> { + pub fn encrypt_container(&mut self, cipher: &impl AeadEncrypt, aad: &[u8]) -> Option<()> { let entries = self.as_container()?; - let plaintext = DataValue::Container(entries).to_bytes().ok()?; - let ct = mtp_crypto::encrypt_for(enc_type, recipient, &plaintext, aad).ok()?; + let plaintext = DataValue::Container(entries).to_bytes(); + let ct = cipher.encrypt(&plaintext, aad).ok()?; *self = DataValue::EncryptedContainer(ct); Some(()) } @@ -328,7 +311,7 @@ impl DataValue { #[cfg(feature = "crypto")] pub fn sign_container(&mut self, algorithm: u8, signer: &impl SignatureScheme) -> Option<()> { let entries = self.as_container()?; - let container_bytes = Self::encode_container(&entries).ok()?; + let container_bytes = Self::encode_container(&entries); let sig = signer.sign(&container_bytes).ok()?; @@ -371,40 +354,35 @@ impl DataValue { /* * Encrypt a `Container` into a `SignedEncryptedContainer` in-place. - * The container is first signed (with `algorithm`/`signer`), then the signed - * blob is encrypted with `enc_type` to `recipient`. The result is an opaque - * ciphertext that decrypts to a `SignedContainer`. + * The result is an opaque ciphertext that decrypts to a `SignedContainer`. */ #[cfg(feature = "crypto")] pub fn sign_and_encrypt_container( &mut self, algorithm: u8, signer: &impl SignatureScheme, - enc_type: EncryptionType, - recipient: &PublicKeyBundle, + cipher: &impl AeadEncrypt, aad: &[u8], ) -> Option<()> { self.sign_container(algorithm, signer)?; let blob = self.as_signed_container()?; - let ct = mtp_crypto::encrypt_for(enc_type, recipient, &blob, aad).ok()?; + let ct = cipher.encrypt(&blob, aad).ok()?; *self = DataValue::SignedEncryptedContainer(ct); Some(()) } /* * Decrypt a `SignedEncryptedContainer` in-place, replacing it with a - * `SignedContainer`. The algorithm and keypair are resolved from the blob's - * leading byte and `keyring`. Does NOT verify; call `verify_into_container` - * next. + * `SignedContainer`. Does NOT verify; call `verify_into_container` next. */ #[cfg(feature = "crypto")] pub fn decrypt_signed_encrypted_container( &mut self, - keyring: &Keyring, + cipher: &impl AeadDecrypt, aad: &[u8], ) -> Option<()> { let data = self.as_signed_encrypted_container()?; - let plaintext = mtp_crypto::decrypt_with(&data, keyring, aad).ok()?; + let plaintext = cipher.decrypt(&data, aad).ok()?; *self = DataValue::SignedContainer(plaintext); Some(()) } @@ -414,7 +392,7 @@ impl DataValue { DataValue::Container(c) => { let mut out = BTreeMap::new(); for (k, v) in c { - out.insert(*k, v.clone()); + out.insert(k.clone(), v.clone()); } Some(out) } @@ -422,14 +400,16 @@ impl DataValue { } } - pub fn to_bytes(&self) -> Result, CodecError> { + pub fn to_bytes(&self) -> Vec { match self { DataValue::Container(entries) => Self::encode_container(entries), DataValue::Array(arr) => Self::encode_array(arr), _ => { let mut out = Vec::new(); - Self::write_value_payload(&mut out, self)?; - Ok(out) + if Self::write_value_payload(&mut out, self).is_none() { + return Vec::new(); + } + out } } } @@ -443,8 +423,8 @@ impl DataValue { Some(value) } - pub fn to_base64(&self) -> Result { - Ok(general_purpose::STANDARD.encode(self.to_bytes()?)) + pub fn to_base64(&self) -> String { + general_purpose::STANDARD.encode(self.to_bytes()) } pub fn from_base64(base64_str: &str) -> Option { @@ -452,138 +432,144 @@ impl DataValue { Self::from_bytes(&bytes) } - fn encode_container(entries: &[(DataTypeId, DataValue)]) -> Result, CodecError> { + fn encode_container(entries: &[(DataTypeId, DataValue)]) -> Vec { let mut out = Vec::new(); - let count = u16::try_from(entries.len()).map_err(|_| CodecError::TooManyEntries)?; - out.write_u16::(count) - .map_err(|_| CodecError::InvalidEncoding)?; + if out + .write_u16::(u16::try_from(entries.len()).ok().unwrap_or(0)) + .is_err() + { + return Vec::new(); + } for (key, value) in entries { - Self::write_container_entry(&mut out, *key, value)?; + if !Self::write_container_entry(&mut out, key.clone(), value) { + return Vec::new(); + } } - Ok(out) + out } - fn write_container_entry( - buf: &mut Vec, - key: DataTypeId, - value: &DataValue, - ) -> Result<(), CodecError> { + fn write_container_entry(buf: &mut Vec, key: DataTypeId, value: &DataValue) -> bool { let kind = Self::kind_marker(value); buf.push(kind); if kind == Self::KIND_BOOL_TRUE || kind == Self::KIND_BOOL_FALSE || kind == Self::KIND_NULL { - buf.write_u16::(key.0) - .map_err(|_| CodecError::InvalidEncoding)?; - return Ok(()); + let _ = buf.write_u16::(key.0); + return true; } let mut payload = Vec::new(); - Self::write_value_payload(&mut payload, value)?; + if Self::write_value_payload(&mut payload, value).is_none() { + return false; + } - let len = u32::try_from(payload.len()).map_err(|_| CodecError::TooManyEntries)?; - buf.write_u32::(len) - .map_err(|_| CodecError::InvalidEncoding)?; - buf.write_u16::(key.0) - .map_err(|_| CodecError::InvalidEncoding)?; + if buf.write_u32::(payload.len() as u32).is_err() { + return false; + } + let _ = buf.write_u16::(key.0); buf.extend_from_slice(&payload); - Ok(()) + true } - fn encode_array(arr: &[DataValue]) -> Result, CodecError> { + fn encode_array(arr: &[DataValue]) -> Vec { let mut out = Vec::new(); - let count = u16::try_from(arr.len()).map_err(|_| CodecError::TooManyEntries)?; - out.write_u16::(count) - .map_err(|_| CodecError::InvalidEncoding)?; + if out + .write_u16::(u16::try_from(arr.len()).ok().unwrap_or(0)) + .is_err() + { + return Vec::new(); + } for value in arr { - Self::write_array_entry(&mut out, value)?; + if !Self::write_array_entry(&mut out, value) { + return Vec::new(); + } } - Ok(out) + out } - fn write_array_entry(buf: &mut Vec, value: &DataValue) -> Result<(), CodecError> { + fn write_array_entry(buf: &mut Vec, value: &DataValue) -> bool { let kind = Self::kind_marker(value); buf.push(kind); if kind == Self::KIND_BOOL_TRUE || kind == Self::KIND_BOOL_FALSE || kind == Self::KIND_NULL { - return Ok(()); + return true; } let mut payload = Vec::new(); - Self::write_value_payload(&mut payload, value)?; + if Self::write_value_payload(&mut payload, value).is_none() { + return false; + } - let len = u32::try_from(payload.len()).map_err(|_| CodecError::TooManyEntries)?; - buf.write_u32::(len) - .map_err(|_| CodecError::InvalidEncoding)?; + if buf.write_u32::(payload.len() as u32).is_err() { + return false; + } buf.extend_from_slice(&payload); - Ok(()) + true } - fn write_value_payload(buf: &mut Vec, value: &DataValue) -> Result<(), CodecError> { + fn write_value_payload(buf: &mut Vec, value: &DataValue) -> Option<()> { match value { - DataValue::BoolTrue => Ok(()), - DataValue::BoolFalse => Ok(()), - #[allow(clippy::if_same_then_else)] + DataValue::BoolTrue => Some(()), + DataValue::BoolFalse => Some(()), DataValue::Bool(v) => { - // Kept intentionally: the kind marker already encodes the boolean, - // so both arms carry no payload. Retained for clear compatibility. - if *v { Ok(()) } else { Ok(()) } + if *v { + Some(()) + } else { + Some(()) + } } DataValue::SignedNumber(n) => { - buf.write_i128::(*n) - .map_err(|_| CodecError::InvalidEncoding)?; - Ok(()) + buf.write_i128::(*n).ok()?; + Some(()) } DataValue::UnsignedNumber(n) => { - buf.write_u128::(*n) - .map_err(|_| CodecError::InvalidEncoding)?; - Ok(()) + buf.write_u128::(*n).ok()?; + Some(()) } DataValue::Float(a, b) => { - buf.write_u8(*a).map_err(|_| CodecError::InvalidEncoding)?; - buf.write_u32::(*b) - .map_err(|_| CodecError::InvalidEncoding)?; - Ok(()) + buf.write_u8(*a).ok()?; + buf.write_u32::(*b).ok()?; + Some(()) } DataValue::Str(s) => { buf.extend_from_slice(s.as_bytes()); - Ok(()) + Some(()) } DataValue::Array(arr) => { - let bytes = Self::encode_array(arr)?; + let bytes = Self::encode_array(arr); buf.extend_from_slice(&bytes); - Ok(()) + Some(()) } DataValue::Bytes(b) => { buf.extend_from_slice(b); - Ok(()) + Some(()) } DataValue::Container(entries) => { - let bytes = Self::encode_container(entries)?; + let bytes = Self::encode_container(entries); buf.extend_from_slice(&bytes); - Ok(()) + Some(()) } #[cfg(feature = "crypto")] DataValue::EncryptedContainer(data) => { buf.extend_from_slice(data); - Ok(()) + Some(()) } #[cfg(feature = "crypto")] DataValue::SignedContainer(data) => { buf.extend_from_slice(data); - Ok(()) + Some(()) } #[cfg(feature = "crypto")] DataValue::SignedEncryptedContainer(data) => { buf.extend_from_slice(data); - Ok(()) + Some(()) } - DataValue::Null => Ok(()), + DataValue::Null => Some(()), } } @@ -611,11 +597,7 @@ impl DataValue { fn try_read_container(cursor: &mut Cursor<&[u8]>) -> Option { let count = cursor.read_u16::().ok()? as usize; - let remaining = cursor - .get_ref() - .len() - .saturating_sub(cursor.position() as usize); - let mut entries = Vec::with_capacity(count.min(remaining / Self::MIN_ENTRY_BYTES)); + let mut entries = Vec::with_capacity(count); for _ in 0..count { let kind = cursor.read_u8().ok()?; @@ -661,11 +643,7 @@ impl DataValue { fn read_array(cursor: &mut Cursor<&[u8]>) -> Option { let count = cursor.read_u16::().ok()? as usize; - let remaining = cursor - .get_ref() - .len() - .saturating_sub(cursor.position() as usize); - let mut out = Vec::with_capacity(count.min(remaining / Self::MIN_ENTRY_BYTES)); + let mut out = Vec::with_capacity(count); for _ in 0..count { let kind = cursor.read_u8().ok()?; @@ -923,28 +901,62 @@ impl PartialEq for DataValue { impl Hash for DataValue { fn hash(&self, state: &mut H) { use DataValue::*; - // Use the wire kind marker as the per-variant discriminant. It is unique - // per kind and maps BoolTrue/Bool(true) (and BoolFalse/Bool(false)) to the - // same marker, keeping the hash consistent with the Eq bool equivalence. - Self::kind_marker(self).hash(state); match self { - BoolTrue | BoolFalse | Bool(_) | Null => {} - SignedNumber(n) => n.hash(state), - UnsignedNumber(n) => n.hash(state), + BoolTrue | Bool(true) => { + 0u8.hash(state); + true.hash(state); + } + BoolFalse | Bool(false) => { + 0u8.hash(state); + false.hash(state); + } + SignedNumber(n) => { + 1u8.hash(state); + n.hash(state); + } + UnsignedNumber(n) => { + 2u8.hash(state); + n.hash(state); + } Float(n, m) => { + 3u8.hash(state); n.hash(state); m.hash(state); } - Str(s) => s.hash(state), - Array(a) => a.hash(state), - Bytes(a) => a.hash(state), - Container(c) => c.hash(state), + Str(s) => { + 2u8.hash(state); + s.hash(state); + } + Array(a) => { + 3u8.hash(state); + a.hash(state); + } + Bytes(a) => { + 4u8.hash(state); + a.hash(state); + } + Container(c) => { + 5u8.hash(state); + c.hash(state); + } #[cfg(feature = "crypto")] - EncryptedContainer(c) => c.hash(state), + EncryptedContainer(c) => { + 6u8.hash(state); + c.hash(state); + } #[cfg(feature = "crypto")] - SignedContainer(c) => c.hash(state), + SignedContainer(c) => { + 7u8.hash(state); + c.hash(state); + } #[cfg(feature = "crypto")] - SignedEncryptedContainer(c) => c.hash(state), + SignedEncryptedContainer(c) => { + 8u8.hash(state); + c.hash(state); + } + Null => { + 9u8.hash(state); + } } } } @@ -958,14 +970,14 @@ mod tests { /// Scalars must be tested inside a container. fn container_roundtrip(values: Vec<(DataTypeId, DataValue)>) { let dv = DataValue::Container(values.clone()); - let bytes = dv.to_bytes().expect("encode failed"); + let bytes = dv.to_bytes(); let decoded = DataValue::from_bytes(&bytes).expect("roundtrip failed"); assert_eq!(dv, decoded, "container roundtrip mismatch"); } fn array_roundtrip(values: Vec) { let dv = DataValue::Array(values.clone()); - let bytes = dv.to_bytes().expect("encode failed"); + let bytes = dv.to_bytes(); let decoded = DataValue::from_bytes(&bytes).expect("roundtrip failed"); assert_eq!(dv, decoded, "array roundtrip mismatch"); } @@ -1099,7 +1111,7 @@ mod tests { DataTypeId(7), DataValue::Bytes(vec![0xDE, 0xAD, 0xBE, 0xEF]), )]); - let b64 = dv.to_base64().expect("encode failed"); + let b64 = dv.to_base64(); let decoded = DataValue::from_base64(&b64).expect("base64 roundtrip failed"); assert_eq!(dv, decoded); } @@ -1191,28 +1203,12 @@ mod tests { #[test] fn test_truncated_container_rejected() { let dv = DataValue::Container(vec![(DataTypeId(1), DataValue::Str("hello".to_string()))]); - let bytes = dv.to_bytes().expect("encode failed"); + let bytes = dv.to_bytes(); // Truncate to fewer than 2 bytes so neither container nor array can be read assert!(DataValue::from_bytes(&bytes[..1]).is_none()); assert!(DataValue::from_bytes(&bytes[..0]).is_none()); } - #[test] - fn test_oversized_count_does_not_overallocate() { - // A frame declaring 65535 entries but carrying almost no payload must be - // rejected without pre-reserving a Vec for 65535 entries. The capacity is - // capped against remaining bytes, so these decode attempts allocate at - // most a handful of slots before failing. - // Container path: count = 0xFFFF, no entries follow. - assert!(DataValue::from_bytes(&[0xFF, 0xFF]).is_none()); - // Container path with one stray byte after the count. - assert!(DataValue::from_bytes(&[0xFF, 0xFF, 0x01]).is_none()); - // Array path: force the container parse to fail first, then the array - // parse also sees the oversized count. A leading kind byte that is not a - // valid container entry makes try_read_container bail to the array path. - assert!(DataValue::from_bytes(&[0xFF, 0xFF, 0x08, 0xFF, 0xFF]).is_none()); - } - #[test] fn test_display_basic() { assert_eq!(format!("{}", DataValue::BoolTrue), "true"); @@ -1267,22 +1263,19 @@ mod tests { #[cfg(feature = "crypto")] #[test] fn test_encrypt_decrypt_container_roundtrip() { - use mtp_crypto::{EncryptionType, Keyring}; - let keyring = Keyring::generate(); - let bundle = keyring.public_key_bundle(); + use mtp_crypto::ChaCha20Poly1305; + let key = [0xAB; 32]; + let cipher = ChaCha20Poly1305::new(key); let mut dv = DataValue::Container(vec![ (DataTypeId(1), DataValue::Str("secret".to_string())), (DataTypeId(2), DataValue::UnsignedNumber(42)), ]); - assert!( - dv.encrypt_container(EncryptionType::MlKemChaCha20Poly1305, &bundle, b"aad") - .is_some() - ); + assert!(dv.encrypt_container(&cipher, b"aad").is_some()); assert!(matches!(dv, DataValue::EncryptedContainer(_))); - assert!(dv.decrypt_into_container(&keyring, b"aad").is_some()); + assert!(dv.decrypt_into_container(&cipher, b"aad").is_some()); assert!(matches!(dv, DataValue::Container(_))); let entries = dv.as_container().unwrap(); @@ -1292,68 +1285,46 @@ mod tests { #[cfg(feature = "crypto")] #[test] fn test_encrypt_container_wrong_key_fails() { - use mtp_crypto::{EncryptionType, Keyring}; - let keyring_a = Keyring::generate(); - let keyring_b = Keyring::generate(); + use mtp_crypto::ChaCha20Poly1305; + let cipher_a = ChaCha20Poly1305::new([0xAB; 32]); + let cipher_b = ChaCha20Poly1305::new([0xCD; 32]); let mut dv = DataValue::Container(vec![(DataTypeId(1), DataValue::Str("secret".to_string()))]); - assert!( - dv.encrypt_container( - EncryptionType::MlKemChaCha20Poly1305, - &keyring_a.public_key_bundle(), - b"aad" - ) - .is_some() - ); - assert!(dv.decrypt_into_container(&keyring_b, b"aad").is_none()); + assert!(dv.encrypt_container(&cipher_a, b"aad").is_some()); + assert!(dv.decrypt_into_container(&cipher_b, b"aad").is_none()); } #[cfg(feature = "crypto")] #[test] fn test_encrypt_container_wrong_aad_fails() { - use mtp_crypto::{EncryptionType, Keyring}; - let keyring = Keyring::generate(); + use mtp_crypto::ChaCha20Poly1305; + let cipher = ChaCha20Poly1305::new([0xAB; 32]); let mut dv = DataValue::Container(vec![(DataTypeId(1), DataValue::Str("secret".to_string()))]); - assert!( - dv.encrypt_container( - EncryptionType::MlKemChaCha20Poly1305, - &keyring.public_key_bundle(), - b"correct-aad" - ) - .is_some() - ); - assert!(dv.decrypt_into_container(&keyring, b"wrong-aad").is_none()); + assert!(dv.encrypt_container(&cipher, b"correct-aad").is_some()); + assert!(dv.decrypt_into_container(&cipher, b"wrong-aad").is_none()); } #[cfg(feature = "crypto")] #[test] fn test_encrypt_non_container_fails() { - use mtp_crypto::{EncryptionType, Keyring}; - let keyring = Keyring::generate(); + let cipher = mtp_crypto::ChaCha20Poly1305::new([0xAB; 32]); let mut dv = DataValue::Str("not a container".to_string()); - assert!( - dv.encrypt_container( - EncryptionType::MlKemChaCha20Poly1305, - &keyring.public_key_bundle(), - b"aad" - ) - .is_none() - ); + assert!(dv.encrypt_container(&cipher, b"aad").is_none()); } #[cfg(feature = "crypto")] #[test] fn test_sign_verify_container_roundtrip() { - use mtp_crypto::{Ed25519Signer, EncryptionType, Keyring, SigAlgorithm}; + use mtp_crypto::{ChaCha20Poly1305, Ed25519Signer, SigAlgorithm}; - let keyring = Keyring::generate(); let (signer, sk, _pk) = Ed25519Signer::generate(); + let cipher = ChaCha20Poly1305::new([0xAB; 32]); let mut dv = DataValue::Container(vec![( DataTypeId(1), @@ -1361,19 +1332,13 @@ mod tests { )]); assert!( - dv.sign_and_encrypt_container( - SigAlgorithm::ED25519, - &signer, - EncryptionType::MlKemChaCha20Poly1305, - &keyring.public_key_bundle(), - b"aad" - ) - .is_some() + dv.sign_and_encrypt_container(SigAlgorithm::ED25519, &signer, &cipher, b"aad") + .is_some() ); assert!(matches!(dv, DataValue::SignedEncryptedContainer(_))); assert!( - dv.decrypt_signed_encrypted_container(&keyring, b"aad") + dv.decrypt_signed_encrypted_container(&cipher, b"aad") .is_some() ); assert!(matches!(dv, DataValue::SignedContainer(_))); diff --git a/codec/src/lib.rs b/codec/src/lib.rs index 69f15e7..b1e7074 100644 --- a/codec/src/lib.rs +++ b/codec/src/lib.rs @@ -6,8 +6,8 @@ pub use data_value::{DataKind, DataValue}; pub use mtp_common::CodecError; pub use mtp_type_map::{ - CommunicationType, CommunicationTypeId, DataType, DataTypeId, PROTOCOL_VERSION, TypeMap, - Version, communication_type_name, data_type_name, + communication_type_name, data_type_name, CommunicationType, CommunicationTypeId, DataType, + DataTypeId, TypeMap, Version, PROTOCOL_VERSION, }; pub(crate) fn rand_u32() -> u32 { diff --git a/common/src/lib.rs b/common/src/lib.rs index 05ac9f6..7637d37 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -12,8 +12,6 @@ pub enum CodecError { ReservedCommunicationType(u16), #[error("Invalid encoding")] InvalidEncoding, - #[error("Too many entries to encode")] - TooManyEntries, #[error("Crypto failed: {0}")] CryptoFailed(String), } @@ -71,9 +69,6 @@ pub enum CommunicationError { #[error("ParseCommunicationValue error")] ParseCommunicationValue, - #[error("Encode error")] - Encode, - #[error("Parse Certificate error")] CertificateParseFailed, @@ -144,9 +139,6 @@ pub enum CommunicationError { #[error("ParseCommunicationValue error")] ParseCommunicationValue, - #[error("Encode error")] - Encode, - #[error("Parse Certificate error")] CertificateParseFailed, @@ -190,7 +182,6 @@ impl PartialEq for CommunicationError { (Self::ConnectionLost, Self::ConnectionLost) => true, (Self::Quinn(_), Self::Quinn(_)) => true, (Self::ParseCommunicationValue, Self::ParseCommunicationValue) => true, - (Self::Encode, Self::Encode) => true, (Self::CertificateParseFailed, Self::CertificateParseFailed) => true, (Self::CertificateLoadFailed, Self::CertificateLoadFailed) => true, (Self::ParseError(a), Self::ParseError(b)) => a == b, @@ -222,7 +213,6 @@ impl PartialEq for CommunicationError { (Self::ClosedByPeer, Self::ClosedByPeer) => true, (Self::ConnectionLost, Self::ConnectionLost) => true, (Self::ParseCommunicationValue, Self::ParseCommunicationValue) => true, - (Self::Encode, Self::Encode) => true, (Self::CertificateParseFailed, Self::CertificateParseFailed) => true, (Self::CertificateLoadFailed, Self::CertificateLoadFailed) => true, (Self::ParseError(a), Self::ParseError(b)) => a == b, @@ -251,18 +241,9 @@ mod communication_error_tests { #[test] fn test_communication_error_display() { - assert_eq!( - format!("{}", CommunicationError::UseAfterClosed), - "Use after Closed" - ); - assert_eq!( - format!("{}", CommunicationError::StreamClosed), - "Stream Closed" - ); - assert_eq!( - format!("{}", CommunicationError::StreamError), - "Stream Error" - ); + assert_eq!(format!("{}", CommunicationError::UseAfterClosed), "Use after Closed"); + assert_eq!(format!("{}", CommunicationError::StreamClosed), "Stream Closed"); + assert_eq!(format!("{}", CommunicationError::StreamError), "Stream Error"); } #[test] diff --git a/crypto/src/aead.rs b/crypto/src/aead.rs index 3729ebd..4e65064 100644 --- a/crypto/src/aead.rs +++ b/crypto/src/aead.rs @@ -33,9 +33,9 @@ impl ChaCha20Poly1305 { #[cfg(feature = "chacha20poly1305")] impl AeadEncrypt for ChaCha20Poly1305 { fn encrypt(&self, plaintext: &[u8], aad: &[u8]) -> Result, CryptoError> { + use chacha20poly1305::aead::{Aead, KeyInit, Payload}; use chacha20poly1305::XChaCha20Poly1305; use chacha20poly1305::XNonce; - use chacha20poly1305::aead::{Aead, KeyInit, Payload}; let key = chacha20poly1305::Key::from_slice(&self.key); let cipher = XChaCha20Poly1305::new(key); @@ -63,9 +63,9 @@ impl AeadEncrypt for ChaCha20Poly1305 { #[cfg(feature = "chacha20poly1305")] impl AeadDecrypt for ChaCha20Poly1305 { fn decrypt(&self, ciphertext: &[u8], aad: &[u8]) -> Result, CryptoError> { + use chacha20poly1305::aead::{Aead, KeyInit, Payload}; use chacha20poly1305::XChaCha20Poly1305; use chacha20poly1305::XNonce; - use chacha20poly1305::aead::{Aead, KeyInit, Payload}; if ciphertext.len() < 24 { return Err(CryptoError::InvalidNonceLength); @@ -76,7 +76,10 @@ impl AeadDecrypt for ChaCha20Poly1305 { let cipher = XChaCha20Poly1305::new(key); let nonce_ref = XNonce::from_slice(nonce); - let payload = Payload { msg: ct, aad }; + let payload = Payload { + msg: ct, + aad, + }; cipher .decrypt(nonce_ref, payload) @@ -106,9 +109,9 @@ impl Aes256Gcm { #[cfg(feature = "aes-gcm")] impl AeadEncrypt for Aes256Gcm { fn encrypt(&self, plaintext: &[u8], aad: &[u8]) -> Result, CryptoError> { + use aes_gcm::aead::{Aead, KeyInit, Payload}; use aes_gcm::Aes256Gcm as AesGcmInner; use aes_gcm::Nonce; - use aes_gcm::aead::{Aead, KeyInit, Payload}; let key = aes_gcm::Key::::from_slice(&self.key); let cipher = AesGcmInner::new(key); @@ -136,9 +139,9 @@ impl AeadEncrypt for Aes256Gcm { #[cfg(feature = "aes-gcm")] impl AeadDecrypt for Aes256Gcm { fn decrypt(&self, ciphertext: &[u8], aad: &[u8]) -> Result, CryptoError> { + use aes_gcm::aead::{Aead, KeyInit, Payload}; use aes_gcm::Aes256Gcm as AesGcmInner; use aes_gcm::Nonce; - use aes_gcm::aead::{Aead, KeyInit, Payload}; if ciphertext.len() < 12 { return Err(CryptoError::InvalidNonceLength); @@ -149,7 +152,10 @@ impl AeadDecrypt for Aes256Gcm { let cipher = AesGcmInner::new(key); let nonce_ref = Nonce::from_slice(nonce); - let payload = Payload { msg: ct, aad }; + let payload = Payload { + msg: ct, + aad, + }; cipher .decrypt(nonce_ref, payload) diff --git a/crypto/src/enc.rs b/crypto/src/enc.rs deleted file mode 100644 index 3b7a44b..0000000 --- a/crypto/src/enc.rs +++ /dev/null @@ -1,246 +0,0 @@ -#[cfg(all(feature = "mlkem-tls", feature = "hkdf"))] -use crate::error::CryptoError; - -#[cfg(all(feature = "mlkem-tls", feature = "hkdf"))] -use crate::kdf::derive_encryption_key; -#[cfg(all(feature = "mlkem-tls", feature = "hkdf"))] -use crate::kem::HybridKem; -#[cfg(all(feature = "mlkem-tls", feature = "hkdf"))] -use crate::keypair::{Keyring, PublicKeyBundle}; - -/* - * Algorithm selector for encrypted containers. - * - * Mirrors `SigAlgorithm` for signatures: a single marking byte identifies the - * key-encapsulation mechanism and the AEAD used to seal a container. The byte - * is stored as the first byte of every encrypted blob so the decryptor can pick - * the matching algorithm (and the matching keypair from a `Keyring`) without - * any out-of-band agreement. - * - * All variants currently use ML-KEM (X25519MlKem768) for key encapsulation and - * differ only in the AEAD. AES-256-GCM variants require the `aes-gcm` feature - * (enabled via the crate's `full` feature); sealing/opening with a variant whose - * AEAD feature is not compiled in returns an error. - */ -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum EncryptionType { - /// ML-KEM (X25519MlKem768) key encapsulation with XChaCha20-Poly1305 AEAD. - MlKemChaCha20Poly1305, - /// ML-KEM (X25519MlKem768) key encapsulation with AES-256-GCM AEAD. - MlKemAes256Gcm, -} - -impl EncryptionType { - pub const ML_KEM_CHACHA20POLY1305: u8 = 0x01; - pub const ML_KEM_AES256_GCM: u8 = 0x02; - - /// The marking byte written at the front of an encrypted blob. - pub const fn to_byte(self) -> u8 { - match self { - Self::MlKemChaCha20Poly1305 => Self::ML_KEM_CHACHA20POLY1305, - Self::MlKemAes256Gcm => Self::ML_KEM_AES256_GCM, - } - } - - /// Recover an `EncryptionType` from its marking byte, or `None` if unknown. - pub const fn from_byte(b: u8) -> Option { - match b { - Self::ML_KEM_CHACHA20POLY1305 => Some(Self::MlKemChaCha20Poly1305), - Self::ML_KEM_AES256_GCM => Some(Self::MlKemAes256Gcm), - _ => None, - } - } -} - -/* - * Seal `plaintext` with a 32-byte AEAD key chosen by `enc_type`. - * - * Returns `EncryptionFailed` when the selected AEAD's feature is not compiled in. - */ -#[cfg(all(feature = "mlkem-tls", feature = "hkdf"))] -#[allow(unused_variables)] -fn aead_seal( - enc_type: EncryptionType, - key: [u8; 32], - plaintext: &[u8], - aad: &[u8], -) -> Result, CryptoError> { - #[allow(unused_imports)] - use crate::aead::AeadEncrypt; - match enc_type { - #[cfg(feature = "chacha20poly1305")] - EncryptionType::MlKemChaCha20Poly1305 => { - crate::aead::ChaCha20Poly1305::new(key).encrypt(plaintext, aad) - } - #[cfg(feature = "aes-gcm")] - EncryptionType::MlKemAes256Gcm => crate::aead::Aes256Gcm::new(key).encrypt(plaintext, aad), - #[allow(unreachable_patterns)] - _ => Err(CryptoError::EncryptionFailed), - } -} - -/* - * Open `ciphertext` with a 32-byte AEAD key chosen by `enc_type`. - * - * Returns `DecryptionFailed` when the selected AEAD's feature is not compiled in. - */ -#[cfg(all(feature = "mlkem-tls", feature = "hkdf"))] -#[allow(unused_variables)] -fn aead_open( - enc_type: EncryptionType, - key: [u8; 32], - ciphertext: &[u8], - aad: &[u8], -) -> Result, CryptoError> { - #[allow(unused_imports)] - use crate::aead::AeadDecrypt; - match enc_type { - #[cfg(feature = "chacha20poly1305")] - EncryptionType::MlKemChaCha20Poly1305 => { - crate::aead::ChaCha20Poly1305::new(key).decrypt(ciphertext, aad) - } - #[cfg(feature = "aes-gcm")] - EncryptionType::MlKemAes256Gcm => crate::aead::Aes256Gcm::new(key).decrypt(ciphertext, aad), - #[allow(unreachable_patterns)] - _ => Err(CryptoError::DecryptionFailed), - } -} - -#[cfg(all(feature = "mlkem-tls", feature = "hkdf"))] -const ENC_KDF_SALT: &[u8] = b"mtp-container-enc"; -#[cfg(all(feature = "mlkem-tls", feature = "hkdf"))] -const ENC_KDF_CONTEXT: &[u8] = b"single-recipient"; - -/* - * Encrypt `plaintext` for a single recipient, selecting the algorithm with - * `enc_type` and the recipient's KEM public key from `recipient`. - * - * The returned, self-describing blob is laid out as: - * [1 byte EncryptionType] [2 bytes u16 kem_ct_len] [kem_ciphertext] [aead_payload] - * where `aead_payload` is the AEAD output (nonce + ciphertext + tag). The AEAD - * key is derived from the KEM shared secret via HKDF, so no separate content key - * is transmitted. - * - * Requires the `mlkem-tls` and `hkdf` features, plus the AEAD feature backing - * `enc_type`. - */ -#[cfg(all(feature = "mlkem-tls", feature = "hkdf"))] -pub fn encrypt_for( - enc_type: EncryptionType, - recipient: &PublicKeyBundle, - plaintext: &[u8], - aad: &[u8], -) -> Result, CryptoError> { - let enc = HybridKem::encapsulate(&recipient.kem_public_key)?; - let key = derive_encryption_key(&enc.shared_secret, ENC_KDF_SALT, ENC_KDF_CONTEXT)?; - let aead_payload = aead_seal(enc_type, key, plaintext, aad)?; - - let kem_ct = enc.ciphertext; - let mut out = Vec::with_capacity(1 + 2 + kem_ct.len() + aead_payload.len()); - out.push(enc_type.to_byte()); - out.extend_from_slice(&(kem_ct.len() as u16).to_be_bytes()); - out.extend_from_slice(&kem_ct); - out.extend_from_slice(&aead_payload); - Ok(out) -} - -/* - * Decrypt a blob produced by [`encrypt_for`] using `keyring`. - * - * The leading byte selects the `EncryptionType` (and thus which keypair to use - * from the keyring); for the current ML-KEM variants that is `kem_secret_key`. - * Returns `DecryptionFailed` on any malformed input or authentication failure. - * - * Requires the `mlkem-tls` and `hkdf` features, plus the AEAD feature backing - * the blob's algorithm. - */ -#[cfg(all(feature = "mlkem-tls", feature = "hkdf"))] -pub fn decrypt_with(blob: &[u8], keyring: &Keyring, aad: &[u8]) -> Result, CryptoError> { - if blob.len() < 3 { - return Err(CryptoError::DecryptionFailed); - } - let enc_type = EncryptionType::from_byte(blob[0]).ok_or(CryptoError::DecryptionFailed)?; - let kem_ct_len = u16::from_be_bytes([blob[1], blob[2]]) as usize; - let kem_end = 3usize - .checked_add(kem_ct_len) - .ok_or(CryptoError::DecryptionFailed)?; - let kem_ct = blob.get(3..kem_end).ok_or(CryptoError::DecryptionFailed)?; - let aead_payload = blob.get(kem_end..).ok_or(CryptoError::DecryptionFailed)?; - - let shared_secret = HybridKem::decapsulate(&keyring.kem_secret_key, kem_ct)?; - let key = derive_encryption_key(&shared_secret, ENC_KDF_SALT, ENC_KDF_CONTEXT)?; - aead_open(enc_type, key, aead_payload, aad) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn encryption_type_byte_roundtrip() { - for t in [ - EncryptionType::MlKemChaCha20Poly1305, - EncryptionType::MlKemAes256Gcm, - ] { - assert_eq!(EncryptionType::from_byte(t.to_byte()), Some(t)); - } - assert_eq!(EncryptionType::from_byte(0x00), None); - assert_eq!(EncryptionType::from_byte(0xFF), None); - } - - #[cfg(all(feature = "mlkem-tls", feature = "hkdf", feature = "chacha20poly1305"))] - #[test] - fn encrypt_for_roundtrip() { - let kr = Keyring::generate(); - let blob = encrypt_for( - EncryptionType::MlKemChaCha20Poly1305, - &kr.public_key_bundle(), - b"secret payload", - b"aad", - ) - .unwrap(); - assert_eq!(blob[0], EncryptionType::ML_KEM_CHACHA20POLY1305); - - let pt = decrypt_with(&blob, &kr, b"aad").unwrap(); - assert_eq!(pt, b"secret payload"); - } - - #[cfg(all(feature = "mlkem-tls", feature = "hkdf", feature = "chacha20poly1305"))] - #[test] - fn decrypt_with_wrong_keyring_fails() { - let kr = Keyring::generate(); - let other = Keyring::generate(); - let blob = encrypt_for( - EncryptionType::MlKemChaCha20Poly1305, - &kr.public_key_bundle(), - b"secret", - b"aad", - ) - .unwrap(); - assert!(decrypt_with(&blob, &other, b"aad").is_err()); - } - - #[cfg(all(feature = "mlkem-tls", feature = "hkdf", feature = "chacha20poly1305"))] - #[test] - fn decrypt_with_wrong_aad_fails() { - let kr = Keyring::generate(); - let blob = encrypt_for( - EncryptionType::MlKemChaCha20Poly1305, - &kr.public_key_bundle(), - b"secret", - b"right", - ) - .unwrap(); - assert!(decrypt_with(&blob, &kr, b"wrong").is_err()); - } - - #[cfg(all(feature = "mlkem-tls", feature = "hkdf", feature = "chacha20poly1305"))] - #[test] - fn decrypt_with_malformed_fails() { - let kr = Keyring::generate(); - assert!(decrypt_with(b"", &kr, b"").is_err()); - assert!(decrypt_with(&[0x01, 0x00], &kr, b"").is_err()); - // Unknown algorithm byte. - assert!(decrypt_with(&[0x7F, 0x00, 0x00], &kr, b"").is_err()); - } -} diff --git a/crypto/src/hash.rs b/crypto/src/hash.rs index 62602f1..39765b3 100644 --- a/crypto/src/hash.rs +++ b/crypto/src/hash.rs @@ -13,12 +13,6 @@ pub fn sha256_double(data: &[u8]) -> [u8; 32] { pub struct Sha256Hasher(sha2::Sha256); -impl Default for Sha256Hasher { - fn default() -> Self { - Self::new() - } -} - impl Sha256Hasher { pub fn new() -> Self { Self(sha2::Sha256::new()) diff --git a/crypto/src/helper.rs b/crypto/src/helper.rs index fe68178..beb75d7 100644 --- a/crypto/src/helper.rs +++ b/crypto/src/helper.rs @@ -196,3 +196,5 @@ pub fn decrypt_multi( } Err(CryptoError::DecryptionFailed) } + + diff --git a/crypto/src/kdf.rs b/crypto/src/kdf.rs index 52baf4d..113880c 100644 --- a/crypto/src/kdf.rs +++ b/crypto/src/kdf.rs @@ -16,12 +16,10 @@ pub fn hkdf_expand( } pub fn hkdf_extract(ikm: &[u8], salt: &[u8]) -> [u8; 32] { - // Return the pseudo-random key (PRK) produced by HKDF-Extract directly. - // Extract cannot fail, so this avoids the panicking expand step entirely. - let (prk, _) = Hkdf::::extract(Some(salt), ikm); - let mut out = [0u8; 32]; - out.copy_from_slice(&prk); - out + let (_, hk) = Hkdf::::extract(Some(salt), ikm); + let mut okm = [0u8; 32]; + hk.expand(&[], &mut okm).expect("hkdf expand failed"); + okm } pub fn derive_encryption_key( diff --git a/crypto/src/kem.rs b/crypto/src/kem.rs index 87ca38a..41c743c 100644 --- a/crypto/src/kem.rs +++ b/crypto/src/kem.rs @@ -12,7 +12,8 @@ pub struct HybridKem; #[cfg(feature = "mlkem-tls")] impl HybridKem { pub fn generate_keypair() -> (KemPrivateKey, KemPublicKey) { - let (ek, dk) = mlkem_tls::X25519MlKem768::keygen(&mut rand_core::OsRng); + let (ek, dk) = + mlkem_tls::X25519MlKem768::keygen(&mut rand_core::OsRng); ( KemPrivateKey::new(dk.as_bytes().to_vec()), KemPublicKey::new(ek.as_bytes().to_vec()), @@ -22,7 +23,8 @@ impl HybridKem { pub fn encapsulate(recipient_pk: &KemPublicKey) -> Result { let ek = mlkem_tls::EncapsKey768::try_from(recipient_pk.as_bytes()) .map_err(|_| CryptoError::KemEncapsulationFailed)?; - let (ct, ss) = mlkem_tls::X25519MlKem768::encapsulate(&ek, &mut rand_core::OsRng); + let (ct, ss) = + mlkem_tls::X25519MlKem768::encapsulate(&ek, &mut rand_core::OsRng); Ok(Encapsulated { ciphertext: ct.as_bytes().to_vec(), shared_secret: ss.as_bytes().to_vec(), diff --git a/crypto/src/lib.rs b/crypto/src/lib.rs index 1f91a75..d132b63 100644 --- a/crypto/src/lib.rs +++ b/crypto/src/lib.rs @@ -17,8 +17,6 @@ pub use sign::SigAlgorithm; #[cfg(feature = "mlkem-tls")] pub mod kem; -pub mod enc; - pub mod helper; pub use aead::{AeadCipher, AeadDecrypt, AeadEncrypt}; @@ -36,16 +34,16 @@ pub use aead::ChaCha20Poly1305; pub use aead::Aes256Gcm; #[cfg(feature = "ed25519-dalek")] -pub use sign::{Ed25519Signer, SignatureScheme, verify_ed25519}; +pub use sign::{verify_ed25519, Ed25519Signer, SignatureScheme}; #[cfg(feature = "ml-dsa")] -pub use sign::{MlDsaSigner, verify_ml_dsa}; +pub use sign::{verify_ml_dsa, MlDsaSigner}; #[cfg(all(feature = "ed25519-dalek", feature = "ml-dsa"))] -pub use sign::{DualSignature, sign_dual}; +pub use sign::{sign_dual, DualSignature}; #[cfg(feature = "sha2")] -pub use hash::{Sha256Hasher, sha256, sha256_double}; +pub use hash::{sha256, sha256_double, Sha256Hasher}; #[cfg(feature = "hkdf")] pub use kdf::{derive_encryption_key, hkdf_expand, hkdf_extract}; @@ -53,13 +51,8 @@ pub use kdf::{derive_encryption_key, hkdf_expand, hkdf_extract}; #[cfg(feature = "mlkem-tls")] pub use kem::{Encapsulated, HybridKem}; -pub use enc::EncryptionType; - -#[cfg(all(feature = "mlkem-tls", feature = "hkdf"))] -pub use enc::{decrypt_with, encrypt_for}; - #[cfg(all(feature = "mlkem-tls", feature = "chacha20poly1305", feature = "hkdf"))] -pub use helper::{MultiEncryptedMessage, RecipientEntry, decrypt_multi, encrypt_multi}; +pub use helper::{decrypt_multi, encrypt_multi, MultiEncryptedMessage, RecipientEntry}; /* ================================ TESTS ================================ */ #[cfg(test)] @@ -147,8 +140,13 @@ mod tests { let (ed_signer, _, _) = Ed25519Signer::generate(); let (ml_signer, _, _) = MlDsaSigner::generate(); - let dual = sign_dual(ed_signer.signing_key(), ml_signer.signing_key(), b"msg").unwrap(); - dual.verify(ed_signer.verifying_key(), ml_signer.verifying_key(), b"msg") + let dual = sign_dual(ed_signer.signing_key(), ml_signer.signing_key(), b"msg"); + dual + .verify( + ed_signer.verifying_key(), + ml_signer.verifying_key(), + b"msg", + ) .unwrap(); } @@ -159,15 +157,10 @@ mod tests { let (ed_signer, _, _) = Ed25519Signer::generate(); let (ml_signer, _, _) = MlDsaSigner::generate(); - let dual = sign_dual(ed_signer.signing_key(), ml_signer.signing_key(), b"msg").unwrap(); - assert!( - dual.verify( - ed_signer.verifying_key(), - ml_signer.verifying_key(), - b"wrong" - ) - .is_err() - ); + let dual = sign_dual(ed_signer.signing_key(), ml_signer.signing_key(), b"msg"); + assert!(dual + .verify(ed_signer.verifying_key(), ml_signer.verifying_key(), b"wrong") + .is_err()); } #[cfg(feature = "hkdf")] @@ -255,18 +248,9 @@ mod tests { let kr = Keyring::generate(); let bytes = kr.to_bytes(); let loaded = Keyring::from_bytes(&bytes).unwrap(); - assert_eq!( - kr.kem_public_key.as_bytes(), - loaded.kem_public_key.as_bytes() - ); - assert_eq!( - kr.sig_pq_public_key.as_bytes(), - loaded.sig_pq_public_key.as_bytes() - ); - assert_eq!( - kr.sig_cl_public_key.as_bytes(), - loaded.sig_cl_public_key.as_bytes() - ); + assert_eq!(kr.kem_public_key.as_bytes(), loaded.kem_public_key.as_bytes()); + assert_eq!(kr.sig_pq_public_key.as_bytes(), loaded.sig_pq_public_key.as_bytes()); + assert_eq!(kr.sig_cl_public_key.as_bytes(), loaded.sig_cl_public_key.as_bytes()); } #[cfg(all(feature = "mlkem-tls", feature = "ml-dsa", feature = "ed25519-dalek"))] @@ -276,10 +260,7 @@ mod tests { let bundle = kr.public_key_bundle(); let bytes = bundle.as_bytes(); let loaded = PublicKeyBundle::from_bytes(&bytes).unwrap(); - assert_eq!( - bundle.kem_public_key.as_bytes(), - loaded.kem_public_key.as_bytes() - ); + assert_eq!(bundle.kem_public_key.as_bytes(), loaded.kem_public_key.as_bytes()); assert_eq!( bundle.sig_pq_public_key.as_bytes(), loaded.sig_pq_public_key.as_bytes() @@ -302,8 +283,8 @@ mod tests { #[cfg(all(feature = "mlkem-tls", feature = "chacha20poly1305", feature = "hkdf"))] #[test] fn encrypt_multi_roundtrip() { - use crate::helper::{decrypt_multi, encrypt_multi}; use crate::keypair::Keyring; + use crate::helper::{encrypt_multi, decrypt_multi}; let kr = Keyring::generate(); let entities = vec![kr.public_key_bundle()]; diff --git a/crypto/src/sign.rs b/crypto/src/sign.rs index 6a1d836..c39bb55 100644 --- a/crypto/src/sign.rs +++ b/crypto/src/sign.rs @@ -172,9 +172,7 @@ impl MlDsaSigner { impl SignatureScheme for MlDsaSigner { fn sign(&self, msg: &[u8]) -> Result, CryptoError> { use ml_dsa::Signer; - let signature = self - .secret - .try_sign(msg) + let signature = self.secret.try_sign(msg) .map_err(|_| CryptoError::SigningFailed)?; Ok(signature.encode().to_vec()) } @@ -183,8 +181,7 @@ impl SignatureScheme for MlDsaSigner { use ml_dsa::Verifier; let sig = ml_dsa::Signature::::try_from(signature) .map_err(|_| CryptoError::InvalidSignature)?; - self.public - .verify(msg, &sig) + self.public.verify(msg, &sig) .map_err(|_| CryptoError::VerificationFailed) } } @@ -221,20 +218,19 @@ pub fn sign_dual( ed25519_sk: &ed25519_dalek::SigningKey, mldsa_sk: &ml_dsa::SigningKey, message: &[u8], -) -> Result { +) -> DualSignature { let ed25519 = { use ed25519_dalek::Signer; ed25519_sk.sign(message).to_bytes().to_vec() }; let mldsa = { use ml_dsa::Signer; - mldsa_sk - .try_sign(message) - .map_err(|_| CryptoError::SigningFailed)? + mldsa_sk.try_sign(message) + .expect("ML-DSA signing failed") .encode() .to_vec() }; - Ok(DualSignature { ed25519, mldsa }) + DualSignature { ed25519, mldsa } } impl DualSignature { diff --git a/deny.toml b/deny.toml deleted file mode 100644 index 41c6bb9..0000000 --- a/deny.toml +++ /dev/null @@ -1,32 +0,0 @@ -# cargo-deny configuration. See https://embarkstudios.github.io/cargo-deny/ -# Run locally with: cargo deny check - -[advisories] -# Fail on any security advisory affecting the dependency tree. -yanked = "deny" -ignore = [] - -[bans] -# Flag multiple versions of the same crate so duplicate trees are visible. -multiple-versions = "warn" -wildcards = "deny" - -[licenses] -# Allowlist of licenses acceptable for this project's dependencies. -allow = [ - "MIT", - "Apache-2.0", - "Apache-2.0 WITH LLVM-exception", - "BSD-2-Clause", - "BSD-3-Clause", - "ISC", - "Unicode-3.0", - "Zlib", - "MPL-2.0", -] -confidence-threshold = 0.8 - -[sources] -unknown-registry = "deny" -unknown-git = "deny" -allow-registry = ["https://github.com/rust-lang/crates.io-index"] diff --git a/example-usage/.gitignore b/example-usage/.gitignore index 894dd06..006bccb 100644 --- a/example-usage/.gitignore +++ b/example-usage/.gitignore @@ -3,9 +3,5 @@ host_keys.json host_sig_pk.bin host_sig_pq_pk.bin host_enc_kem_pk.bin -host_public_key_bundle.hex clients.json web-client/node_modules -dev-cert/ -web-client/public/host_public_key_bundle.hex -web-client/public/mtp_dev_cert_hash.txt diff --git a/example-usage/Cargo.lock b/example-usage/Cargo.lock deleted file mode 100644 index 48f612f..0000000 --- a/example-usage/Cargo.lock +++ /dev/null @@ -1,2361 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "aead" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" -dependencies = [ - "crypto-common 0.1.7", - "generic-array", -] - -[[package]] -name = "asn1-rs" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f43a50ac4fdca5df8e885c21b835997f0a1cdee65494a6847694a98652d9d8" -dependencies = [ - "asn1-rs-derive", - "asn1-rs-impl", - "displaydoc", - "nom", - "num-traits", - "rusticata-macros", - "thiserror", - "time", -] - -[[package]] -name = "asn1-rs-derive" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "asn1-rs-impl" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "autocfg" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" - -[[package]] -name = "aws-lc-rs" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ec2f1fc3ec205783a5da9a7e6c1509cc69dedf09a1949e412c1e18469326d00" -dependencies = [ - "aws-lc-sys", - "untrusted 0.7.1", - "zeroize", -] - -[[package]] -name = "aws-lc-sys" -version = "0.41.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a2f9779ce85b93ab6170dd940ad0169b5766ff848247aff13bb788b832fe3f4" -dependencies = [ - "cc", - "cmake", - "dunce", - "fs_extra", -] - -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - -[[package]] -name = "base64ct" -version = "1.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" - -[[package]] -name = "bit-vec" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71798fca2c1fe1086445a7258a4bc81e6e49dcd24c8d0dd9a1e57395b603f51" -dependencies = [ - "serde", -] - -[[package]] -name = "bitflags" -version = "2.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "block-buffer" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" -dependencies = [ - "hybrid-array", -] - -[[package]] -name = "bumpalo" -version = "3.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593" - -[[package]] -name = "cc" -version = "1.2.65" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96" -dependencies = [ - "find-msvc-tools", - "jobserver", - "libc", - "shlex", -] - -[[package]] -name = "cfg-if" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" - -[[package]] -name = "cfg_aliases" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" - -[[package]] -name = "chacha20" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures 0.2.17", -] - -[[package]] -name = "chacha20poly1305" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" -dependencies = [ - "aead", - "chacha20", - "cipher", - "poly1305", - "zeroize", -] - -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common 0.1.7", - "inout", - "zeroize", -] - -[[package]] -name = "client" -version = "0.1.0" -dependencies = [ - "hex", - "mtp", - "serde_json", - "tokio", -] - -[[package]] -name = "cmake" -version = "0.1.58" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" -dependencies = [ - "cc", -] - -[[package]] -name = "cmov" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a" - -[[package]] -name = "const-oid" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" - -[[package]] -name = "const-oid" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" - -[[package]] -name = "core-foundation" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "cpufeatures" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] - -[[package]] -name = "cpufeatures" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" -dependencies = [ - "libc", -] - -[[package]] -name = "crypto-common" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" -dependencies = [ - "generic-array", - "rand_core 0.6.4", - "typenum", -] - -[[package]] -name = "crypto-common" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" -dependencies = [ - "getrandom 0.4.3", - "hybrid-array", - "rand_core 0.10.1", -] - -[[package]] -name = "ctutils" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" -dependencies = [ - "cmov", -] - -[[package]] -name = "curve25519-dalek" -version = "4.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" -dependencies = [ - "cfg-if", - "cpufeatures 0.2.17", - "curve25519-dalek-derive", - "digest 0.10.7", - "fiat-crypto", - "rustc_version", - "subtle", - "zeroize", -] - -[[package]] -name = "curve25519-dalek-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "data-encoding" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8" - -[[package]] -name = "der" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" -dependencies = [ - "const-oid 0.9.6", - "pem-rfc7468", - "zeroize", -] - -[[package]] -name = "der" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71fd89660b2dc699704064e59e9dba0147b903e85319429e131620d022be411b" -dependencies = [ - "const-oid 0.10.2", - "zeroize", -] - -[[package]] -name = "der-parser" -version = "10.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07da5016415d5a3c4dd39b11ed26f915f52fc4e0dc197d87908bc916e51bc1a6" -dependencies = [ - "asn1-rs", - "displaydoc", - "nom", - "num-bigint", - "num-traits", - "rusticata-macros", -] - -[[package]] -name = "deranged" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer 0.10.4", - "crypto-common 0.1.7", -] - -[[package]] -name = "digest" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" -dependencies = [ - "block-buffer 0.12.1", - "const-oid 0.10.2", - "crypto-common 0.2.2", - "ctutils", -] - -[[package]] -name = "displaydoc" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "dunce" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" - -[[package]] -name = "ed25519" -version = "2.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" -dependencies = [ - "pkcs8 0.10.2", - "signature 2.2.0", -] - -[[package]] -name = "ed25519-dalek" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" -dependencies = [ - "curve25519-dalek", - "ed25519", - "serde", - "sha2 0.10.9", - "subtle", - "zeroize", -] - -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "errno" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" -dependencies = [ - "libc", - "windows-sys 0.61.2", -] - -[[package]] -name = "fiat-crypto" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" - -[[package]] -name = "find-msvc-tools" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" - -[[package]] -name = "form_urlencoded" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "fs_extra" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" - -[[package]] -name = "futures-core" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" - -[[package]] -name = "futures-task" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" - -[[package]] -name = "futures-util" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" -dependencies = [ - "futures-core", - "futures-task", - "pin-project-lite", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi", - "wasm-bindgen", -] - -[[package]] -name = "getrandom" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "r-efi 5.3.0", - "wasip2", - "wasm-bindgen", -] - -[[package]] -name = "getrandom" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" -dependencies = [ - "cfg-if", - "libc", - "r-efi 6.0.0", - "rand_core 0.10.1", -] - -[[package]] -name = "hashbrown" -version = "0.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hkdf" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4aaa26c720c68b866f2c96ef5c1264b3e6f473fe5d4ce61cd44bbe913e553018" -dependencies = [ - "hmac", -] - -[[package]] -name = "hmac" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" -dependencies = [ - "digest 0.11.3", -] - -[[package]] -name = "httlib-huffman" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a9fcbcc408c5526c3ab80d534e5c86e7967c1fb7aa0a8c76abd1edc27deb877" - -[[package]] -name = "hybrid-array" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da" -dependencies = [ - "ctutils", - "typenum", -] - -[[package]] -name = "icu_collections" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" -dependencies = [ - "displaydoc", - "potential_utf", - "utf8_iter", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locale_core" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_normalizer" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" -dependencies = [ - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" - -[[package]] -name = "icu_properties" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" -dependencies = [ - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "zerotrie", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" - -[[package]] -name = "icu_provider" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" -dependencies = [ - "displaydoc", - "icu_locale_core", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", -] - -[[package]] -name = "idna" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - -[[package]] -name = "indexmap" -version = "2.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" -dependencies = [ - "equivalent", - "hashbrown", -] - -[[package]] -name = "inout" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" -dependencies = [ - "generic-array", -] - -[[package]] -name = "itoa" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" - -[[package]] -name = "jobserver" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" -dependencies = [ - "getrandom 0.3.4", - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.102" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31" -dependencies = [ - "cfg-if", - "futures-util", - "wasm-bindgen", -] - -[[package]] -name = "keccak" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" -dependencies = [ - "cpufeatures 0.2.17", -] - -[[package]] -name = "keccak" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e24a010dd405bd7ed803e5253182815b41bf2e6a80cc3bfc066658e03a198aa" -dependencies = [ - "cfg-if", - "cpufeatures 0.3.0", -] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "libc" -version = "0.2.186" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" - -[[package]] -name = "litemap" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" - -[[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.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" - -[[package]] -name = "lru-slab" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" - -[[package]] -name = "memchr" -version = "2.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "mio" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" -dependencies = [ - "libc", - "wasi", - "windows-sys 0.61.2", -] - -[[package]] -name = "ml-dsa" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add6b9d92e496f16f4526d68ff29da1483aba4b119baeab8bed3b9e3544a6f3d" -dependencies = [ - "const-oid 0.10.2", - "crypto-common 0.2.2", - "ctutils", - "hybrid-array", - "module-lattice", - "pkcs8 0.11.0", - "shake", - "signature 3.0.0", -] - -[[package]] -name = "mlkem-rs" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b0965b8b081668ff0398dc5e9dc3f2ebb9e833393f4ab5b9f725ddce11acef8" -dependencies = [ - "rand_core 0.6.4", - "serde", - "sha3", - "subtle", - "zeroize", -] - -[[package]] -name = "mlkem-tls" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77b205d031298adf904d88efd6a57862d8650a4ab754aade19a9b5e87040bf4e" -dependencies = [ - "mlkem-rs", - "rand_core 0.6.4", - "subtle", - "x25519-dalek", - "zeroize", -] - -[[package]] -name = "module-lattice" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c61b87c9683ab7cb1c6871d261ad5479b6b10ceb52c4352aaca3b5d35a8febe" -dependencies = [ - "ctutils", - "hybrid-array", - "num-traits", -] - -[[package]] -name = "mtp" -version = "0.1.0" -dependencies = [ - "mtp-client", - "mtp-codec", - "mtp-common", - "mtp-crypto", - "mtp-host", - "mtp-transport", - "mtp-type-map", -] - -[[package]] -name = "mtp-client" -version = "0.1.0" -dependencies = [ - "mtp-codec", - "mtp-common", - "mtp-crypto", - "mtp-transport", - "rand 0.8.6", - "tokio", -] - -[[package]] -name = "mtp-codec" -version = "0.1.0" -dependencies = [ - "base64", - "byteorder", - "mtp-common", - "mtp-crypto", - "mtp-type-map", - "rand 0.8.6", -] - -[[package]] -name = "mtp-common" -version = "0.1.0" -dependencies = [ - "quinn", - "rustls", - "thiserror", - "wtransport", -] - -[[package]] -name = "mtp-crypto" -version = "0.1.0" -dependencies = [ - "chacha20poly1305", - "ed25519-dalek", - "getrandom 0.4.3", - "hkdf", - "ml-dsa", - "mlkem-tls", - "rand_core 0.6.4", - "serde", - "sha2 0.11.0", - "zeroize", -] - -[[package]] -name = "mtp-host" -version = "0.1.0" -dependencies = [ - "mtp-codec", - "mtp-common", - "mtp-crypto", - "mtp-transport", - "rand 0.8.6", - "tokio", -] - -[[package]] -name = "mtp-transport" -version = "0.1.0" -dependencies = [ - "log", - "mtp-codec", - "mtp-common", - "quinn", - "rustls", - "rustls-native-certs", - "thiserror", - "tokio", - "wtransport", -] - -[[package]] -name = "mtp-type-map" -version = "0.1.0" -dependencies = [ - "serde", - "serde_yaml", -] - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "num-bigint" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" -dependencies = [ - "num-integer", - "num-traits", -] - -[[package]] -name = "num-conv" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "octets" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8311fa8ab7a57759b4ff1f851a3048d9ef0effaa0130726426b742d26d8a88e7" - -[[package]] -name = "oid-registry" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f40cff3dde1b6087cc5d5f5d4d65712f34016a03ed60e9c08dcc392736b5b7" -dependencies = [ - "asn1-rs", -] - -[[package]] -name = "once_cell" -version = "1.21.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" - -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - -[[package]] -name = "openssl-probe" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" - -[[package]] -name = "parking_lot" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-link", -] - -[[package]] -name = "pem" -version = "3.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be" -dependencies = [ - "base64", - "serde_core", -] - -[[package]] -name = "pem-rfc7468" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" -dependencies = [ - "base64ct", -] - -[[package]] -name = "percent-encoding" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" - -[[package]] -name = "pin-project-lite" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" - -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der 0.7.10", - "spki 0.7.3", -] - -[[package]] -name = "pkcs8" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "451913da69c775a56034ea8d9003d27ee8948e12443eae7c038ba100a4f21cb7" -dependencies = [ - "der 0.8.0", - "spki 0.8.0", -] - -[[package]] -name = "poly1305" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" -dependencies = [ - "cpufeatures 0.2.17", - "opaque-debug", - "universal-hash", -] - -[[package]] -name = "potential_utf" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" -dependencies = [ - "zerovec", -] - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "proc-macro2" -version = "1.0.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quinn" -version = "0.11.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8" -dependencies = [ - "bytes", - "cfg_aliases", - "pin-project-lite", - "quinn-proto", - "quinn-udp", - "rustc-hash", - "rustls", - "socket2", - "thiserror", - "tokio", - "tracing", - "web-time", -] - -[[package]] -name = "quinn-proto" -version = "0.11.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fcb935c5bec503c2f0e306bdd3e58bb9029dcb14fa8d9ac76e3a5256ac0763e" -dependencies = [ - "aws-lc-rs", - "bytes", - "getrandom 0.3.4", - "lru-slab", - "rand 0.9.4", - "ring", - "rustc-hash", - "rustls", - "rustls-pki-types", - "slab", - "thiserror", - "tinyvec", - "tracing", - "web-time", -] - -[[package]] -name = "quinn-udp" -version = "0.5.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" -dependencies = [ - "cfg_aliases", - "libc", - "once_cell", - "socket2", - "tracing", - "windows-sys 0.60.2", -] - -[[package]] -name = "quote" -version = "1.0.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "r-efi" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" - -[[package]] -name = "r-efi" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" - -[[package]] -name = "rand" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" -dependencies = [ - "rand_chacha 0.9.0", - "rand_core 0.9.5", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" -dependencies = [ - "ppv-lite86", - "rand_core 0.9.5", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.17", -] - -[[package]] -name = "rand_core" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" -dependencies = [ - "getrandom 0.3.4", -] - -[[package]] -name = "rand_core" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" - -[[package]] -name = "rcgen" -version = "0.14.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57f6d249aad744e274e682777a50283a225a32705394ee6d5fcc01efa25e4055" -dependencies = [ - "aws-lc-rs", - "pem", - "ring", - "rustls-pki-types", - "time", - "x509-parser", - "yasna", -] - -[[package]] -name = "redox_syscall" -version = "0.5.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" -dependencies = [ - "bitflags", -] - -[[package]] -name = "ring" -version = "0.17.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" -dependencies = [ - "cc", - "cfg-if", - "getrandom 0.2.17", - "libc", - "untrusted 0.9.0", - "windows-sys 0.52.0", -] - -[[package]] -name = "rustc-hash" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" - -[[package]] -name = "rustc_version" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver", -] - -[[package]] -name = "rusticata-macros" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" -dependencies = [ - "nom", -] - -[[package]] -name = "rustls" -version = "0.23.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b92b125634d9b795e7beca796cc790df15a7fb38323bf3196fda83292d06b1f" -dependencies = [ - "aws-lc-rs", - "log", - "once_cell", - "ring", - "rustls-pki-types", - "rustls-webpki", - "subtle", - "zeroize", -] - -[[package]] -name = "rustls-native-certs" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d" -dependencies = [ - "openssl-probe", - "rustls-pki-types", - "schannel", - "security-framework", -] - -[[package]] -name = "rustls-pki-types" -version = "1.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" -dependencies = [ - "web-time", - "zeroize", -] - -[[package]] -name = "rustls-webpki" -version = "0.103.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" -dependencies = [ - "aws-lc-rs", - "ring", - "rustls-pki-types", - "untrusted 0.9.0", -] - -[[package]] -name = "rustversion" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" - -[[package]] -name = "ryu" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" - -[[package]] -name = "schannel" -version = "0.1.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "security-framework" -version = "3.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "semver" -version = "1.0.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" - -[[package]] -name = "serde" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" -dependencies = [ - "serde_core", - "serde_derive", -] - -[[package]] -name = "serde_core" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.150" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" -dependencies = [ - "itoa", - "memchr", - "serde", - "serde_core", - "zmij", -] - -[[package]] -name = "serde_yaml" -version = "0.9.34+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" -dependencies = [ - "indexmap", - "itoa", - "ryu", - "serde", - "unsafe-libyaml", -] - -[[package]] -name = "server" -version = "0.1.0" -dependencies = [ - "base64", - "hex", - "mtp", - "rcgen", - "serde_core", - "serde_json", - "tokio", -] - -[[package]] -name = "sha2" -version = "0.10.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" -dependencies = [ - "cfg-if", - "cpufeatures 0.2.17", - "digest 0.10.7", -] - -[[package]] -name = "sha2" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" -dependencies = [ - "cfg-if", - "cpufeatures 0.3.0", - "digest 0.11.3", -] - -[[package]] -name = "sha3" -version = "0.10.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77fd7028345d415a4034cf8777cd4f8ab1851274233b45f84e3d955502d93874" -dependencies = [ - "digest 0.10.7", - "keccak 0.1.6", -] - -[[package]] -name = "shake" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09057cb2149ad4cbd2da1e26b351f9a4c354219421229c69c3063e6f61947c4a" -dependencies = [ - "digest 0.11.3", - "keccak 0.2.0", - "sponge-cursor", -] - -[[package]] -name = "shlex" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" - -[[package]] -name = "signal-hook-registry" -version = "1.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" -dependencies = [ - "errno", - "libc", -] - -[[package]] -name = "signature" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" -dependencies = [ - "rand_core 0.6.4", -] - -[[package]] -name = "signature" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d567dcbaf0049cb8ac2608a76cd95ff9e4412e1899d389ee400918ca7537f5" -dependencies = [ - "digest 0.11.3", - "rand_core 0.10.1", -] - -[[package]] -name = "slab" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" - -[[package]] -name = "smallvec" -version = "1.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" - -[[package]] -name = "socket2" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" -dependencies = [ - "libc", - "windows-sys 0.61.2", -] - -[[package]] -name = "spki" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" -dependencies = [ - "base64ct", - "der 0.7.10", -] - -[[package]] -name = "spki" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d9efca8738c78ee9484207732f728b1ef517bbb1833d6fc0879ca898a522f6f" -dependencies = [ - "base64ct", - "der 0.8.0", -] - -[[package]] -name = "sponge-cursor" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a0219bd7d979d58245a4f41f695e1ac9f8befdffadd7f61f1bae9e39abc6620" - -[[package]] -name = "stable_deref_trait" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "syn" -version = "2.0.118" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "synstructure" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "thiserror" -version = "2.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "2.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "time" -version = "0.3.51" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c17d80feb7334b40c484e45ed1a5273dfd8bfda537c3be2e74a06a6686f327" -dependencies = [ - "deranged", - "num-conv", - "powerfmt", - "serde_core", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" - -[[package]] -name = "time-macros" -version = "0.2.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcef1a61bdb119096e153208ec5cbec23944ce8bca13be5c7f60c634f7403935" -dependencies = [ - "num-conv", - "time-core", -] - -[[package]] -name = "tinystr" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" -dependencies = [ - "displaydoc", - "zerovec", -] - -[[package]] -name = "tinyvec" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "tokio" -version = "1.52.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" -dependencies = [ - "bytes", - "libc", - "mio", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "windows-sys 0.61.2", -] - -[[package]] -name = "tokio-macros" -version = "2.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tracing" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tracing-core" -version = "0.1.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" -dependencies = [ - "once_cell", -] - -[[package]] -name = "typenum" -version = "1.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" - -[[package]] -name = "unicode-ident" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" - -[[package]] -name = "universal-hash" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" -dependencies = [ - "crypto-common 0.1.7", - "subtle", -] - -[[package]] -name = "unsafe-libyaml" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" - -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - -[[package]] -name = "url" -version = "2.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", - "serde", -] - -[[package]] -name = "utf8_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - -[[package]] -name = "wasip2" -version = "1.0.4+wasi-0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" -dependencies = [ - "wit-bindgen", -] - -[[package]] -name = "wasm-bindgen" -version = "0.2.125" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a" -dependencies = [ - "cfg-if", - "once_cell", - "rustversion", - "wasm-bindgen-macro", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.125" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.125" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd" -dependencies = [ - "bumpalo", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.125" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "web-time" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "windows-link" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.5", -] - -[[package]] -name = "windows-sys" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", -] - -[[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_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - -[[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_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - -[[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_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - -[[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_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - -[[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_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - -[[package]] -name = "wit-bindgen" -version = "0.57.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" - -[[package]] -name = "writeable" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" - -[[package]] -name = "wtransport" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea4aacf790813ee1956751491800537f4e04af7557b7b370501ccbfbc85963e4" -dependencies = [ - "bytes", - "pem", - "quinn", - "rcgen", - "rustls", - "rustls-native-certs", - "rustls-pki-types", - "sha2 0.11.0", - "socket2", - "thiserror", - "time", - "tokio", - "tracing", - "url", - "wtransport-proto", - "x509-parser", -] - -[[package]] -name = "wtransport-proto" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5867c629e4252f7439d82315923daaf27f4fa442410d51b78ab93ef4c432a11" -dependencies = [ - "httlib-huffman", - "octets", - "thiserror", - "url", -] - -[[package]] -name = "x25519-dalek" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" -dependencies = [ - "curve25519-dalek", - "rand_core 0.6.4", - "serde", - "zeroize", -] - -[[package]] -name = "x509-parser" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d43b0f71ce057da06bc0851b23ee24f3f86190b07203dd8f567d0b706a185202" -dependencies = [ - "asn1-rs", - "aws-lc-rs", - "data-encoding", - "der-parser", - "lazy_static", - "nom", - "oid-registry", - "ring", - "rusticata-macros", - "thiserror", - "time", -] - -[[package]] -name = "yasna" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5f6765e852b9b4dc8e2a76843e4d64d1cea8e79bcde0b6901aea8e7c7f08282" -dependencies = [ - "bit-vec", - "time", -] - -[[package]] -name = "yoke" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" -dependencies = [ - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zerocopy" -version = "0.8.52" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.52" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "zerofrom" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zeroize" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "zerotrie" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", -] - -[[package]] -name = "zerovec" -version = "0.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "zmij" -version = "1.0.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/example-usage/client/src/main.rs b/example-usage/client/src/main.rs index b822805..5f3c9b4 100644 --- a/example-usage/client/src/main.rs +++ b/example-usage/client/src/main.rs @@ -2,29 +2,13 @@ mod auth; mod messages; use std::fs; -use std::path::Path; use mtp::client::ClientConfig; use mtp::crypto::{KemPublicKey, PublicKeyBundle, SignaturePqPublicKey, SignaturePublicKey}; -fn dev_cert_path() -> String { - std::env::var("MTP_DEV_CERT").unwrap_or_else(|_| { - if Path::new("example-usage/dev-cert/cert.pem").exists() { - "example-usage/dev-cert/cert.pem".to_string() - } else { - "dev-cert/cert.pem".to_string() - } - }) -} - #[tokio::main] async fn main() -> Result<(), Box> { - let cert_path = dev_cert_path(); - let cert_pem = fs::read(&cert_path).unwrap_or_else(|e| { - panic!( - "Missing TLS certificate at {cert_path}: enter the Nix shell first or run the server to generate it: {e}" - ) - }); + let cert_pem = fs::read("server.pem").expect("Missing server.pem: run server first"); let host_public_key = PublicKeyBundle::new( KemPublicKey::new( fs::read("host_enc_kem_pk.bin") @@ -47,10 +31,9 @@ async fn main() -> Result<(), Box> { client_id: 0, }; - let server_bundle = host_public_key.clone(); let (conn, keyring) = auth::connect_or_register(config, host_public_key, "client_keys.json").await?; - messages::send_and_receive(&conn, &keyring, &server_bundle).await?; + messages::send_and_receive(&conn, &keyring).await?; println!("\nDone"); Ok(()) diff --git a/example-usage/client/src/messages.rs b/example-usage/client/src/messages.rs index f5b82a4..1c17e5a 100644 --- a/example-usage/client/src/messages.rs +++ b/example-usage/client/src/messages.rs @@ -1,14 +1,18 @@ use mtp::client::MTPConnection; use mtp::codec::{CommunicationType, CommunicationValue, DataType, DataTypeId, DataValue}; -use mtp::crypto::{Ed25519Signer, EncryptionType, Keyring, PublicKeyBundle, SigAlgorithm}; +use mtp::crypto::{ChaCha20Poly1305, Ed25519Signer, Keyring, SigAlgorithm}; -pub fn build_demo_message( - client_id: u64, - keyring: &Keyring, - server_bundle: &PublicKeyBundle, -) -> CommunicationValue { - // Encrypt to the server's KEM public key; the server decrypts with its keyring. - let enc_type = EncryptionType::MlKemChaCha20Poly1305; +fn derive_demo_key() -> [u8; 32] { + mtp::crypto::derive_encryption_key( + b"MTP-demo-shared-secret", + b"MTP-demo-salt", + b"encrypted-container-demo", + ) + .expect("key derivation must succeed") +} + +pub fn build_demo_message(client_id: u64, keyring: &Keyring) -> CommunicationValue { + let cipher = ChaCha20Poly1305::new(derive_demo_key()); let signer = Ed25519Signer::new(&keyring.sig_cl_secret_key) .expect("Ed25519 signer from keyring"); @@ -17,7 +21,7 @@ pub fn build_demo_message( (DataTypeId(2), DataValue::UnsignedNumber(42)), ]); let mut dv_enc = inner_enc; - dv_enc.encrypt_container(enc_type, server_bundle, b"demo-aad"); + dv_enc.encrypt_container(&cipher, b"demo-aad"); let inner_sig = DataValue::Container(vec![ (DataTypeId(1), DataValue::Str("signed by client".into())), @@ -27,36 +31,24 @@ pub fn build_demo_message( dv_sig.sign_container(SigAlgorithm::ED25519, &signer); let inner_sec = DataValue::Container(vec![ - ( - DataTypeId(1), - DataValue::Str("signed+encrypted payload".into()), - ), + (DataTypeId(1), DataValue::Str("signed+encrypted payload".into())), (DataTypeId(2), DataValue::UnsignedNumber(7)), ]); let mut dv_sec = inner_sec; - dv_sec.sign_and_encrypt_container(SigAlgorithm::ED25519, &signer, enc_type, server_bundle, b"demo-aad"); + dv_sec.sign_and_encrypt_container(SigAlgorithm::ED25519, &signer, &cipher, b"demo-aad"); let timestamp = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap() .as_secs(); - let msg = CommunicationValue::new(CommunicationType::Ping) - .add_typed_default( - DataType::Description, - DataValue::Str("MTP Data Type Demo".into()), - ) - .add_typed_default( - DataType::Timestamp, - DataValue::UnsignedNumber(timestamp as u128), - ) + CommunicationValue::new(CommunicationType::Ping) + .add_typed_default(DataType::Description, DataValue::Str("MTP Data Type Demo".into())) + .add_typed_default(DataType::Timestamp, DataValue::UnsignedNumber(timestamp as u128)) .add_typed_default(DataType::Data, DataValue::Str("Hello, MTP!".into())) .add_typed_default(DataType::Flags, DataValue::BoolTrue) .add_typed_default(DataType::Value, DataValue::Float(2, 12345)) - .add_typed_default( - DataType::BinaryData, - DataValue::Bytes(vec![0xDE, 0xAD, 0xBE, 0xEF, 0x42]), - ) + .add_typed_default(DataType::BinaryData, DataValue::Bytes(vec![0xDE, 0xAD, 0xBE, 0xEF, 0x42])) .add_typed_default( DataType::Items, DataValue::Array(vec![ @@ -68,23 +60,19 @@ pub fn build_demo_message( .add_typed_default(DataType::EncryptedPayload, dv_enc) .add_typed_default(DataType::SignedPayload, dv_sig) .add_typed_default(DataType::SecurePayload, dv_sec) - .with_sender(client_id); - msg + .with_sender(client_id) } pub async fn send_and_receive( conn: &MTPConnection, keyring: &Keyring, - server_bundle: &PublicKeyBundle, ) -> Result<(), Box> { - let msg = build_demo_message(conn.client_id, keyring, server_bundle); + let msg = build_demo_message(conn.client_id, keyring); println!("Sending: {msg}"); conn.sender.send(&msg).await?; match conn.receiver.receive().await { - Ok(resp) => { - println!("Received: {resp}"); - } + Ok(resp) => println!("Received: {resp}"), Err(e) => eprintln!("Receive error: {e}"), } diff --git a/example-usage/host_keys.json.stale-no-kem b/example-usage/host_keys.json.stale-no-kem deleted file mode 100644 index f38d29b..0000000 --- a/example-usage/host_keys.json.stale-no-kem +++ /dev/null @@ -1,4 +0,0 @@ -{ - "host_id": 1, - "keyring": "0000000007a0cc83597da99032dfe763d1e27eb368420b023be3518323638a09c10446e5a1e182beca1c0e8dda17a7b4b69cc0bbf1ec45f0b03c6b3c1052a540f69e4140f7d1d11039398f77a45630b7fe3254b001ce08d5dd92c6cba881ed20f4eefa6153608d7fb766bdb038939348ba091806c8bc5608650ae8c187be3bf90384b3cd227041462ba409d521c3970c7cc3fce096058f2648c6e2e242273e0af2c47fbf4d899be75b910e7d357618248d51c6e608e9c7a247e88f5961cad53bc163cea869a54c4abbc3d6ebbffa918296f4a21694f83941335ac061068ae67edce3783b8a6afb2676171906ba862a97df2b11dc9911d7e654718d2ecfb9e4b69217f50065981f15ce1d7b0b6d249f68a357c9c56b6c3edfbcf876713e7f6376baa181a4535d0ab5811c2b7e7ffef23cfb6a4af0ea4e6e2f55685d594e97a20c0fac2246618120117879f521f7bb2a26a4f697e9451e3f3653695235dac13feeb0cb8999ff41fad6bf55426877bbae8fd1cd8622c2cf90a57701a7136f01a3d03202b6b1488f70c5840ced7509425b1c3ca019bd55060509a8f2bb42977c78187d7d2801309af9ae2f609cb918c1956b0f282fa4eb591b530c7f5f83c1d54bacabe4abe34780e6c6802509082ad38ec1bcc6105eae77e67e3d414c7eb248d3f5582681e9fbbd5183fa978604f094b9013804055745deba587086f2eeb95a911d1cb4d0dd960c64ecfaad2ae0981e44d38c2441b5df03c9ea23338be78dcd0d4e8712ff6e9ab5d751870e7243c06835e2e7a14b7d3005251ab66fbff4820c0e03317035ead18e213846af6325d3e871524708eaa3093f883e223281a8f1be55cd3dc084dbdd461566c35f6a0d418dcc66ab1697242bf1016283f4e50e76e8f42feae937d4b908d6132c7d80755a58120d75489931f58de641f2f8676fca6b60da18e977b38108d8ffe98f96165222c07520c06974b39aa8b5139458ea101727f95818e69a6afcf0fa028224e8c0af5cd4f32db0a0583eb42a11fe7fa08c424563dde4e2977c898f2f68b2f183016c44dba013851d909844981d0d2635e7fe4af8f80ca3acbea30d11a2b92cf4c4866765493217fd078aa8903ea50aeace282d90a156cc37714f95d109c5421f947209656305beffa891717c7bc8802bb3eab87fc753b0450155e5f0b0c7f14bd66db4e69d330b64e8fc6cbc946e515536b06f65966a982435af15c4b612d25434ef3bc98c33c47abc3b98159733c5f03f541342e6d5e1c0ca6caa00e5616cee151771dbf3a73d571ee0b37ae54d4672e411feb1364f5b820dbc0912e8c43a8213d41576d8b207ab8564537a23aa99c08f6079b83a63c376d10b919023cb57363e7562527e634cc45f5131ae3204615ac078bb216677e65cafb2a95246635f76e1a1a7659d8be263ef403395e16ca388ec1b58b51376b221ab64309bb493687e6cfa7587b603a53e00b1eb4d413f299d7741e1de70df3dc6d3190a8c84fffb7a7901d524f4b5d9a7229c5c99f61faf3d5295760f35d3d54bbea944f044c35a2202e6d2865369809d0df2f64151fb83b3a74d8ad1e7b6cc6d0088a535f7ca6dc384bd93cef50132a0d882caac96acecd15d6eeb600ca6c25f7ff19795cf8595d62bdf5022eadc99a471a36a2b46cd1c4f4d999560eadf4994f77c50083eaad96f574100b594a5272b661c80ffed36a364e7aa69e5a0c69f1af9ba44eeb50e892309ca442ec09f0c716d1483f4d74efbf12ff845f5252e83e64d28a83541b5fbef87296e8a19c84c7c6fa46f61299f7375d74c8441e432613a5f721548a010406ab56f18c997a48d74970f6e651f5d1223e233b5b2ff952e3824b72f92755f491110517d71878e7469beaab6c0835c6467598f7969f1b85157dabebb1003b1f9081bab2aa2296a269a35c34f494e706291db5923690c19e4eaafa5bc3e838e3c6434d0ab91c0b95ce4221ed9cfbe011fa24168d821bed5af6f2fbcb75db1e1ea2a71e5a5f38ad4fab3ebf61983745f4464a0fcf5917415b01846d037fdb628637241070287cbcdcdf638353f01c03030bb36df7f48b5b1eba6152d4f569d034b5f2c9b61b1cf0402df910947d100f54bd0b0261445e60c0f4b1e1df292dbf26bb85ab327a19a33bca531d497b4e7181ba54881cfa1b43d35da64436850d298077877bd41cfd172d91413fee1888ad603a2368fedd611690878ca1f789a6fd21b6932b868bb3084e689c8995113478bbf6ba8ad04e937be34dce58b1117ebbd2eddde489fb34028e117b59fac89bf9a6b5970a989840447d3649f6e955fd0561a56d4038fac4fa4f67515400ecbf256a9339a6b61a62ffc101fc7241422e991b54215f2f6ae4d719d99e660cc6800bf33ce2a00a2b8d101908eb32a31ecb311f8d2da5509a4f0800515193d336a716a52868813a8ea5b878aacd5dca3753c66ea38c3f1f48529746581cbc375cdef323d885ee119f4b1397f5828dec90923caae9845c1f189c482d68342a70d979b95943287127996ce137cfdc2ce3f6ecbfe5f5f5b90b8260fc662c897d4cc1414ad77314f4c15b84308f5836d33d8183388dbbc0d15aa2a9c4c14f447450861e373544c25a61b874ba6716af6bce7bec2a42d6408e73fbf0a5b27fbd9aa3055bfd7b0a79cac66c6f51f00ab90bcb0dc28254a8a4fdbfb7c5bc63a6aa7227d0e335eb0eb01124582db8c7b92f8e84515acddc7bb24e2b3059329228c197e3432bead261b2dbf1798491ebb11658700201d4224bc1f165129ac6fac5909a664ef107f70035019ff7051bba3dc980ac3da0020faa51b18eb51dd316605d3842f71c23a1a15ec71c1cc5d650dabe60da9dc7c5600209300a95b9dcf41d3ee469fc9937737d572915f10e5ea2da286e13bf2dbb54ef6" -} \ No newline at end of file diff --git a/example-usage/server/Cargo.toml b/example-usage/server/Cargo.toml index d94132e..79d33be 100644 --- a/example-usage/server/Cargo.toml +++ b/example-usage/server/Cargo.toml @@ -14,4 +14,3 @@ tokio = { version = "1", features = ["full"] } serde_json = { version = "1" } hex = "0.4" serde_core = "1.0.228" -base64 = "0.22" diff --git a/example-usage/server/src/clients.rs b/example-usage/server/src/clients.rs index d9ad714..3417604 100644 --- a/example-usage/server/src/clients.rs +++ b/example-usage/server/src/clients.rs @@ -8,18 +8,14 @@ pub fn load_client_db( path: &str, ) -> Result<(Arc>>, Arc>), Box> { - let clients_map = match fs::read_to_string(path) { - Ok(data) => match serde_json::from_str(&data) { - Ok(clients) => clients, - Err(e) => { - eprintln!("Failed to parse {path}; starting with empty client database: {e}"); - HashMap::new() - } - }, - Err(_) => HashMap::new(), - }; - let clients: Arc>> = Arc::new(Mutex::new(clients_map)); - let next_value = clients.lock().unwrap().keys().max().unwrap_or(&999) + 1; - let next_id = Arc::new(Mutex::new(next_value)); + let clients: Arc>> = + Arc::new(Mutex::new(if let Ok(data) = fs::read_to_string(path) { + serde_json::from_str(&data).unwrap_or_default() + } else { + HashMap::new() + })); + let next_id = Arc::new(Mutex::new( + clients.lock().unwrap().keys().max().unwrap_or(&999) + 1, + )); Ok((clients, next_id)) } diff --git a/example-usage/server/src/handlers.rs b/example-usage/server/src/handlers.rs index 2a35595..768293b 100644 --- a/example-usage/server/src/handlers.rs +++ b/example-usage/server/src/handlers.rs @@ -1,7 +1,5 @@ use mtp::codec::{CommunicationType, CommunicationValue, DataType, DataTypeId, DataValue, TypeMap}; -use mtp::crypto::{ - CryptoError, Keyring, SignaturePublicKey, SignatureScheme, verify_ed25519, -}; +use mtp::crypto::{ChaCha20Poly1305, CryptoError, SignatureScheme, SignaturePublicKey, verify_ed25519}; struct Ed25519Verifier(SignaturePublicKey); @@ -14,11 +12,19 @@ impl SignatureScheme for Ed25519Verifier { } } +fn derive_demo_key() -> [u8; 32] { + mtp::crypto::derive_encryption_key( + b"MTP-demo-shared-secret", + b"MTP-demo-salt", + b"encrypted-container-demo", + ) + .expect("key derivation must succeed") +} + pub fn process_and_respond( msg: &CommunicationValue, tm: &TypeMap, client_pk: Option<&mtp::crypto::PublicKeyBundle>, - host_keyring: &Keyring, ) -> CommunicationValue { let desc_id = DataTypeId(tm.data_id_enum(DataType::Description).unwrap()); let ts_id = DataTypeId(tm.data_id_enum(DataType::Timestamp).unwrap()); @@ -50,6 +56,8 @@ pub fn process_and_respond( println!(" Binary: {:?}", binary.as_bytes()); println!(" Items: {:?}", items.as_array()); + let cipher = ChaCha20Poly1305::new(derive_demo_key()); + let mut enc_status = String::from("EncryptedPayload: not present"); let mut sig_status = String::from("SignedPayload: not present"); let mut secure_status = String::from("SecurePayload: not present"); @@ -57,13 +65,12 @@ pub fn process_and_respond( let enc = msg.get_data(enc_id); if matches!(enc, DataValue::EncryptedContainer(_)) { let mut dv = enc.clone(); - if dv.decrypt_into_container(host_keyring, b"demo-aad").is_some() { + if dv.decrypt_into_container(&cipher, b"demo-aad").is_some() { if let Some(entries) = dv.as_container() { println!(" Decrypted EncryptedPayload: {:?}", entries); enc_status = format!("EncryptedPayload decrypted OK ({} entries)", entries.len()); } } else { - eprintln!(" EncryptedPayload decryption failed"); enc_status = String::from("EncryptedPayload: decryption FAILED"); } } @@ -76,14 +83,13 @@ pub fn process_and_respond( if dv.verify_into_container(&verifier).is_some() { if let Some(entries) = dv.as_container() { println!(" Verified SignedPayload: {:?}", entries); - sig_status = format!("SignedPayload verified OK ({} entries)", entries.len()); + sig_status = + format!("SignedPayload verified OK ({} entries)", entries.len()); } } else { - eprintln!(" SignedPayload verification failed"); sig_status = String::from("SignedPayload: verification FAILED"); } } else { - eprintln!(" SignedPayload cannot be verified; no client public key available"); sig_status = String::from("SignedPayload: no client public key available"); } } @@ -93,7 +99,7 @@ pub fn process_and_respond( if let Some(pk_bundle) = client_pk { let verifier = Ed25519Verifier(pk_bundle.sig_cl_public_key.clone()); let mut dv = secure.clone(); - if dv.decrypt_signed_encrypted_container(host_keyring, b"demo-aad").is_some() + if dv.decrypt_signed_encrypted_container(&cipher, b"demo-aad").is_some() && dv.verify_into_container(&verifier).is_some() { if let Some(entries) = dv.as_container() { @@ -104,11 +110,9 @@ pub fn process_and_respond( ); } } else { - eprintln!(" SecurePayload decryption/verification failed"); secure_status = String::from("SecurePayload: decryption/verification FAILED"); } } else { - eprintln!(" SecurePayload cannot be verified; no client public key available"); secure_status = String::from("SecurePayload: no client public key available"); } } diff --git a/example-usage/server/src/keys.rs b/example-usage/server/src/keys.rs index 133eeba..86ac9c2 100644 --- a/example-usage/server/src/keys.rs +++ b/example-usage/server/src/keys.rs @@ -1,11 +1,9 @@ use std::fs; -use mtp::crypto::kem::HybridKem; use mtp::crypto::{Ed25519Signer, Keyring, MlDsaSigner}; +use mtp::crypto::kem::HybridKem; -pub fn load_or_generate_host_keys( - path: &str, -) -> Result<(u64, Keyring), Box> { +pub fn load_or_generate_host_keys(path: &str) -> Result<(u64, Keyring), Box> { if let Ok(data) = fs::read_to_string(path) { let json: serde_json::Value = serde_json::from_str(&data)?; let hid = json["host_id"].as_u64().unwrap_or(1); @@ -29,14 +27,6 @@ pub fn load_or_generate_host_keys( } pub fn export_host_public_keys(host_keyring: &Keyring) -> Result<(), Box> { - let public_key_bundle_hex = hex::encode(host_keyring.public_key_bundle().as_bytes()); - - fs::write("host_public_key_bundle.hex", &public_key_bundle_hex)?; - fs::create_dir_all("web-client/public")?; - fs::write( - "web-client/public/host_public_key_bundle.hex", - &public_key_bundle_hex, - )?; fs::write( "host_enc_kem_pk.bin", host_keyring.kem_public_key.as_bytes(), diff --git a/example-usage/server/src/main.rs b/example-usage/server/src/main.rs index 28d1ff5..414bbe1 100644 --- a/example-usage/server/src/main.rs +++ b/example-usage/server/src/main.rs @@ -5,53 +5,18 @@ mod tls; use mtp::host::{HostConfig, MTPHost}; use mtp::type_map::TypeMap; -use std::path::Path; - -fn dev_cert_paths() -> (String, String) { - let cert = std::env::var("MTP_DEV_CERT").unwrap_or_else(|_| { - if Path::new("example-usage/dev-cert/cert.pem").exists() { - "example-usage/dev-cert/cert.pem".to_string() - } else { - "dev-cert/cert.pem".to_string() - } - }); - let key = std::env::var("MTP_DEV_KEY").unwrap_or_else(|_| { - if Path::new("example-usage/dev-cert/key.pem").exists() { - "example-usage/dev-cert/key.pem".to_string() - } else { - "dev-cert/key.pem".to_string() - } - }); - (cert, key) -} #[tokio::main] async fn main() -> Result<(), Box> { - let (cert_path, key_path) = dev_cert_paths(); - let (cert_pem, key_pem) = tls::load_or_generate_tls(&cert_path, &key_path)?; - let cert_hash = tls::certificate_sha256_hex(&cert_pem)?; - tls::export_webtransport_cert_hash(&cert_hash)?; - println!("WebTransport certificate sha256: {cert_hash}"); - + let (cert_pem, key_pem) = tls::load_or_generate_tls("server.pem", "server.key")?; let (host_id, host_keyring) = keys::load_or_generate_host_keys("host_keys.json")?; keys::export_host_public_keys(&host_keyring)?; - // The keyring is moved into the host config; keep a copy for decrypting the - // demo payloads clients encrypt to our KEM public key. - let decrypt_keyring = mtp::crypto::Keyring::from_bytes(&host_keyring.to_bytes()) - .expect("re-load host keyring for decryption"); - let (clients, next_id) = clients::load_client_db("clients.json")?; let clients_for_get = clients.clone(); let get_existing_user = Box::new(move |id: u64| -> Option { - let result = clients_for_get.lock().unwrap().get(&id).cloned(); - if result.is_some() { - println!("Auth lookup: client ID {id} found"); - } else { - eprintln!("Auth lookup: unknown client ID {id}"); - } - result + clients_for_get.lock().unwrap().get(&id).cloned() }); let clients_for_register = clients.clone(); @@ -63,13 +28,7 @@ async fn main() -> Result<(), Box> { let id = *nid; *nid += 1; db.insert(id, bundle); - match serde_json::to_string_pretty(&*db) { - Ok(json) => match std::fs::write(&clients_path, json) { - Ok(()) => {} - Err(e) => eprintln!("Failed to persist client database to {clients_path}: {e}"), - }, - Err(e) => eprintln!("Failed to serialize client database after registering {id}: {e}"), - } + std::fs::write(&clients_path, serde_json::to_string_pretty(&*db).unwrap()).ok(); println!("Registered new client with ID: {}", id); id }); @@ -103,12 +62,8 @@ async fn main() -> Result<(), Box> { match conn.receiver.receive().await { Ok(msg) => { println!("Received: {msg}"); - let response = handlers::process_and_respond( - &msg, - tm, - conn.client_public_key.as_ref(), - &decrypt_keyring, - ); + let response = + handlers::process_and_respond(&msg, tm, conn.client_public_key.as_ref()); println!("Sending: {response}"); conn.sender.send(&response).await?; } diff --git a/example-usage/server/src/tls.rs b/example-usage/server/src/tls.rs index b312100..ab8c993 100644 --- a/example-usage/server/src/tls.rs +++ b/example-usage/server/src/tls.rs @@ -1,7 +1,4 @@ use std::fs; -use std::path::Path; - -use base64::Engine; pub fn load_or_generate_tls( cert_path: &str, @@ -13,12 +10,6 @@ pub fn load_or_generate_tls( } println!("Generating self-signed TLS certificate ..."); - if let Some(parent) = Path::new(cert_path).parent() { - fs::create_dir_all(parent)?; - } - if let Some(parent) = Path::new(key_path).parent() { - fs::create_dir_all(parent)?; - } let key_pair = rcgen::KeyPair::generate()?; let params = rcgen::CertificateParams::new(vec!["localhost".into(), "127.0.0.1".into()])?; let cert = params.self_signed(&key_pair)?; @@ -32,39 +23,3 @@ pub fn load_or_generate_tls( Ok((cert_str.into_bytes(), key_str.into_bytes())) } - -pub fn certificate_sha256_hex(cert: &[u8]) -> Result> { - let der = if cert.starts_with(b"-----BEGIN CERTIFICATE-----") { - let pem = std::str::from_utf8(cert)?; - let base64 = pem - .lines() - .filter(|line| !line.starts_with("-----")) - .collect::(); - base64::engine::general_purpose::STANDARD.decode(base64)? - } else { - cert.to_vec() - }; - - Ok(hex::encode(mtp::crypto::sha256(&der))) -} - -pub fn export_webtransport_cert_hash(hash: &str) -> Result<(), Box> { - let public_dir = if Path::new("web-client").exists() { - Path::new("web-client/public") - } else { - Path::new("example-usage/web-client/public") - }; - fs::create_dir_all(public_dir)?; - fs::write(public_dir.join("mtp_dev_cert_hash.txt"), hash)?; - - let dev_cert_dir = if Path::new("dev-cert").exists() { - Path::new("dev-cert") - } else { - Path::new("example-usage/dev-cert") - }; - if dev_cert_dir.exists() { - fs::write(dev_cert_dir.join("sha256.txt"), hash)?; - } - - Ok(()) -} diff --git a/example-usage/web-client/index.html b/example-usage/web-client/index.html index 5a6b1b2..904cc81 100644 --- a/example-usage/web-client/index.html +++ b/example-usage/web-client/index.html @@ -5,11 +5,8 @@ MTP Web Client