diff --git a/.gitignore b/.gitignore index ea8c4bf..a74fd9f 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +/*/*/deps/ diff --git a/Cargo.lock b/Cargo.lock index f6dbc8d..14c4bef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,47 +4,47 @@ version = 4 [[package]] name = "ahash" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", - "getrandom 0.2.15", + "getrandom 0.3.4", "once_cell", "serde", "version_check", - "zerocopy 0.7.35", + "zerocopy", ] [[package]] name = "aho-corasick" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" dependencies = [ "memchr", ] [[package]] -name = "android-tzdata" -version = "0.1.1" +name = "allocator-api2" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "android_system_properties" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +checksum = "ae221649c9976a6f6c56ae1facf410f3ddb33cc661c4b7b61020a912d4237fbc" dependencies = [ "libc", ] [[package]] name = "anstream" -version = "0.6.18" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" dependencies = [ "anstyle", "anstyle-parse", @@ -57,56 +57,86 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.10" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" [[package]] name = "anstyle-parse" -version = "0.2.6" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.2" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "anstyle-wincon" -version = "3.0.7" +version = "3.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", - "once_cell", - "windows-sys 0.59.0", + "once_cell_polyfill", + "windows-sys 0.61.2", ] [[package]] name = "anyhow" -version = "1.0.97" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" + +[[package]] +name = "atomic-waker" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.4.0" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "aws-lc-rs" +version = "1.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b281d307588d634de920874890732659e2e7672f72b5e10e81badc1a8a83621e" +dependencies = [ + "aws-lc-sys", + "untrusted 0.7.1", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "9bff6c3b54fad79a2e60b8102caf565819711497c1f5f092f49508e2f5c31b27" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", + "pkg-config", +] [[package]] name = "base16ct" -version = "0.2.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +checksum = "fd307490d624467aa6f74b0eabb77633d1f758a7b25f12bceb0b22e08d9726f6" [[package]] name = "base64" @@ -120,11 +150,23 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5" + +[[package]] +name = "base64-serde" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c6d128af408d8ebd08331f0331cf2cf20d19e6c44a7aec58791641ecc8c0b5" + [[package]] name = "base64ct" -version = "1.8.1" +version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e050f626429857a27ddccb31e0aca21356bfa709c04041aefddac081a8f068a" +checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" [[package]] name = "bit-set" @@ -143,42 +185,61 @@ checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" [[package]] name = "bitflags" -version = "2.9.0" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "bitmask" -version = "0.5.0" +name = "bitflags" +version = "2.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5da9b3d9f6f585199287a473f4f8dfab6566cf827d15c00c219f53c645687ead" +checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" [[package]] name = "block-buffer" -version = "0.10.4" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" dependencies = [ - "generic-array", + "hybrid-array", ] [[package]] name = "borrow-or-share" -version = "0.2.2" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc0b364ead1874514c8c2855ab558056ebfeb775653e7ae45ff72f28f8f3166c" + +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "bstr" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eeab4423108c5d7c744f4d234de88d18d636100093ae04caf4825134b9c3a32" +checksum = "6bb31b46c14244e20ee9984b11bf5c992b91fb6939fea616e3512c8baecdbe5f" +dependencies = [ + "memchr", + "serde_core", +] [[package]] name = "bumpalo" -version = "3.17.0" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "bytecount" -version = "0.6.8" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" +checksum = "175812e0be2bccb6abe50bb8d566126198344f707e304f45c648fd8f2cc0365e" [[package]] name = "byteorder" @@ -186,6 +247,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "bytes" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" + [[package]] name = "cbor-codec" version = "0.7.1" @@ -198,24 +265,27 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.17" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a" +checksum = "f360145194ee8e21db5ee7f3fcd4fe52210864c75c985dae33218202c8bbe040" dependencies = [ + "find-msvc-tools", + "jobserver", + "libc", "shlex", ] [[package]] name = "ccatoken" version = "0.1.0" -source = "git+https://github.com/veraison/rust-ccatoken?rev=6d5b8db9#6d5b8db9e815fbcfeacbb19f8793fed4b6f38b62" +source = "git+https://github.com/veraison/rust-ccatoken?rev=c2257a3#c2257a351f792cb64a8d230b4caa6256fd8118ed" dependencies = [ "base64 0.21.7", - "bitmask", + "bitflags 2.13.2", "ciborium", "clap", "cose-rust", - "ear 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ear 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex", "hex-literal", "jsonwebtoken", @@ -229,17 +299,27 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" + +[[package]] +name = "chacha20" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "65c35e4b699c7e15ccbe7ee35c005e4fc0a278d22238a2857e6ce2dadeda1b06" +dependencies = [ + "cfg-if", + "cpufeatures", + "rand_core 0.10.1", +] [[package]] name = "chrono" -version = "0.4.40" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" dependencies = [ - "android-tzdata", "iana-time-zone", "js-sys", "num-traits", @@ -250,23 +330,12 @@ dependencies = [ [[package]] name = "chrono-tz" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efdce149c370f133a071ca8ef6ea340b7b88748ab0810097a9e2976eaa34b4f3" +checksum = "a6139a8597ed92cf816dfb33f5dd6cf0bb93a6adc938f11039f371bc5bcd26c3" dependencies = [ "chrono", - "chrono-tz-build", - "phf 0.11.3", -] - -[[package]] -name = "chrono-tz-build" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f10f8c9340e31fc120ff885fcdb54a0b48e474bbd77cab557f0c30a3e569402" -dependencies = [ - "parse-zoneinfo", - "phf_codegen", + "phf 0.12.1", ] [[package]] @@ -298,9 +367,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.37" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071" +checksum = "aa8876b300ab35ba921adea3dfd70157a46249b33f95c9084ae5709785478946" dependencies = [ "clap_builder", "clap_derive", @@ -318,9 +387,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.37" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2" +checksum = "ec0797fb7aeb1406c84efac526901f7ec3ead2124f946b494e72879d4b54704d" dependencies = [ "anstream", "anstyle", @@ -330,59 +399,103 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.32" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" +checksum = "f9c751b79415d4e559e3d1fcf128e09e720eb673a06d26cf6f392d37d75b66e0" dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 3.0.6", ] [[package]] name = "clap_lex" -version = "0.7.4" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +checksum = "1c133bc6a41be0d194c306b5506d15e6feeea7b1d6604bd3f8310dfb2ca96486" [[package]] -name = "colorchoice" -version = "1.0.3" +name = "cmake" +version = "0.1.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" +dependencies = [ + "cc", +] [[package]] -name = "const-oid" -version = "0.9.6" +name = "cmov" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a" [[package]] -name = "const_format" -version = "0.2.34" +name = "cmw" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "126f97965c8ad46d6d9163268ff28432e8f6a1196a55578867832e3049df63dd" +checksum = "579a5bfd38d97739b94c06dd5aa08a85621b18dc3a6b06def2998afc52b518c0" dependencies = [ - "const_format_proc_macros", + "base64 0.22.1", + "base64-serde", + "bitflags 1.3.2", + "ciborium", + "hex", + "iri-string", + "lazy_static", + "mime", + "minicbor 1.1.0", + "minicbor-serde", + "once_cell", + "regex", + "reqwest", + "serde", + "serde_json", + "simple_asn1", + "thiserror 2.0.21", + "xml-rs", ] [[package]] -name = "const_format_proc_macros" -version = "0.2.34" +name = "cobs" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" +checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", + "thiserror 2.0.21", ] [[package]] -name = "constant_time_eq" -version = "0.4.2" +name = "colorchoice" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" + +[[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.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] [[package]] name = "core-foundation-sys" @@ -390,15 +503,23 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "core_detect" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f8f80099a98041a3d1622845c271458a2d73e688351bf3cb999266764b81d48" + [[package]] name = "corim-rs" -version = "0.1.0" -source = "git+https://github.com/veraison/corim-rs#8d297d090521e1a8ee40c6a8bda97ff708e7302c" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d607c5e5e776ebd44992dda947c4190752039c268c3eb42388e384ee48f8fec7" dependencies = [ "base64 0.22.1", "ciborium", "coset", "derive_more", + "either", "oid", "openssl", "serde", @@ -408,13 +529,13 @@ dependencies = [ [[package]] name = "cose-rust" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f221b4189b72ce93755b7fa1495d1741cc330bbd9698d3032562811698e3ab84" +checksum = "6a140f41f55ff1f2126aed96961bad2387ae31d7f9bbd0e98ec888073beaac6f" dependencies = [ "cbor-codec", "openssl", - "rand 0.8.5", + "rand 0.8.8", "serde_json", ] @@ -433,14 +554,16 @@ name = "cover" version = "0.0.1" dependencies = [ "anyhow", - "base64 0.22.1", + "base64 0.23.1", "ccatoken", + "chrono", "ciborium", "clap", "clap-verbosity-flag", + "cmw", "corim-rs", "cose-rust", - "ear 0.4.0 (git+https://github.com/veraison/rust-ear?rev=15184e9a)", + "ear 0.6.0 (git+https://github.com/veraison/rust-ear?rev=5dfe47d)", "elliptic-curve", "env_logger", "jsonwebtoken", @@ -448,57 +571,80 @@ dependencies = [ "p256", "p384", "p521", - "pem", + "pem 4.0.0", "picky-asn1-der", "picky-asn1-x509", "regorus", "serde", "serde_json", + "strum", + "strum_macros", "test-case", ] +[[package]] +name = "cpubits" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b85f9c39137c3a891689859392b1bd49812121d0d61c9caf00d46ed5ce06ae" + [[package]] name = "cpufeatures" -version = "0.2.17" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +checksum = "5ca28b0ae3115b884660db4118d803791fd6756b6e88f39c0f3f7859060d7566" dependencies = [ "libc", ] [[package]] name = "crunchy" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "crypto-bigint" -version = "0.5.5" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +checksum = "1a52aa3fcda4e6302a9f48734f234d35d4721b96f8fe07d073f07ce9df4f0271" dependencies = [ - "generic-array", - "rand_core 0.6.4", + "cpubits", + "ctutils", + "getrandom 0.4.3", + "hybrid-array", + "num-traits", + "rand_core 0.10.1", "subtle", "zeroize", ] [[package]] name = "crypto-common" -version = "0.1.6" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" dependencies = [ - "generic-array", - "typenum", + "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", + "subtle", ] [[package]] name = "darling" -version = "0.21.3" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" +checksum = "ed17f5901b6630b993ca003def43f2f8ef4014fc13b047b57aad617ff32bc2ec" dependencies = [ "darling_core", "darling_macro", @@ -506,40 +652,70 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.21.3" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" +checksum = "6837e2cf7485aaae18f86181d2f0e9a7ed297a025e220aeabf63fdebd3a2ddff" dependencies = [ - "fnv", "ident_case", "proc-macro2", "quote", "strsim", - "syn", + "syn 3.0.6", ] [[package]] name = "darling_macro" -version = "0.21.3" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" +checksum = "2ac7135c3ef02b2f7833bbeb1be5ba7f966dcde8a87c6b87f65a778d71a02785" dependencies = [ "darling_core", "quote", - "syn", + "syn 3.0.6", ] [[package]] name = "data-encoding" -version = "2.8.0" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4583a4551df46e2792f82ceeac45e850d2e2d5debba0b91f102385cda5b11f06" + +[[package]] +name = "defmt" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8" +dependencies = [ + "defmt-parser", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "defmt-parser" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "575f75dfd25738df5b91b8e43e14d44bda14637a58fae779fd2b064f8bf3e010" +checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" +dependencies = [ + "thiserror 2.0.21", +] [[package]] name = "der" -version = "0.7.10" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +checksum = "a878c850e9e421b20262e9b41f9c860e4785fa07541c266b62ff9d1ef998a80a" dependencies = [ "const-oid", "pem-rfc7468", @@ -548,57 +724,63 @@ dependencies = [ [[package]] name = "deranged" -version = "0.4.0" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" dependencies = [ - "powerfmt", - "serde", + "serde_core", ] [[package]] name = "derive_more" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" +checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" dependencies = [ "derive_more-impl", ] [[package]] name = "derive_more-impl" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" +checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" dependencies = [ "proc-macro2", "quote", - "syn", + "rustc_version", + "syn 2.0.119", ] [[package]] name = "digest" -version = "0.10.7" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" dependencies = [ "block-buffer", "const-oid", "crypto-common", - "subtle", + "ctutils", ] [[package]] name = "displaydoc" -version = "0.2.5" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", ] +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "dyn-clone" version = "1.0.20" @@ -607,77 +789,80 @@ checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" [[package]] name = "ear" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bc48a3976de4a3c2f6661a74836abbd7d458ef10e391fedcf47bcc4c983abc1" +checksum = "579b9ca5846d627287a8760809645fdce2229aa60e93021c359680eb109addcd" dependencies = [ - "base64 0.22.1", + "base64 0.23.1", "ciborium", + "cmw", "cose-rust", "hex", "jsonwebtoken", "lazy_static", "openssl", - "phf 0.11.3", + "phf 0.14.0", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.21", ] [[package]] name = "ear" -version = "0.4.0" -source = "git+https://github.com/veraison/rust-ear?rev=15184e9a#15184e9a47f642eece82f176b5b1802ab69dbc25" +version = "0.6.0" +source = "git+https://github.com/veraison/rust-ear?rev=5dfe47d#5dfe47d4d81c0d8db5e2ba70679021acf9de1e16" dependencies = [ - "base64 0.22.1", + "base64 0.23.1", "ciborium", + "cmw", "cose-rust", "hex", "jsonwebtoken", "lazy_static", "openssl", - "phf 0.13.1", + "phf 0.14.0", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.21", ] [[package]] name = "ecdsa" -version = "0.16.9" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +checksum = "c0681a4fc24c767085329728d8dfba959af91228aa4610cca4f8ce317ba46ae0" dependencies = [ "der", "digest", "elliptic-curve", "rfc6979", - "signature", + "signature 3.0.0", "spki", + "zeroize", ] [[package]] name = "either" -version = "1.15.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34" [[package]] name = "elliptic-curve" -version = "0.13.8" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +checksum = "9d65aa39b3a5c1c9c1b745c9a019234bb7a21b77abcb4f4d266d706e2d577d65" dependencies = [ "base16ct", "crypto-bigint", + "crypto-common", "digest", "ff", - "generic-array", "group", - "hkdf", + "hybrid-array", "pem-rfc7468", "pkcs8", - "rand_core 0.6.4", + "rand_core 0.10.1", "sec1", "subtle", "zeroize", @@ -692,11 +877,37 @@ dependencies = [ "serde", ] +[[package]] +name = "embedded-io" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + +[[package]] +name = "encoding_rs" +version = "0.8.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e985e0451871ad22fb8d2b6b076e2028a502a0d3950998c2c5c0a4f9b5d9679" +dependencies = [ + "cfg-if", + "core_detect", + "multiversion_no_op", + "rustversion", + "scopeguard", + "simdutf8", +] + [[package]] name = "env_filter" -version = "0.1.3" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" +checksum = "900d271a03799a1ee8d1ca9b19893b48ca674a9284fefcfb85f05e74ed314217" dependencies = [ "log", "regex", @@ -704,9 +915,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.8" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" +checksum = "de671bd27a75a797dc9ae289ba1e77276e75e2026408aab65185384e2d5cd3f6" dependencies = [ "anstream", "anstyle", @@ -721,11 +932,21 @@ 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 = "fancy-regex" -version = "0.14.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e24cb5a94bcae1e5408b0effca5cd7172ea3c5755049c5f3af4cd283a165298" +checksum = "e1e1dacd0d2082dfcf1351c4bdd566bbe89a2b263235a2b50058f1e130a47277" dependencies = [ "bit-set", "regex-automata", @@ -734,25 +955,37 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.3.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" [[package]] name = "ff" -version = "0.13.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +checksum = "a1f686ab92a9fb0eaf188f6c6c87b89490baa6fdb0db4544ba4dc47f7942489f" dependencies = [ - "rand_core 0.6.4", + "rand_core 0.10.1", "subtle", ] +[[package]] +name = "fiat-crypto" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64cd1e32ddd350061ae6edb1b082d7c54915b5c672c389143b9a63403a109f24" + +[[package]] +name = "find-msvc-tools" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aedcfb3409746eddb02b9e19ebda1c3394f759a152e48ee875a0844d1b955484" + [[package]] name = "fluent-uri" -version = "0.3.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1918b65d96df47d3591bed19c5cca17e3fa5d0707318e4b5ef2eae01764df7e5" +checksum = "bc74ac4d8359ae70623506d512209619e5cf8f347124910440dbc221714b328e" dependencies = [ "borrow-or-share", "ref-cast", @@ -765,6 +998,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + [[package]] name = "foreign-types" version = "0.3.2" @@ -782,78 +1021,166 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ "percent-encoding", ] [[package]] name = "fraction" -version = "0.15.3" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f158e3ff0a1b334408dc9fb811cd99b446986f4d8b741bb08f9df1604085ae7" +checksum = "e076045bb43dac435333ed5f04caf35c7463631d0dae2deb2638d94dd0a5b872" dependencies = [ "lazy_static", "num", ] [[package]] -name = "generic-array" -version = "0.14.7" +name = "fs_extra" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", - "zeroize", -] +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" [[package]] -name = "getrandom" -version = "0.2.15" +name = "futures-channel" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", - "wasm-bindgen", + "futures-core", + "futures-sink", ] [[package]] -name = "getrandom" -version = "0.3.2" +name = "futures-core" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" -dependencies = [ - "cfg-if", - "libc", - "r-efi", - "wasi 0.14.2+wasi-0.2.4", -] +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" [[package]] -name = "group" -version = "0.13.0" +name = "futures-io" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" -dependencies = [ - "ff", - "rand_core 0.6.4", +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" + +[[package]] +name = "futures-sink" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" + +[[package]] +name = "futures-task" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" + +[[package]] +name = "futures-util" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" +dependencies = [ + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "slab", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[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 = "globset" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07c34a9410465b45bd9787443bc7370f37735bad04b0f0cd57ff1a3186c98988" +dependencies = [ + "aho-corasick", + "bstr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "group" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fd1a1c7a5206c5b7a3f5a0d7ccd3ff85d0c8f5133d62a02680255b0004af5f4" +dependencies = [ + "ff", + "rand_core 0.10.1", "subtle", ] +[[package]] +name = "h2" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef8e5e5a340588f4452631496976cf8636d4a7ecf600239fdc27615d2530bc16" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap 2.14.2", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "half" -version = "2.5.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7db2ff139bba50379da6aa0766b52fdcb62cb5b263009b09ed58ba604e14bbd1" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" dependencies = [ "cfg-if", "crunchy", + "zerocopy", ] [[package]] @@ -864,9 +1191,14 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] [[package]] name = "heck" @@ -890,28 +1222,147 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] -name = "hkdf" -version = "0.12.4" +name = "hmac" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" dependencies = [ - "hmac", + "digest", ] [[package]] -name = "hmac" -version = "0.12.1" +name = "http" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0" dependencies = [ - "digest", + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23169fe34a5fbcdd3f3862e78fb9b6fccd5f02a6dc6f732547005d45631ce71c" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "hybrid-array" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27f864f10dfb56725ce5ce5472bc52252c8f93a4ab86327122cebf62c5f59a17" +dependencies = [ + "subtle", + "typenum", + "zeroize", +] + +[[package]] +name = "hyper" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b501faa50e7a26c3d3560ca625132f4078a17771f4810baf70475ae48cbe43" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfa8e654703247911e29c23fbeaa261834bd9bb74efba2f9acddc37bfb127f53" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "tokio", + "tokio-rustls", + "tower-service", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddc03d96684f9226b8a787cdb71488417b53ab5ea8fdb1dac946cb9431cc8bff" +dependencies = [ + "base64 0.23.1", + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "httparse", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "system-configuration", + "tokio", + "tower-service", + "tracing", + "windows-registry", ] [[package]] name = "iana-time-zone" -version = "0.1.63" +version = "0.1.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -933,21 +1384,23 @@ dependencies = [ [[package]] name = "icu_collections" -version = "1.5.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +checksum = "fa68d21081c4a05d5a901a1c62add574c77048b6a1c67be3b50ce0b60d4ca513" dependencies = [ "displaydoc", + "potential_utf", + "utf8_iter", "yoke", "zerofrom", "zerovec", ] [[package]] -name = "icu_locid" -version = "1.5.0" +name = "icu_locale_core" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +checksum = "d56e28588da92eee5c3201a6eff33fabdd49b62269c8938d4ff050ce4d900deb" dependencies = [ "displaydoc", "litemap", @@ -956,99 +1409,62 @@ dependencies = [ "zerovec", ] -[[package]] -name = "icu_locid_transform" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_locid_transform_data", - "icu_provider", - "tinystr", - "zerovec", -] - -[[package]] -name = "icu_locid_transform_data" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d" - [[package]] name = "icu_normalizer" -version = "1.5.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +checksum = "12f9cf5f235641ed274641dd81c3f28d870e276763d0797aeeab72317b1c646f" dependencies = [ - "displaydoc", "icu_collections", "icu_normalizer_data", "icu_properties", "icu_provider", "smallvec", - "utf16_iter", - "utf8_iter", - "write16", "zerovec", ] [[package]] name = "icu_normalizer_data" -version = "1.5.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7" +checksum = "1563da1ed3e0b3bf3d74c9b85917ac9c56464d2f57242270c09c9e752f8021a0" [[package]] name = "icu_properties" -version = "1.5.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +checksum = "7e7ca276ad3145661a65914e6daf131ca5120cd3dcee8f8f3214b8875184a148" dependencies = [ "displaydoc", "icu_collections", - "icu_locid_transform", + "icu_locale_core", "icu_properties_data", "icu_provider", - "tinystr", + "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" -version = "1.5.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2" +checksum = "e590f038c1464a96894fd6d10127e90a8be4509f56ff7ecef851b15cee0b7caa" [[package]] name = "icu_provider" -version = "1.5.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +checksum = "d27bbb9d3abbefac45d55f647c9de1d44aafcd1186eb91879afef17c396c3e73" dependencies = [ "displaydoc", - "icu_locid", - "icu_provider_macros", - "stable_deref_trait", - "tinystr", + "icu_locale_core", "writeable", "yoke", "zerofrom", + "zerotrie", "zerovec", ] -[[package]] -name = "icu_provider_macros" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "ident_case" version = "1.0.1" @@ -1057,9 +1473,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ "idna_adapter", "smallvec", @@ -1068,9 +1484,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.0" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" dependencies = [ "icu_normalizer", "icu_properties", @@ -1089,107 +1505,171 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.8.0" +version = "2.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" dependencies = [ "equivalent", - "hashbrown 0.15.2", + "hashbrown 0.17.1", "serde", + "serde_core", ] [[package]] -name = "is_terminal_polyfill" -version = "1.70.1" +name = "ipnet" +version = "2.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +checksum = "791930b43c0d5973160d90a8f3894509f2b273430f5c5c73b668636d0287c5c0" [[package]] -name = "itertools" -version = "0.11.0" +name = "iri-string" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +checksum = "1663ee7d8cf2900cc1414b1e1eec9f348d6eaa3bcab07579f4726a4b8499f447" dependencies = [ - "either", + "memchr", + "serde", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + [[package]] name = "itoa" -version = "1.0.15" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jiff" -version = "0.2.15" +version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49" +checksum = "0ab1baf72f08796de0260609515130699b890ac25f30e610ad894bc5856cafdb" dependencies = [ + "defmt", + "jiff-core", "jiff-static", + "jiff-tzdb-platform", "log", "portable-atomic", "portable-atomic-util", - "serde", + "serde_core", + "windows-link", +] + +[[package]] +name = "jiff-core" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e52fe76043ccecc9005d2305ebaadf7d7fc0cc89ca6baa10a94d6bc68c7128c" +dependencies = [ + "defmt", + "log", ] [[package]] name = "jiff-static" -version = "0.2.15" +version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" +checksum = "378268a1116ad67ae6228701118ac9f491d78fda38a40a1f1a9e1348de6f7212" dependencies = [ + "jiff-core", "proc-macro2", "quote", - "syn", + "syn 2.0.119", +] + +[[package]] +name = "jiff-tzdb" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "142bd39932ad231f10513df9ab62661fead8719872150b7ad02a2df79f4e141e" + +[[package]] +name = "jiff-tzdb-platform" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" +dependencies = [ + "jiff-tzdb", +] + +[[package]] +name = "jobserver" +version = "0.1.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" +dependencies = [ + "getrandom 0.4.3", + "libc", ] [[package]] name = "js-sys" -version = "0.3.77" +version = "0.3.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +checksum = "7883d941dae510fb2d978fc3fe018c71c9e2892fd38854de3e8b92c2e5ad9cc5" dependencies = [ - "once_cell", + "cfg-if", + "futures-util", "wasm-bindgen", ] [[package]] name = "jsonschema" -version = "0.29.1" +version = "0.47.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "161c33c3ec738cfea3288c5c53dfcdb32fd4fc2954de86ea06f71b5a1a40bfcd" +checksum = "281c43ff06dcb331e9356d30e38853d559ce3d0a3f693e0b0e102667dec14fb1" dependencies = [ "ahash", - "base64 0.22.1", "bytecount", + "data-encoding", "email_address", "fancy-regex", "fraction", + "getrandom 0.3.4", "idna", "itoa", + "jsonschema-regex", "num-cmp", - "once_cell", + "num-traits", "percent-encoding", "referencing", - "regex-syntax", + "regex", "serde", "serde_json", + "unicode-general-category", "uuid-simd", ] +[[package]] +name = "jsonschema-regex" +version = "0.47.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee0b351864e7ffbc5db9273daf7fa1b4d5177b0946713d667ca571b83c0b4045" +dependencies = [ + "regex-syntax", +] + [[package]] name = "jsonwebtoken" -version = "9.3.1" +version = "11.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde" +checksum = "e75fe14a82d81e5f5af639997db37d8b96045938a7ac6ab18cdbe1c7467e05e1" dependencies = [ + "aws-lc-rs", "base64 0.22.1", + "getrandom 0.2.17", "js-sys", - "pem", - "ring", + "pem 3.0.6", "serde", "serde_json", + "signature 2.2.0", "simple_asn1", + "zeroize", ] [[package]] @@ -1200,53 +1680,116 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.171" +version = "0.2.189" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "litemap" -version = "0.7.5" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" +checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae" [[package]] name = "lock_api" -version = "0.4.12" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.27" +version = "0.4.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" + +[[package]] +name = "lru" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef9ac18847474e638e3702b76c65d4eb93428471a74778ef0f1be711717f89b5" + +[[package]] +name = "memchr" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" [[package]] -name = "md-5" -version = "0.10.6" +name = "micromap" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +checksum = "c2a86d3146ed3995b5913c414f6664344b9617457320782e64f0bb44afd49d74" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "minicbor" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "734daad4ff3b880f23dc2a675dd74553fa8e583367aa7523f96a16e96a516b62" dependencies = [ - "cfg-if", - "digest", + "minicbor-derive", +] + +[[package]] +name = "minicbor" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c12b4033ffaa92fbf9df03df38d19324f52bad130dd223f811734a8006dd2d69" + +[[package]] +name = "minicbor-derive" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512ce2c37128698ea15c99b3518936c78a8b112b92468e7b95b9fa045666ebd8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "minicbor-serde" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80047f75e28e3b38f6ab2ec3c2c7669f6b411fa6f8424e1a90a3fd784b19a3f4" +dependencies = [ + "minicbor 2.3.0", + "serde", ] [[package]] -name = "memchr" -version = "2.7.4" +name = "mio" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "4b18443e9c262bfe8fa82f51666e2642c53393f7e5c27b3e1aeab922cff5b9d8" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.61.2", +] [[package]] -name = "minimal-lexical" -version = "0.2.1" +name = "msvc_spectre_libs" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +checksum = "29e871a9861f3664f18b7e04e9301d4edd55090c2dadb4b1c602e26ab32b1f5b" +dependencies = [ + "cc", +] [[package]] name = "multimap" @@ -1258,13 +1801,26 @@ dependencies = [ ] [[package]] -name = "nom" -version = "7.1.3" +name = "multiversion_no_op" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "743fb55ba31b18fb1ecef6bdc9aa2743314978ac084044301a7eee33fb99a20d" + +[[package]] +name = "native-tls" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +checksum = "465500e14ea162429d264d44189adc38b199b62b1c21eea9f69e4b73cb03bbf2" dependencies = [ - "memchr", - "minimal-lexical", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", ] [[package]] @@ -1273,7 +1829,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" dependencies = [ - "num-bigint", + "num-bigint 0.4.8", "num-complex", "num-integer", "num-iter", @@ -1283,9 +1839,19 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.6" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +checksum = "93e7820bc0a80a0238e650327316f929ba18d5be054b647490a3a6a339f3e7c0" dependencies = [ "num-integer", "num-traits", @@ -1308,26 +1874,25 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.1.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" [[package]] name = "num-integer" -version = "0.1.46" +version = "0.1.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +checksum = "7ce2d95d4b3734dc35aa2f45e1aa22cd416814592a4f9d9205e11affd5b8e10b" dependencies = [ "num-traits", ] [[package]] name = "num-iter" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +checksum = "c92800bd69a1eac91786bcfe9da64a897eb72911b8dc3095decbd07429e8048b" dependencies = [ - "autocfg", "num-integer", "num-traits", ] @@ -1338,7 +1903,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" dependencies = [ - "num-bigint", + "num-bigint 0.4.8", "num-integer", "num-traits", ] @@ -1363,21 +1928,26 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.3" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "openssl" -version = "0.10.75" +version = "0.10.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" +checksum = "77823a27f0babb03091cb9ed9ef80af3b39dbc82f97e8fa530374b7dafd87a45" dependencies = [ - "bitflags", + "bitflags 2.13.2", "cfg-if", "foreign-types", "libc", - "once_cell", "openssl-macros", "openssl-sys", ] @@ -1390,23 +1960,29 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] +[[package]] +name = "openssl-probe" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" + [[package]] name = "openssl-src" -version = "300.4.2+3.4.1" +version = "300.6.1+3.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168ce4e058f975fe43e89d9ccf78ca668601887ae736090aacc23ae353c298e2" +checksum = "46eb8fb9fb3b61ce1c0f8a026c4c1a0714d3a9e138e7fbde78753ce2babc3846" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.111" +version = "0.9.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" +checksum = "b47e7e6bb2c38cd930d25a23b40fa52e068c10e85f3e03a7f5ba5aaca5713695" dependencies = [ "cc", "libc", @@ -1423,47 +1999,50 @@ checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" [[package]] name = "p256" -version = "0.13.2" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +checksum = "d2c9239b2dbc807adbbe147e8cf72ea7450c3a0aabe62cb8e75ff4ec22e1f72a" dependencies = [ "ecdsa", "elliptic-curve", + "primefield", "primeorder", "sha2", ] [[package]] name = "p384" -version = "0.13.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6" +checksum = "d17b851e6b3e378ab4ecb07fa2ed23f4d15f075735f8fec9fa1e7bdce5f8301f" dependencies = [ "ecdsa", "elliptic-curve", + "fiat-crypto", + "primefield", "primeorder", "sha2", ] [[package]] name = "p521" -version = "0.13.3" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fc9e2161f1f215afdfce23677034ae137bbd45016a880c2eb3ba8eb95f085b2" +checksum = "4ad64cc32c2dc466317c12ee5853e61f159f9eab1fe7efade0395dc2e7b43449" dependencies = [ "base16ct", "ecdsa", "elliptic-curve", + "primefield", "primeorder", - "rand_core 0.6.4", "sha2", ] [[package]] name = "parking_lot" -version = "0.12.3" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", @@ -1471,143 +2050,109 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.10" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets", + "windows-link", ] [[package]] -name = "parse-zoneinfo" -version = "0.3.1" +name = "pem" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f2a05b18d44e2957b88f96ba460715e295bc1d7510468a2f3d3b44535d26c24" +checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be" dependencies = [ - "regex", + "base64 0.22.1", + "serde_core", ] [[package]] name = "pem" -version = "3.0.6" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be" +checksum = "d354a98a3d1251555de99e8fdd8afda05573c31b82f59063a7b0a29b5527f120" dependencies = [ - "base64 0.22.1", + "base64 0.23.1", "serde_core", ] [[package]] name = "pem-rfc7468" -version = "0.7.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +checksum = "a6305423e0e7738146434843d1694d621cce767262b2a86910beab705e4493d9" dependencies = [ "base64ct", ] [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "phf" -version = "0.11.3" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +checksum = "913273894cec178f401a31ec4b656318d95473527be05c0752cc41cdc32be8b7" dependencies = [ - "phf_macros 0.11.3", - "phf_shared 0.11.3", - "serde", + "phf_shared 0.12.1", ] [[package]] name = "phf" -version = "0.13.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" +checksum = "010378780309880b08997fae13be7834dba947d36393bd372f2b1556deb2a2f6" dependencies = [ - "phf_macros 0.13.1", - "phf_shared 0.13.1", + "phf_macros", + "phf_shared 0.14.0", "serde", ] -[[package]] -name = "phf_codegen" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" -dependencies = [ - "phf_generator 0.11.3", - "phf_shared 0.11.3", -] - -[[package]] -name = "phf_generator" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" -dependencies = [ - "phf_shared 0.11.3", - "rand 0.8.5", -] - [[package]] name = "phf_generator" -version = "0.13.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" +checksum = "aeb62e0959d5a1bebc965f4d15d9e2b7cea002b6b0f5ba8cde6cc26738467100" dependencies = [ "fastrand", - "phf_shared 0.13.1", -] - -[[package]] -name = "phf_macros" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" -dependencies = [ - "phf_generator 0.11.3", - "phf_shared 0.11.3", - "proc-macro2", - "quote", - "syn", + "phf_shared 0.14.0", ] [[package]] name = "phf_macros" -version = "0.13.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef" +checksum = "5fa8d0ca26d424d27630da600c6624696e7dec8bf7b3b492b383c5dc49e5e085" dependencies = [ - "phf_generator 0.13.1", - "phf_shared 0.13.1", + "phf_generator", + "phf_shared 0.14.0", "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "phf_shared" -version = "0.11.3" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +checksum = "06005508882fb681fd97892ecff4b7fd0fee13ef1aa569f8695dae7ab9099981" dependencies = [ "siphasher", ] [[package]] name = "phf_shared" -version = "0.13.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" +checksum = "c6fd9027e2d9319be6349febd1db4e8d02aa544921200c9b777720ac34a3aa89" dependencies = [ "siphasher", ] @@ -1625,9 +2170,9 @@ dependencies = [ [[package]] name = "picky-asn1-der" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b491eb61603cba1ad5c6be0269883538f8d74136c35e3641a840fb0fbcd41efc" +checksum = "d413165e4bf7f808b9a27cbaba657657a2921f0965db833f488c4d4be96dcd2e" dependencies = [ "picky-asn1", "serde", @@ -1636,9 +2181,9 @@ dependencies = [ [[package]] name = "picky-asn1-x509" -version = "0.15.2" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c97cd14d567a17755910fa8718277baf39d08682a980b1b1a4b4da7d0bc61a04" +checksum = "859d4117bd1b1dc5646359ee7243c50c5000c0920ea2d1fb120335a2f4c684b8" dependencies = [ "base64 0.22.1", "oid", @@ -1647,11 +2192,17 @@ dependencies = [ "serde", ] +[[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" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +checksum = "451913da69c775a56034ea8d9003d27ee8948e12443eae7c038ba100a4f21cb7" dependencies = [ "der", "spki", @@ -1659,32 +2210,44 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.32" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" + +[[package]] +name = "portable-atomic" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" [[package]] -name = "pori" -version = "0.0.0" +name = "portable-atomic-util" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a63d338dec139f56dacc692ca63ad35a6be6a797442479b55acd611d79e906" +checksum = "10ab3eb7f3becc3a1cbc4f2c6f20267996cfc1a6467a873763411b136a122715" dependencies = [ - "nom", + "portable-atomic", ] [[package]] -name = "portable-atomic" -version = "1.11.1" +name = "postcard" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" +checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24" +dependencies = [ + "cobs", + "embedded-io 0.4.0", + "embedded-io 0.6.1", + "serde", +] [[package]] -name = "portable-atomic-util" -version = "0.2.4" +name = "potential_utf" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +checksum = "d83eb9bc6d8e5cf568e7a1101d60ee05e81ed50ea106026f3d18deeb046d7661" dependencies = [ - "portable-atomic", + "zerovec", ] [[package]] @@ -1699,62 +2262,86 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "zerocopy 0.8.24", + "zerocopy", +] + +[[package]] +name = "primefield" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c555a6e4eb7d4e158fcb028c835c3b8642206ddc279b5c6b202ef9a8bdb592f4" +dependencies = [ + "crypto-bigint", + "crypto-common", + "ff", + "rand_core 0.10.1", + "subtle", + "zeroize", ] [[package]] name = "primeorder" -version = "0.13.6" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +checksum = "5c9f42978c78a00e3d68f69fc03e57a234debae69da4020a4fb588fcdcd07b06" dependencies = [ "elliptic-curve", + "once_cell", + "primefield", + "serdect", + "wnaf", ] [[package]] name = "proc-macro2" -version = "1.0.101" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.40" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" dependencies = [ "proc-macro2", ] [[package]] name = "r-efi" -version = "5.2.0" +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 = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" [[package]] name = "rand" -version = "0.8.5" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "e058c7de0b26af77780c769414d6257830bb240f3c38477dbc2c16e5f54d6d4c" dependencies = [ "libc", - "rand_chacha 0.3.1", + "rand_chacha", "rand_core 0.6.4", ] [[package]] name = "rand" -version = "0.9.0" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" +checksum = "65c9fb96cbc91e3478eaae79a69fcd3f1ae4ad052e471fe6732fff548984b4af" dependencies = [ - "rand_chacha 0.9.0", - "rand_core 0.9.3", - "zerocopy 0.8.24", + "chacha20", + "getrandom 0.4.3", + "rand_core 0.10.1", ] [[package]] @@ -1767,72 +2354,62 @@ dependencies = [ "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.3", -] - [[package]] name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.2.17", ] [[package]] name = "rand_core" -version = "0.9.3" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" -dependencies = [ - "getrandom 0.3.2", -] +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" [[package]] name = "redox_syscall" -version = "0.5.10" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags", + "bitflags 2.13.2", ] [[package]] name = "ref-cast" -version = "1.0.24" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf" +checksum = "7e440fb4e4b4147295338efb76001ab9e4efc0e5839df2c47fc5ac2381d365c3" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.24" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" +checksum = "92ecd8964f8453721699a1ed72037b0db49ce2f5a5138486ee89bed6f67cdf3a" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", ] [[package]] name = "referencing" -version = "0.29.1" +version = "0.47.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40a64b3a635fad9000648b4d8a59c8710c523ab61a23d392a7d91d47683f5adc" +checksum = "348e860aeb0b7bd035778fd11dd9cd5290d32e4aed3b8f2274a00287a9fd362b" dependencies = [ "ahash", "fluent-uri", - "once_cell", + "getrandom 0.3.4", + "hashbrown 0.17.1", + "itoa", + "micromap", "parking_lot", "percent-encoding", "serde_json", @@ -1840,9 +2417,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.1" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" dependencies = [ "aho-corasick", "memchr", @@ -1852,9 +2429,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.9" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" dependencies = [ "aho-corasick", "memchr", @@ -1863,47 +2440,93 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.5" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] name = "regorus" -version = "0.4.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf70615014ce5c89fe427197fd9b52e6506916838b449e80ee141adc43adec6b" +checksum = "3cc4dc91481b1d4001ba7f2e81f7faf674142e0ac36d37d79e5f02764d06571e" dependencies = [ "anyhow", "chrono", "chrono-tz", - "constant_time_eq", "data-encoding", - "hex", - "hmac", + "globset", + "indexmap 2.14.2", + "ipnet", "jsonschema", "lazy_static", - "md-5", - "rand 0.9.0", + "lru", + "msvc_spectre_libs", + "num-bigint 0.5.1", + "num-traits", + "parking_lot", + "postcard", + "rand 0.10.3", "regex", - "scientific", "semver", "serde", "serde_json", "serde_yaml", - "sha2", + "spin", + "thiserror 2.0.21", "url", "uuid", - "wax", +] + +[[package]] +name = "reqwest" +version = "0.12.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +dependencies = [ + "base64 0.22.1", + "bytes", + "encoding_rs", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-tls", + "hyper-util", + "js-sys", + "log", + "mime", + "native-tls", + "percent-encoding", + "pin-project-lite", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-native-tls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", ] [[package]] name = "rfc6979" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +checksum = "b4a459cddafb3fe76b31fd8f1108007566c40301feb64dc7b54656eb7388172b" dependencies = [ + "crypto-bigint", "hmac", - "subtle", ] [[package]] @@ -1914,23 +2537,87 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.15", + "getrandom 0.2.17", "libc", - "untrusted", + "untrusted 0.9.0", "windows-sys 0.52.0", ] +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891efababe418670775f199f0d233d84843c227a0949a883ce15b37c78d6629d" +dependencies = [ + "bitflags 2.13.2", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls" +version = "0.23.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d41d731c7d2f962d1ccc364cec258de3c0e93b38c2fb3ba97ac74513048d634" +dependencies = [ + "once_cell", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96" +dependencies = [ + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3c3cf1d8b1e7d4927e2d154c3fcb02979afb9939629c62cd9048d4f07b60ac2" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted 0.9.0", +] + [[package]] name = "rustversion" -version = "1.0.20" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" [[package]] name = "ryu" -version = "1.0.20" +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 = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" +dependencies = [ + "windows-sys 0.61.2", +] [[package]] name = "schemars" @@ -1946,9 +2633,9 @@ dependencies = [ [[package]] name = "schemars" -version = "1.0.4" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82d20c4491bc164fa2f6c5d44565947a52ad80b9505d8e36f8d54c27c739fcd0" +checksum = "687274d293b6cdc6e73e0fee520bf2049650090d7164f87672d212a3c530cf4a" dependencies = [ "dyn-clone", "ref-cast", @@ -1956,26 +2643,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "scientific" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38a4b339a8de779ecb098a772ecbba2ace74e23ed959a5b4f30631d8bf1799a8" -dependencies = [ - "scientific-macro", -] - -[[package]] -name = "scientific-macro" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2ee4885492bb655bfa05d039cd9163eb8fe9f79ddebf00ca23a1637510c2fd2" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "scopeguard" version = "1.2.0" @@ -1984,29 +2651,52 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sec1" -version = "0.7.3" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +checksum = "d56d437c2f19203ce5f7122e507831de96f3d2d4d3be5af44a0b0a09d8a80e4d" dependencies = [ "base16ct", + "ctutils", "der", - "generic-array", - "pkcs8", + "hybrid-array", "subtle", "zeroize", ] +[[package]] +name = "security-framework" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" +dependencies = [ + "bitflags 2.13.2", + "core-foundation 0.10.1", + "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.26" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" [[package]] name = "serde" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" dependencies = [ "serde_core", "serde_derive", @@ -2024,50 +2714,64 @@ dependencies = [ [[package]] name = "serde_core" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", ] [[package]] name = "serde_json" -version = "1.0.145" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" dependencies = [ "itoa", "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", "ryu", "serde", - "serde_core", ] [[package]] name = "serde_with" -version = "3.15.0" +version = "3.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6093cd8c01b25262b84927e0f7151692158fab02d961e04c979d3903eba7ecc5" +checksum = "df9adc193c780ef8f159aee8b61e2d5801aaa555e6eb0947fe45530ec506296f" dependencies = [ - "base64 0.22.1", + "base64 0.23.1", + "bs58", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.8.0", + "indexmap 2.14.2", + "jiff", "schemars 0.9.0", - "schemars 1.0.4", + "schemars 1.2.2", "serde_core", "serde_json", "serde_with_macros", @@ -2076,14 +2780,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.15.0" +version = "3.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7e6c180db0816026a61afa1cff5344fb7ebded7e4d3062772179f2501481c27" +checksum = "3e17bbc68e28663bbbb90df47e058aa7eda4fb445b89fe70457bb94fbccf6e49" dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 3.0.6", ] [[package]] @@ -2092,18 +2796,28 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.8.0", + "indexmap 2.14.2", "itoa", "ryu", "serde", "unsafe-libyaml", ] +[[package]] +name = "serdect" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66cf8fedced2fcf12406bcb34223dffb92eaf34908ede12fed414c82b7f00b3e" +dependencies = [ + "base16ct", + "serde", +] + [[package]] name = "sha2" -version = "0.10.8" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" dependencies = [ "cfg-if", "cpufeatures", @@ -2112,9 +2826,9 @@ dependencies = [ [[package]] name = "shlex" -version = "1.3.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] name = "signature" @@ -2122,39 +2836,76 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ - "digest", "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", + "rand_core 0.10.1", +] + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + [[package]] name = "simple_asn1" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb" +checksum = "0d585997b0ac10be3c5ee635f1bab02d512760d14b7c468801ac8a01d9ae5f1d" dependencies = [ - "num-bigint", + "num-bigint 0.4.8", "num-traits", - "thiserror 2.0.16", + "thiserror 2.0.21", "time", ] [[package]] name = "siphasher" -version = "1.0.1" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33f4fe9184a62d842c9ef383018f3306d8ba224fd9d836f56d7288308847c256" + +[[package]] +name = "slab" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" -version = "1.14.0" +version = "1.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9395f0f0eee849a9b707b2f06bb92a6a422090e2123bb2ef8e87a0e61892a8e" + +[[package]] +name = "socket2" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "spin" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" +checksum = "0134f9043ed38b087ac4f7d4af44c79e2c9e5094421fe3164f435ce585953b10" [[package]] name = "spki" -version = "0.7.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +checksum = "1d9efca8738c78ee9484207732f728b1ef517bbb1833d6fc0879ca898a522f6f" dependencies = [ "base64ct", "der", @@ -2162,9 +2913,9 @@ dependencies = [ [[package]] name = "stable_deref_trait" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "strsim" @@ -2172,6 +2923,24 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "strum" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd" + +[[package]] +name = "strum_macros" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "subtle" version = "2.6.1" @@ -2180,56 +2949,110 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.100" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + [[package]] name = "synstructure" -version = "0.13.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +checksum = "901704edd0dfe137f1987838ee4f259e4e063c31371bdb423f7ae38ec6f77f02" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", +] + +[[package]] +name = "system-configuration" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" +dependencies = [ + "bitflags 2.13.2", + "core-foundation 0.9.4", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tempfile" +version = "3.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" +dependencies = [ + "fastrand", + "getrandom 0.4.3", + "once_cell", + "rustix", + "windows-sys 0.61.2", ] [[package]] name = "test-case" -version = "3.3.1" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb2550dd13afcd286853192af8601920d959b14c401fcece38071d53bf0768a8" +checksum = "124953e7f67cb0b2fcfb87e899e4ae5a64fb68e2e160767933cc67b646fb0042" dependencies = [ "test-case-macros", ] [[package]] name = "test-case-core" -version = "3.3.1" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adcb7fd841cd518e279be3d5a3eb0636409487998a4aff22f3de87b81e88384f" +checksum = "bd097615b407247e102046ba34426bb594923ab3554cf0f3cdfed050f1a5a3e8" dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn", + "syn 3.0.6", ] [[package]] name = "test-case-macros" -version = "3.3.1" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" +checksum = "f4ce35ece947bccac166e1ded639133827a953f69a48ba134d17f91108333082" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", "test-case-core", ] @@ -2244,11 +3067,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.16" +version = "2.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0" +checksum = "09e52cb86a36cede5cb101bf8908837b3e4c6e5e59fe7fd85c23fb56200d189e" dependencies = [ - "thiserror-impl 2.0.16", + "thiserror-impl 2.0.21", ] [[package]] @@ -2259,46 +3082,45 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "thiserror-impl" -version = "2.0.16" +version = "2.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960" +checksum = "fe5197923287db20a58125f0bc85c062f7f2c892de97b18c356f9efb14b28524" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", ] [[package]] name = "time" -version = "0.3.41" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134" dependencies = [ "deranged", - "itoa", "num-conv", "powerfmt", - "serde", + "serde_core", "time-core", "time-macros", ] [[package]] name = "time-core" -version = "0.1.4" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" [[package]] name = "time-macros" -version = "0.2.22" +version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" +checksum = "7e689342a48d2ea927c87ea50cabf8594854bf940e9310208848d680d668ed85" dependencies = [ "num-conv", "time-core", @@ -2306,31 +3128,155 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.7.6" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +checksum = "b1e27c91459209c2986af3dcf603a5a74a4368754ce37414f59acc971167f643" dependencies = [ "displaydoc", "zerovec", ] +[[package]] +name = "tinyvec" +version = "1.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd3ca314f692efd6c868f8408f53fe444634a845f96c028b97d35f6a1f79f0ee" + +[[package]] +name = "tokio" +version = "1.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed" +dependencies = [ + "bytes", + "libc", + "mio", + "pin-project-lite", + "socket2", + "windows-sys 0.61.2", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9cc2678c2cdd569ef8215e2afd7954ada2ae20b4fdd2c5fe6139a3b02d105db" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "494815d09bf52b5548659851081238f0ca39ff638363907596da739561c62c52" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "libc", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" +dependencies = [ + "bitflags 2.13.2", + "bytes", + "futures-util", + "http", + "http-body", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", + "url", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[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 = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + [[package]] name = "typenum" -version = "1.18.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" [[package]] -name = "unicode-ident" -version = "1.0.18" +name = "unicode-general-category" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "0b993bddc193ae5bd0d623b49ec06ac3e9312875fdae725a975c51db1cc1677f" [[package]] -name = "unicode-xid" -version = "0.2.6" +name = "unicode-ident" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954" [[package]] name = "unsafe-libyaml" @@ -2338,6 +3284,12 @@ 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" @@ -2346,21 +3298,16 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.4" +version = "2.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" dependencies = [ "form_urlencoded", "idna", "percent-encoding", + "serde", ] -[[package]] -name = "utf16_iter" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" - [[package]] name = "utf8_iter" version = "1.0.4" @@ -2375,12 +3322,14 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.16.0" +version = "1.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9" +checksum = "2ef6dac1e96601b4fb3acccccff2139741fcb757cb9a36089bf5be91cfb285ce" dependencies = [ - "getrandom 0.3.2", - "rand 0.9.0", + "getrandom 0.4.3", + "js-sys", + "rand 0.10.3", + "wasm-bindgen", ] [[package]] @@ -2390,7 +3339,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b082222b4f6619906941c17eb2297fff4c2fb96cb60164170522942a200bd8" dependencies = [ "outref", - "uuid", "vsimd", ] @@ -2413,51 +3361,58 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" [[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +name = "want" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] [[package]] name = "wasi" -version = "0.14.2+wasi-0.2.4" +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 = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" dependencies = [ - "wit-bindgen-rt", + "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.100" +version = "0.2.129" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +checksum = "9bb54f33acc68fd454578d9820b0bde1a1a3d17aa17bb7b6595806d02886d409" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", + "wasm-bindgen-shared", ] [[package]] -name = "wasm-bindgen-backend" -version = "0.2.100" +name = "wasm-bindgen-futures" +version = "0.4.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +checksum = "3cbab34de2d982e9b48e18d216d04c4a6f641066ff19ffb699980f591ee3610e" dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", + "js-sys", + "tokio", + "wasm-bindgen", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.100" +version = "0.2.129" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "2e29d0c35b16e224a7eeb5cd2d25e3e1968fbd65604117b44d3b789d00ee8535" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2465,45 +3420,41 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.100" +version = "0.2.129" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "6f501a8bc3719dba86ef8ae4728879c08001bea749eb1333ac5b91e040e2a6b7" dependencies = [ + "bumpalo", "proc-macro2", "quote", - "syn", - "wasm-bindgen-backend", + "syn 3.0.6", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.100" +version = "0.2.129" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "23f0c9c52aa7cd7d77769a4cfe2a9adb1b331f489a41d912ce14513d5ab995c6" dependencies = [ "unicode-ident", ] [[package]] -name = "wax" -version = "0.6.0" +name = "web-sys" +version = "0.3.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d12a78aa0bab22d2f26ed1a96df7ab58e8a93506a3e20adb47c51a93b4e1357" +checksum = "88261b9deccee56594c11a3460c462c41f58d148598fe70ad77070126a68aba4" dependencies = [ - "const_format", - "itertools", - "nom", - "pori", - "regex", - "thiserror 1.0.69", + "js-sys", + "wasm-bindgen", ] [[package]] name = "windows-core" -version = "0.61.0" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ "windows-implement", "windows-interface", @@ -2514,46 +3465,57 @@ dependencies = [ [[package]] name = "windows-implement" -version = "0.60.0" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "windows-interface" -version = "0.59.1" +version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "windows-link" -version = "0.1.1" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-registry" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" +checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" +dependencies = [ + "windows-link", + "windows-result", + "windows-strings", +] [[package]] name = "windows-result" -version = "0.3.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ "windows-link", ] [[package]] name = "windows-strings" -version = "0.4.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ "windows-link", ] @@ -2569,11 +3531,11 @@ dependencies = [ [[package]] name = "windows-sys" -version = "0.59.0" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-targets", + "windows-link", ] [[package]] @@ -2641,33 +3603,41 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] -name = "wit-bindgen-rt" -version = "0.39.0" +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "wnaf" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +checksum = "795ca18b3fdb5e62bf982199278341ddcf7ebf7d32e25e212ad05d496e95f6fa" dependencies = [ - "bitflags", + "ff", + "group", + "hybrid-array", + "primefield", ] [[package]] -name = "write16" -version = "1.0.0" +name = "writeable" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" +checksum = "3ad82d2a33cdc9674dc7465672f271e096168fcdbe0f799d9e6db8c5892679dc" [[package]] -name = "writeable" -version = "0.5.5" +name = "xml-rs" +version = "0.8.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" +checksum = "e450f9b2ed1dff33c94c12589a87338689467b9c4f5d8a5710bd09a847d2c8a7" [[package]] name = "yoke" -version = "0.7.5" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" dependencies = [ - "serde", "stable_deref_trait", "yoke-derive", "zerofrom", @@ -2675,88 +3645,93 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.5" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +checksum = "33811428bee40dbceb6d545e95754741d17a6aef9a4849f0fd62e2ba4f412a78" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", "synstructure", ] [[package]] name = "zerocopy" -version = "0.7.35" +version = "0.8.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +checksum = "6df92bf3d9227be3d53173901ddbffac2babc27ae50f397776ffd6dc33f800cb" dependencies = [ - "zerocopy-derive 0.7.35", + "zerocopy-derive", ] [[package]] -name = "zerocopy" -version = "0.8.24" +name = "zerocopy-derive" +version = "0.8.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" +checksum = "ac4f328cf2f05d084e496c3e9c3f33ed0a183656a16e1fcec4d464d8373aec82" dependencies = [ - "zerocopy-derive 0.8.24", + "proc-macro2", + "quote", + "syn 2.0.119", ] [[package]] -name = "zerocopy-derive" -version = "0.7.35" +name = "zerofrom" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" dependencies = [ - "proc-macro2", - "quote", - "syn", + "zerofrom-derive", ] [[package]] -name = "zerocopy-derive" -version = "0.8.24" +name = "zerofrom-derive" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" +checksum = "f75b4683f6c7f45248d4d64056a24298c6281e0993356d7d1b4a1a962ef10d4a" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", + "synstructure", ] [[package]] -name = "zerofrom" -version = "0.1.6" +name = "zeroize" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" dependencies = [ - "zerofrom-derive", + "zeroize_derive", ] [[package]] -name = "zerofrom-derive" -version = "0.1.6" +name = "zeroize_derive" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328" dependencies = [ "proc-macro2", "quote", - "syn", - "synstructure", + "syn 2.0.119", ] [[package]] -name = "zeroize" -version = "1.8.2" +name = "zerotrie" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +checksum = "4ea269c3bd32f0a32c321907a2ae912ba6f4649bb0fc764a15627e99a7095a3f" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] [[package]] name = "zerovec" -version = "0.10.4" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +checksum = "bb0464e17806c1d976d5cba29399c7f08e516e279e2ba493f63123b5fca67dd8" dependencies = [ "yoke", "zerofrom", @@ -2765,11 +3740,17 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.10.3" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +checksum = "34df6fc39dbd26ddc9c10e6a2984476e13acce22e64e4487636ef494369225da" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", ] + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/Cargo.toml b/Cargo.toml index 762fcc5..053aa7d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,30 +18,34 @@ name = "cover-cli" path = "src/bin/main.rs" [dependencies] -anyhow = "1.0.97" -base64 = "0.22.1" -ccatoken = { git = "https://github.com/veraison/rust-ccatoken", rev = "6d5b8db9" } +anyhow = "1.0.104" +base64 = "0.23.1" +ccatoken = { git = "https://github.com/veraison/rust-ccatoken", rev = "c2257a3" } ciborium = "0.2.2" -clap = { version = "4.5.32", features = ["derive"] } -clap-verbosity-flag = "3.0.3" -corim-rs = { git = "https://github.com/veraison/corim-rs", features = ["openssl"] } -cose-rust = { version = "0.1.7", features = ["serde_json"] } -ear = { git = "https://github.com/veraison/rust-ear", rev = "15184e9a" } -env_logger = { version = "0.11.8", features = ["kv"] } -jsonwebtoken = "9.3.1" -log = { version = "0.4.27", features = ["kv", "std"] } -regorus = "0.4.0" -serde = { version = "1.0.219", features = ["derive"] } -serde_json = { version = "1.0.140", features = ["raw_value"] } -pem = "3.0.6" -picky-asn1-der = "0.5.4" -picky-asn1-x509 = "0.15.2" -elliptic-curve = { version = "0.13.8", features = ["arithmetic"] } -p256 = "0.13.2" -p384 = "0.13.1" -p521 = "0.13.3" +clap = { version = "4.6.3", features = ["derive"] } +clap-verbosity-flag = "3.0.4" +cmw = "0.1.2" +corim-rs = { version = "0.2.0", features = ["openssl"] } +cose-rust = { version = "0.1.8", features = ["serde_json"] } +ear = { git = "https://github.com/veraison/rust-ear", rev = "5dfe47d" } +env_logger = { version = "0.11.11", features = ["kv"] } +jsonwebtoken = "11.1.0" +log = { version = "0.4.33", features = ["kv", "std"] } +regorus = "0.11.0" +serde = { version = "1.0.229", features = ["derive"] } +serde_json = { version = "1.0.151", features = ["raw_value"] } +pem = "4.0.0" +picky-asn1-der = "0.5.6" +picky-asn1-x509 = "0.15.4" +elliptic-curve = { version = "0.14.1", features = ["arithmetic"] } +p256 = "0.14.0" +p384 = "0.14.0" +p521 = "0.14.0" +chrono = { version = "0.4", features = ["serde"] } +strum = "0.28.0" +strum_macros = "0.28.0" [dev-dependencies] ciborium = "0.2.2" -serde_json = "1.0.140" +serde_json = "1.0.151" test-case = "3.3.1" diff --git a/README.md b/README.md index 4d8ab4a..3721726 100644 --- a/README.md +++ b/README.md @@ -1,40 +1,45 @@ # cover Cover (COrim VERifier) is an implementation of CoRIM-based verifier as outline in CoRIM draft -spec (rev 8.) Section 9\[[1]\]. It attempts follow the outlined algorithm up to phase 4 (ACS -generation). In lieu of subsequent phases, it uses a Rego-based policy engine for policy +spec (rev 11) Section 8\[[1]\]. It follows the outlined algorithm up to phase 4 (ACS generation). +In lieu of subsequent phases, it uses a Rego-based policy engine for policy evaluation, and generates an attestation result in EAR\[[2]\] format. This implementation is intended as a Proof-of-Concept only. It has the following limitations: + - Arm CCA is the only attestation scheme that is currently implemented. -- Only signed CoRIMs are supported. + - Only basic in-memory implementation of key and CoRIM stores are implemented. The verification flow proceeds as follows. -- CoRIMs are processed by validating their signatures and extracting contained measurements - into the "corim store" as RV (reference values), EV (endorsed values), and EVS (endorsed - values series) relations. +- CoRIMs are processed by validating their signatures for signed CoRIMs and extracting contained + measurements into the "corim store" as RV (reference values), EV (endorsed values) or Key relations. +- Unsigned CoRIM verification is not done and it is assumed that user has already verified the + CoRIMs before passing into the verifier. - The signature on the evidence is verified using a trust anchor obtained from the corim store based on an identifier inside the evidence. This is scheme-specific. For CCA, the instance ID is used. Evidence claims are then extracted as ECT (environment-claims tuple) records. - The evidence ECTs are then matched to the relations in the corim store. This results in the - ACS (appraisal claims set) -- a vector of ECT records containing evidence claims and matched + ACS (appraisal claims set) — a vector of ECT records containing evidence claims and matched reference values and endorsements. - The ACS is used as an input into the policy engine along with scheme-specific policies. Each policy results in an appraisal containing an AR4SI\[[3]\] trust vector. - The appraisals are added to an attestation result in EAR\[[2]\] format. -[1]: https://www.ietf.org/archive/id/draft-ietf-rats-corim-08.html#name-example-verifier-algorithm -[2]: https://www.ietf.org/archive/id/draft-fv-rats-ear-05.html -[3]: https://www.ietf.org/archive/id/draft-ietf-rats-ar4si-09.html +[1]: https://www.ietf.org/archive/id/draft-ietf-rats-corim-11.html#name-reference-verifier +[2]: https://www.ietf.org/archive/id/draft-ietf-rats-ear-04.html +[3]: https://www.ietf.org/archive/id/draft-ietf-rats-ar4si-10.html ## API Verification flow consists of the following components: + - A key store that contains keys that are used to verify signatures on CoRIMs. The key for a CoRIM is looked up from the store based on the `kid` inside the CoRIM. + For unsigned CoRIMs, it is assumed that CoRIM is already verified by user and user provided + pub key is used as verfying authority of the CoRIM. - A CoRIM store that loads endorsements and reference values from CoRIMs. - A scheme that defines how evidence is processed to extract claims, and what policy is applied to create an attestation result. @@ -71,7 +76,7 @@ Verification flow consists of the following components: let verifier = Verifier::new(store, schemes); // load evidence - let evidence = fs::read("test/cca/cca-token-01.cbor").unwrap(); + let evidence = fs::read("test/cca/cca-token-03.cbor").unwrap(); /// appraise evidence and produce the attestation result let result = verifier.verify("cca", evidence.as_slice(), None).unwrap(); @@ -90,9 +95,12 @@ Verification flow consists of the following components: ```bash target/debug/cover-cli --corim-dir test/corim/ \ - --key test/corim/key.pub.pem --pretty test/cca/cca-token-01.cbor \ - --nonce adfadaewafewr32r --output cca-token-01.ear.json + # Public key used to verify signed CoRIM signatures + --key test/corim/key.pub.pem + # For unsigned corim and attest/identity key, this is used as verifying authority + --verifier-key test/corim/key.pub.pem \ + --pretty test/cca/cca-token-03.cbor \ + --nonce adfadaewafewr32r --output cca-token-03.ear.json ``` use `-h` to see the full list of command line arguments. - diff --git a/deny.toml b/deny.toml index b489781..0f2c4f9 100644 --- a/deny.toml +++ b/deny.toml @@ -101,6 +101,9 @@ allow = [ #"Apache-2.0 WITH LLVM-exception", # Considered Copyleft, but permitted in this project "MPL-2.0", + # BlueOak is an OSI approved licence, + # https://opensource.org/license/BlueOak-1.0.0 + "BlueOak-1.0.0", ] # The confidence threshold for detecting a license from license text. # The higher the value, the more closely the license text must be to the diff --git a/src/bin/main.rs b/src/bin/main.rs index 52cdd52..c28db31 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -12,7 +12,8 @@ use base64::{ }; use clap::{ArgAction, Parser}; use clap_verbosity_flag::{InfoLevel, Verbosity}; -use log::{debug, error, info}; +use corim_rs::Corim; +use log::{debug, error, info, warn}; use cover::{ cca::CcaScheme, @@ -40,6 +41,11 @@ struct Cli { #[arg(name = "key", short, long, action = ArgAction::Append)] keys: Vec, + /// Public key of Verifier/user of library in PEM format. This key is used as authority of attest/identity key + /// during internal processing and if unsigned corim is provided then same key is used as authority for CoRIMs. + #[arg(long = "verifier-key")] + verifier_key: String, + /// Path to CoRIM containing data relevant to verification of provided evidence. #[arg(short, long = "corim", action = ArgAction::Append)] corims: Vec, @@ -93,7 +99,6 @@ fn read_key>(path: P) -> Result<(String, Vec)> { 2 => Ok((parts[0].to_string(), parts[1].to_string())), _ => Err(Error::custom("invalid key path")), }?; - let bytes = fs::read(&actual_path).map_err(Error::custom)?; Ok((kid, bytes)) @@ -118,17 +123,35 @@ fn verify(args: &Cli) -> Result<()> { let mut key_store = MemKeyStore::new(); for key_path in &args.keys { - debug!("reading key from {:?}", key_path); + debug!("reading CoRIM verification key from \"{}\"", key_path); let (kid, key) = read_key(key_path)?; key_store.add(kid.as_bytes(), key.as_ref())?; } + debug!("reading user/verfier key from \"{}\"", args.verifier_key); + let (_, verifier_key) = read_key(&args.verifier_key)?; + key_store.add("verifier-key".as_bytes(), &verifier_key)?; + let mut corim_store = MemCorimStore::new(key_store); + let mut corim_loaded = false; + for corim in &args.corims { debug!("loading CoRIM {:?}", corim); let corim_bytes = fs::read(corim).map_err(Error::custom)?; - corim_store.add_bytes(corim_bytes.as_slice())?; + let parsed_corim = Corim::from_cbor(corim_bytes.as_slice())?; + if schemes + .values() + .any(|scheme| scheme.as_ref().supports_corim(&parsed_corim)) + { + corim_store.add(&parsed_corim)?; + corim_loaded = true; + } else { + warn!( + "skipping CoRIM {:?} because it does not match a supported scheme profile or is expired", + corim + ); + } } for dir in &args.corim_dirs { @@ -136,15 +159,31 @@ fn verify(args: &Cli) -> Result<()> { let entry = entry?; match entry.path().extension().and_then(OsStr::to_str) { Some("cbor") | Some("corim") => { - debug!("loading CoRIM {:?}", entry.path()); + info!("loading CoRIM {:?}", entry.path()); let corim_bytes = fs::read(entry.path()).map_err(Error::custom)?; - corim_store.add_bytes(corim_bytes.as_slice())?; + let parsed_corim = Corim::from_cbor(corim_bytes.as_slice())?; + if schemes + .values() + .any(|scheme| scheme.as_ref().supports_corim(&parsed_corim)) + { + corim_store.add(&parsed_corim)?; + corim_loaded = true; + } else { + warn!( + "skipping CoRIM {:?} because it does not match a supported scheme profile or is expired", + entry.path() + ); + }; } Some(_) | None => (), - } + }; } } + if !corim_loaded { + return Err(Error::custom("No valid corim found. Exiting ...")); + } + let nonce = match &args.nonce { Some(encoded) => { let encoded = encoded.trim_end_matches("="); @@ -169,6 +208,10 @@ fn verify(args: &Cli) -> Result<()> { debug!("nonce: {:x?}", nonce); let verifier = Verifier::new(corim_store, schemes); + // Check if evidence format matches with supported schemes. + if verifier.match_evidence(evidence.as_slice()).is_none() { + return Err(Error::custom("evidence format not supported")); + } let result = verifier.verify(&args.scheme, evidence.as_slice(), nonce.as_deref())?; debug!("ACS: {}", serde_json::to_string(&result.acs)?); @@ -191,7 +234,7 @@ fn verify(args: &Cli) -> Result<()> { } }; - info!("writing result to {}", &out_path); + info!("writing result to {}", out_path); let mut out = match args.force { true => File::create(&out_path), diff --git a/src/lib/authority.rs b/src/lib/authority.rs index f546af1..cda8400 100644 --- a/src/lib/authority.rs +++ b/src/lib/authority.rs @@ -36,32 +36,40 @@ fn jwk_public_key_use_to_cose(key_use: jwk::PublicKeyUse) -> Result CoseAlgorithm { +fn jwk_algorithm_to_cose(alg: jwk::KeyAlgorithm) -> Result { match alg { - jwk::KeyAlgorithm::HS256 => CoseAlgorithm::Hmac256_256, - jwk::KeyAlgorithm::HS384 => CoseAlgorithm::Hmac384_384, - jwk::KeyAlgorithm::HS512 => CoseAlgorithm::Hmac512_512, - jwk::KeyAlgorithm::ES256 => CoseAlgorithm::ES256, - jwk::KeyAlgorithm::ES384 => CoseAlgorithm::ES384, - jwk::KeyAlgorithm::RS256 => CoseAlgorithm::RS256, - jwk::KeyAlgorithm::RS384 => CoseAlgorithm::RS384, - jwk::KeyAlgorithm::RS512 => CoseAlgorithm::RS512, - jwk::KeyAlgorithm::PS256 => CoseAlgorithm::PS256, - jwk::KeyAlgorithm::PS384 => CoseAlgorithm::PS384, - jwk::KeyAlgorithm::PS512 => CoseAlgorithm::PS512, - jwk::KeyAlgorithm::EdDSA => CoseAlgorithm::EdDSA, - jwk::KeyAlgorithm::RSA1_5 => CoseAlgorithm::RS1, - jwk::KeyAlgorithm::RSA_OAEP => CoseAlgorithm::RsaesOaepRfc, - jwk::KeyAlgorithm::RSA_OAEP_256 => CoseAlgorithm::RsaesOaepSha256, + jwk::KeyAlgorithm::HS256 => Ok(CoseAlgorithm::Hmac256_256), + jwk::KeyAlgorithm::HS384 => Ok(CoseAlgorithm::Hmac384_384), + jwk::KeyAlgorithm::HS512 => Ok(CoseAlgorithm::Hmac512_512), + jwk::KeyAlgorithm::ES256 => Ok(CoseAlgorithm::ES256), + jwk::KeyAlgorithm::ES384 => Ok(CoseAlgorithm::ES384), + jwk::KeyAlgorithm::RS256 => Ok(CoseAlgorithm::RS256), + jwk::KeyAlgorithm::RS384 => Ok(CoseAlgorithm::RS384), + jwk::KeyAlgorithm::RS512 => Ok(CoseAlgorithm::RS512), + jwk::KeyAlgorithm::PS256 => Ok(CoseAlgorithm::PS256), + jwk::KeyAlgorithm::PS384 => Ok(CoseAlgorithm::PS384), + jwk::KeyAlgorithm::PS512 => Ok(CoseAlgorithm::PS512), + jwk::KeyAlgorithm::EdDSA => Ok(CoseAlgorithm::EdDSA), + jwk::KeyAlgorithm::RSA1_5 => Ok(CoseAlgorithm::RS1), + jwk::KeyAlgorithm::RSA_OAEP => Ok(CoseAlgorithm::RsaesOaepRfc), + jwk::KeyAlgorithm::RSA_OAEP_256 => Ok(CoseAlgorithm::RsaesOaepSha256), + jwk::KeyAlgorithm::UNKNOWN_ALGORITHM => { + Err(Error::Custom(format!("Unknowm algorithm {}", alg))) + } + _ => Err(Error::Custom(format!("unsupported algorithm {}", alg))), } } -fn jwk_ec_curve_to_cose(curve: &jwk::EllipticCurve) -> CoseEllipticCurve { +fn jwk_ec_curve_to_cose(curve: &jwk::EllipticCurve) -> Result { match curve { - jwk::EllipticCurve::P256 => CoseEllipticCurve::P256, - jwk::EllipticCurve::P384 => CoseEllipticCurve::P384, - jwk::EllipticCurve::P521 => CoseEllipticCurve::P521, - jwk::EllipticCurve::Ed25519 => CoseEllipticCurve::Ed25519, + jwk::EllipticCurve::P256 => Ok(CoseEllipticCurve::P256), + jwk::EllipticCurve::P384 => Ok(CoseEllipticCurve::P384), + jwk::EllipticCurve::P521 => Ok(CoseEllipticCurve::P521), + jwk::EllipticCurve::Ed25519 => Ok(CoseEllipticCurve::Ed25519), + _ => Err(Error::Custom(format!( + "unsupported algorithm curve {:?}", + curve + ))), } } @@ -107,13 +115,13 @@ pub fn jwk_to_crypto_key(jwk: jwk::Jwk) -> Result, } if let Some(alg) = &jwk.common.key_algorithm { - cose_key.alg = Some(jwk_algorithm_to_cose(*alg)) + cose_key.alg = Some(jwk_algorithm_to_cose(*alg)?) } match &jwk.algorithm { jwk::AlgorithmParameters::EllipticCurve(ec_params) => { cose_key.kty = CoseKty::Ec2; - cose_key.crv = Some(jwk_ec_curve_to_cose(&ec_params.curve)); + cose_key.crv = Some(jwk_ec_curve_to_cose(&ec_params.curve)?); cose_key.x = Some(Bytes::from( URL_SAFE_NO_PAD .decode(&ec_params.x) @@ -127,7 +135,7 @@ pub fn jwk_to_crypto_key(jwk: jwk::Jwk) -> Result, } jwk::AlgorithmParameters::OctetKeyPair(okp_params) => { cose_key.kty = CoseKty::Okp; - cose_key.crv = Some(jwk_ec_curve_to_cose(&okp_params.curve)); + cose_key.crv = Some(jwk_ec_curve_to_cose(&okp_params.curve)?); cose_key.x = Some(Bytes::from( URL_SAFE_NO_PAD .decode(&okp_params.x) @@ -145,6 +153,7 @@ pub fn jwk_to_crypto_key(jwk: jwk::Jwk) -> Result, jwk::AlgorithmParameters::RSA(_) => { return Err(Error::custom("RSA keys are not supported")); } + _ => todo!(), }; Ok(CryptoKeyTypeChoice::CoseKey(CoseKeyType::from( diff --git a/src/lib/cca/mod.rs b/src/lib/cca/mod.rs index 97537be..4c517b9 100644 --- a/src/lib/cca/mod.rs +++ b/src/lib/cca/mod.rs @@ -1,14 +1,18 @@ +mod profile; +use base64::{Engine as _, engine::general_purpose::STANDARD_NO_PAD}; +pub use profile::CcaCorimProfile; use std::borrow::Cow; use ccatoken::{ store::{Cpak, ITrustAnchorStore, MemoTrustAnchorStore}, - token::{Evidence, Platform, Realm}, + token::{Evidence, PlatformClaims, RealmClaims}, + token::{PLATFORM_PROFILE, PLATFORM_PROFILE_2024, REALM_PROFILE, REALM_PROFILE_2024}, }; use corim_rs::{ CryptoKeyTypeChoice, EnvironmentMap, core::{ - Bytes, Digest, ExtensionValue, HashAlgorithm, RawValueType, RawValueTypeChoice, - TaggedBytes, TaggedUeidType, Text, UeidType, Uri, + Bytes, Digest, HashAlgorithm, RawValueType, RawValueTypeChoice, TaggedBytes, + TaggedUeidType, Text, UeidType, Uri, }, corim::ProfileTypeChoice, triples::{ @@ -19,7 +23,7 @@ use corim_rs::{ use ear::claim::TRUSTWORTHY_INSTANCE; use crate::authority::jwk_to_crypto_key; -use crate::ect::{CmType, Ect, ElementMap}; +use crate::ect::{CmType, Ect, ElementEct, ElementMap}; use crate::policy::Policy; use crate::result::Error; use crate::scheme::Scheme; @@ -48,6 +52,7 @@ pub const LC_DECOMMISSIONED: i64 = 6; /// Architecture](https://www.arm.com/architecture/security-features/arm-confidential-compute-architecture) /// attestation scheme. Evidence is composed of plaform and realm components, each evaluated /// according to its own policy. + #[derive(Debug, Default)] pub struct CcaScheme; @@ -66,6 +71,10 @@ impl Scheme for CcaScheme { "arm-cca".to_string() } + fn get_supported_corim_profiles(&self) -> Vec { + CcaCorimProfile::all() + } + fn match_evidence(&self, evidence: &[u8]) -> bool { Evidence::decode(evidence).is_ok() } @@ -76,13 +85,13 @@ impl Scheme for CcaScheme { .class( ClassMapBuilder::default() .class_id(ClassIdTypeChoice::Bytes( - evidence.platform_claims.impl_id.as_slice().into(), + evidence.platform_claims.impl_id().as_slice().into(), )) .build() .unwrap(), ) .instance(InstanceIdTypeChoice::Ueid(TaggedUeidType::from( - UeidType::try_from(evidence.platform_claims.inst_id.as_slice())?, + UeidType::try_from(evidence.platform_claims.inst_id().as_slice())?, ))) .build() .map_err(Error::custom) @@ -91,24 +100,35 @@ impl Scheme for CcaScheme { fn validate_and_parse_evidence<'a>( &self, evidence: &[u8], - trust_anchor: &CryptoKeyTypeChoice<'a>, + trust_anchors: &[CryptoKeyTypeChoice<'a>], ) -> Result>, Error> { - let key_bytes: Vec = match trust_anchor { - CryptoKeyTypeChoice::Bytes(bytes) => Ok(bytes.into()), + let [trust_anchor] = trust_anchors else { + return Err(Error::custom(format!( + "CCA supports exactly one trust anchor, found {}", + trust_anchors.len() + ))); + }; + + let key: Cow<'_, str> = match trust_anchor { + // As per draft-ydb-rats-cca-endorsements-04, CPAK public key uses the tagged-pkix-base64-key-type + // variant of the $crypto-key-type-choice. + // Key is a SubjectPublicKeyInfo [RFC5280] using the encoding defined in Section 13 of [RFC7468]. CryptoKeyTypeChoice::PkixBase64Key(b64key) => { - let pem_bytes = b64key.as_bytes(); - let jwk_string = crate::util::pem_spki_to_jwk_string(pem_bytes)?; - Ok(jwk_string.into()) + let key_bytes = STANDARD_NO_PAD + .decode(b64key.as_bytes()) + .map_err(Error::custom)?; + Cow::Owned(crate::util::pem_spki_to_jwk_string(&key_bytes)?) + } + _ => { + return Err(Error::custom(format!( + "unsupported trust anchor type: {:?}; CCA requires PKIX base64", + trust_anchor + ))); } - _ => Err(Error::custom(format!( - "invalid trust anchor type: {:?}", - trust_anchor - ))), - }?; - let raw_key = std::str::from_utf8(&key_bytes).map_err(Error::custom)?; + }; let evidence = Evidence::decode(evidence).map_err(Error::custom)?; - let ta_store = create_store(&evidence, raw_key).map_err(Error::custom)?; + let ta_store = create_store(&evidence, key.as_ref())?; cca_to_ects(evidence, ta_store).map_err(Error::custom) } @@ -139,8 +159,8 @@ fn create_store(evidence: &Evidence, key: &str) -> Result( return Err(Error::SignatureValidation); } - let inst_id = evidence.platform_claims.inst_id; - let authority = match ta_store.lookup(&inst_id) { + let inst_id = evidence.platform_claims.inst_id(); + let authority = match ta_store.lookup(inst_id) { None => Err(Error::custom("could not find CPAK")), Some(cpak) => match cpak.pkey { Some(key) => jwk_to_crypto_key(key), @@ -173,42 +193,56 @@ fn cca_to_ects<'a, S: ITrustAnchorStore>( }, }?; - let mut plat_ect = platform_to_ect(&evidence.platform_claims)?; - plat_ect.add_authority(authority.clone()); - - let mut realm_ect = realm_to_ect(&evidence.realm_claims)?; - realm_ect.add_authority(authority); - - Ok(vec![plat_ect, realm_ect]) + Ok(vec![ + platform_to_ect(&evidence.platform_claims, &authority)?, + realm_to_ect(&evidence.realm_claims)?, + ]) } -fn platform_to_ect<'a>(plat: &Platform) -> Result, Error> { - let mut ect = Ect::new(CmType::Evidence); +fn platform_to_ect<'a>( + plat: &PlatformClaims, + cpak_pub: &CryptoKeyTypeChoice<'a>, +) -> Result, Error> { + if !(plat.profile() == PLATFORM_PROFILE || plat.profile() == PLATFORM_PROFILE_2024) { + return Err(Error::custom(format!( + "unsupported EAT platform profile {}", + plat.profile() + ))); + } - ect.set_environment( - EnvironmentMapBuilder::default() - .class( - ClassMapBuilder::default() - .class_id(ClassIdTypeChoice::Bytes(plat.impl_id.as_slice().into())) - .build() - .unwrap(), - ) - .build() - .unwrap(), - ); + let mut ect = ElementEct::new() + .cmtype(CmType::Evidence) + .environment( + EnvironmentMapBuilder::default() + .class( + ClassMapBuilder::default() + .class_id(ClassIdTypeChoice::Bytes(plat.impl_id().as_slice().into())) + .build() + .unwrap(), + ) + // Adding instance id as per transformation function given in + // "A-Corim-profile-for-cca-endorsements" rev-04 draft section 3.1.5.1 + // https://www.ietf.org/archive/id/draft-ydb-rats-cca-endorsements-04.html#figure-15 + .instance(InstanceIdTypeChoice::Ueid(TaggedUeidType::from( + UeidType::try_from(plat.inst_id().as_slice())?, + ))) + .build() + .unwrap(), + ) + .profile(ProfileTypeChoice::Uri(Uri::from(Text::from( + plat.profile().to_string(), + )))); - ect.set_profile(ProfileTypeChoice::Uri(Uri::from(Text::from( - plat.profile.to_string(), - )))); + ect.add_authority(cpak_pub.clone()); - let plat_hash_alg = HashAlgorithm::try_from(plat.hash_alg.as_str()).map_err(Error::custom)?; + let plat_hash_alg = HashAlgorithm::try_from(plat.hash_alg().as_str()).map_err(Error::custom)?; let cfg_element = ElementMap { mkey: Some("cca.platform-config".into()), mval: MeasurementValuesMapBuilder::default() .raw(RawValueType { raw_value: RawValueTypeChoice::TaggedBytes(TaggedBytes::from(Bytes::from( - plat.config.clone(), + plat.config().clone(), ))), raw_value_mask: None, }) @@ -218,6 +252,8 @@ fn platform_to_ect<'a>(plat: &Platform) -> Result, Error> { ect.add_element(cfg_element); + // Transformation of platform lifecycle claim is not provided in draft-ydp-rats-cca-endorsements-04 + // However, a lifecyle element-map is created so that it can be checked during the policy evaluation. let lifecycle_elt = ElementMap { mkey: Some(corim_rs::triples::MeasuredElementTypeChoice::Tstr( "lifecycle".into(), @@ -225,8 +261,8 @@ fn platform_to_ect<'a>(plat: &Platform) -> Result, Error> { mval: MeasurementValuesMapBuilder::default() .add_extension( RAW_INT_LABEL.into(), - ExtensionValue::Int( - match plat.lifecycle { + corim_rs::ExtensionValue::Int( + match plat.lifecycle() { 0x0000..=0x00ff => Ok(LC_UNKNOWN), 0x1000..=0x10ff => Ok(LC_ASSEMBLY_AND_TEST), 0x2000..=0x20ff => Ok(LC_CCA_ROT_PROVISIONING), @@ -245,7 +281,7 @@ fn platform_to_ect<'a>(plat: &Platform) -> Result, Error> { ect.add_element(lifecycle_elt); - for sw_comp in plat.sw_components.iter() { + for sw_comp in plat.sw_components().iter() { let mut mval_builder = MeasurementValuesMapBuilder::default() .cryptokeys(vec![CryptoKeyTypeChoice::Bytes( sw_comp.signer_id.clone().as_slice().into(), @@ -277,46 +313,61 @@ fn platform_to_ect<'a>(plat: &Platform) -> Result, Error> { }; ect.add_element(element); + + // TODO: + // Add code to parse "Platform TBB ROTPK" and "Platform manufacturing config" + // once they are supported in veraison/rust-ccatoken } - Ok(ect) + Ok(Ect::from(ect)) } -fn realm_to_ect<'a>(realm: &Realm) -> Result, Error> { - let mut ect = Ect::new(CmType::Evidence); +fn realm_to_ect<'a>(realm: &RealmClaims) -> Result, Error> { + if !(realm.profile() == REALM_PROFILE || realm.profile() == REALM_PROFILE_2024) { + return Err(Error::custom(format!( + "unsupported EAT realm profile {}", + realm.profile() + ))); + } - ect.set_environment( - EnvironmentMapBuilder::default() - .class( - ClassMapBuilder::default() - .class_id(ClassIdTypeChoice::Bytes(TaggedBytes::from(Bytes::from( - realm.rim.clone(), - )))) - .build() - .unwrap(), - ) - .build() - .unwrap(), - ); + let mut ect = ElementEct::new() + .cmtype(CmType::Evidence) + .environment( + EnvironmentMapBuilder::default() + .class( + ClassMapBuilder::default() + .class_id(ClassIdTypeChoice::Bytes(TaggedBytes::from(Bytes::from( + realm.rim().clone(), + )))) + .build() + .unwrap(), + ) + .build() + .unwrap(), + ) + .profile(ProfileTypeChoice::Uri(Uri::from(Text::from( + realm.profile().to_string(), + )))); - ect.set_profile(ProfileTypeChoice::Uri(Uri::from(Text::from( - realm.profile.to_string(), - )))); + let hash_alg = HashAlgorithm::try_from(realm.hash_alg().as_str()).map_err(Error::custom)?; - let hash_alg = HashAlgorithm::try_from(realm.hash_alg.as_str()).map_err(Error::custom)?; + let authority: CryptoKeyTypeChoice = + ciborium::from_reader(realm.get_realm_key().map_err(Error::custom)?.as_slice()) + .map_err(Error::custom)?; + ect.add_authority(authority); ect.add_element(ElementMap { mkey: Some("cca.rim".into()), mval: MeasurementValuesMapBuilder::default() .digest(vec![Digest { alg: hash_alg.clone(), - val: realm.rim.clone().into(), + val: realm.rim().clone().into(), }]) .build() .map_err(Error::custom)?, }); - for (i, rem) in realm.rem.iter().enumerate() { + for (i, rem) in realm.rem().iter().enumerate() { ect.add_element(ElementMap { mkey: Some(Cow::::Owned(format!("cca.rem{i}")).into()), mval: MeasurementValuesMapBuilder::default() @@ -334,7 +385,7 @@ fn realm_to_ect<'a>(realm: &Realm) -> Result, Error> { mval: MeasurementValuesMapBuilder::default() .raw(RawValueType { raw_value: RawValueTypeChoice::TaggedBytes(TaggedBytes::from(Bytes::from( - realm.perso.clone().as_slice(), + realm.perso(), ))), raw_value_mask: None, }) @@ -342,7 +393,7 @@ fn realm_to_ect<'a>(realm: &Realm) -> Result, Error> { .map_err(Error::custom)?, }); - Ok(ect) + Ok(Ect::from(ect)) } #[cfg(test)] @@ -351,15 +402,17 @@ mod test { #[test] fn evidence_to_ect() { - let token = include_bytes!("../../../test/cca/cca-token-01.cbor"); - let raw_key = include_str!("../../../test/cca/pkey.json"); + let token = include_bytes!("../../../test/cca/cca-token-03.cbor"); + let pem_key = include_bytes!("../../../test/cca/keys/iak-ec256.pub.pem"); let scheme = CcaScheme::new(); - let key = CryptoKeyTypeChoice::Bytes(raw_key.as_bytes().into()); + let key = CryptoKeyTypeChoice::PkixBase64Key( + Cow::::Owned(STANDARD_NO_PAD.encode(pem_key)).into(), + ); let ects = scheme - .validate_and_parse_evidence(token.as_slice(), &key) + .validate_and_parse_evidence(token.as_slice(), std::slice::from_ref(&key)) .unwrap(); assert_eq!(ects.len(), 2); } diff --git a/src/lib/cca/platform.rego b/src/lib/cca/platform.rego index 3e62344..d537e9b 100644 --- a/src/lib/cca/platform.rego +++ b/src/lib/cca/platform.rego @@ -17,12 +17,12 @@ platform contains ect if { refvals contains ect if { ect = platform[_] - ect["cm-type"] == "reference-values" + ect["cmtype"] == "reference-values" } evidence contains ect if { ect = platform[_] - ect["cm-type"] == "evidence" + ect["cmtype"] == "evidence" } lifecycle := ret if { diff --git a/src/lib/cca/profile.rs b/src/lib/cca/profile.rs new file mode 100644 index 0000000..0d126de --- /dev/null +++ b/src/lib/cca/profile.rs @@ -0,0 +1,49 @@ +use strum::IntoEnumIterator; +use strum_macros::EnumIter; + +/// Arm CCA Platform endorsement Corim profile identifier. +const CCA_CORIM_PLATFORM_PROFILE: &str = "tag:arm.com,2025:endorsements/cca_platform#1.0.0"; + +/// Arm CCA Realm endorsement Corim profile identifier. +const CCA_CORIM_REALM_PROFILE: &str = "tag:arm.com,2025:endorsements/cca_realm#1.0.0"; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumIter)] +pub enum CcaCorimProfile { + Platform, + Realm, +} + +impl CcaCorimProfile { + pub const fn as_str(self) -> &'static str { + match self { + Self::Platform => CCA_CORIM_PLATFORM_PROFILE, + Self::Realm => CCA_CORIM_REALM_PROFILE, + } + } + + pub fn all() -> Vec { + Self::iter().map(|p| p.to_string()).collect() + } +} + +impl std::fmt::Display for CcaCorimProfile { + fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str(self.as_str()) + } +} + +impl TryFrom<&str> for CcaCorimProfile { + type Error = crate::Error; + + fn try_from(profile: &str) -> Result { + match profile { + CCA_CORIM_PLATFORM_PROFILE => Ok(Self::Platform), + CCA_CORIM_REALM_PROFILE => Ok(Self::Realm), + _ => Err(crate::Error::custom(format!( + "Unrecognised CCA CoRIM profile \"{}\". \ + Supported profiles: \"{}\", \"{}\"", + profile, CCA_CORIM_PLATFORM_PROFILE, CCA_CORIM_REALM_PROFILE, + ))), + } + } +} diff --git a/src/lib/cca/realm.rego b/src/lib/cca/realm.rego index c9ed87e..5e21fc0 100644 --- a/src/lib/cca/realm.rego +++ b/src/lib/cca/realm.rego @@ -11,12 +11,12 @@ realm contains ect if { refvals contains ect if { ect = realm[_] - ect["cm-type"] == "reference-values" + ect["cmtype"] == "reference-values" } evidence contains ect if { ect = realm[_] - ect["cm-type"] == "evidence" + ect["cmtype"] == "evidence" } # If cryptographic verification completes (implicit in getting here), instance diff --git a/src/lib/corim.rs b/src/lib/corim.rs index 15f2b33..8706f6a 100644 --- a/src/lib/corim.rs +++ b/src/lib/corim.rs @@ -1,188 +1,96 @@ -use std::collections::BTreeMap; -use std::fmt::Display; +use log::warn; use std::vec::IntoIter; +use crate::ect::ElementMap; +use std::time::{SystemTime, UNIX_EPOCH}; + use corim_rs::{ - AttestKeyTripleRecord, ConciseMidTag, ConciseTagTypeChoice, - ConditionalEndorsementSeriesTripleRecord, ConditionalEndorsementTripleRecord, Corim, - CoseKeyOwner, CryptoKeyTypeChoice, EndorsedTripleRecord, ExtensionValue, Label, - MeasurementValuesMapBuilder, OpensslSigner, ProfileTypeChoice, ReferenceTripleRecord, + AttestKeyTripleRecord, ConciseMidTag, ConciseTagTypeChoice, Corim, CoseKeyOwner, + CryptoKeyTypeChoice, EndorsedTripleRecord, IdentityTripleRecord, MeasurementMap, OpensslSigner, + ProfileTypeChoice, ReferenceTripleRecord, ValidityMap, }; -use serde::{Deserialize, Serialize, de}; +use serde::{Deserialize, Serialize}; -use crate::ect::{CmType, Ect, EctBuilder, ElementMap}; +use crate::ect::{CmType, ElementEct, ElementEctBuilder, KeyEct, KeyEctBuilder, KeyType}; use crate::keystore::KeyStore; use crate::result::{Error, Result}; -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -pub enum KeyType { - AttestKey, - IdentityKey, -} - -impl From<&KeyType> for i64 { - fn from(value: &KeyType) -> Self { - match value { - KeyType::AttestKey => 0, - KeyType::IdentityKey => 1, - } - } -} - -impl TryFrom for KeyType { - type Error = Error; - - fn try_from(value: i64) -> std::result::Result { - match value { - 0 => Ok(Self::AttestKey), - 1 => Ok(Self::IdentityKey), - n => Err(Error::invalid_value(n, "a valid KeyType: 0 or 1")), - } - } -} - -impl Display for KeyType { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(match self { - Self::AttestKey => "attest-key", - Self::IdentityKey => "identity-key", - }) - } -} - -impl TryFrom<&str> for KeyType { - type Error = Error; - - fn try_from(value: &str) -> std::result::Result { - match value { - "attest-key" => Ok(Self::AttestKey), - "identity-key" => Ok(Self::IdentityKey), - s => Err(Error::invalid_value( - s.to_string(), - "a valid KeyType: \"attest-key\" or \"identity-key\"", - )), - } +/// Helper function to check time validity of Corim. +pub fn is_rim_valid(rim_validity: Option<&ValidityMap>) -> bool { + let Some(validity) = rim_validity else { + return true; + }; + + let Ok(now) = SystemTime::now().duration_since(UNIX_EPOCH) else { + warn!("System time is before UNIX epoch"); + return false; + }; + + let now = now.as_secs(); + + let Some(not_after) = u64::try_from(validity.not_after.as_i128()).ok() else { + warn!("Invalid CoRIM 'not_after' timestamp"); + return false; + }; + + let not_before = validity + .not_before + .as_ref() + .and_then(|t| u64::try_from(t.as_i128()).ok()) + .unwrap_or(0); + + if not_before > not_after { + warn!( + "CoRIM is invalid: 'not_before' ({}) is greater than 'not_after' ({})", + not_before, not_after + ); + return false; } -} -impl Serialize for KeyType { - fn serialize(&self, serializer: S) -> std::result::Result - where - S: serde::Serializer, - { - if serializer.is_human_readable() { - self.to_string().serialize(serializer) - } else { - i64::from(self).serialize(serializer) - } + if now > not_after { + warn!("CoRIM expired at timestamp: {}", not_after); + return false; } -} -impl<'de> Deserialize<'de> for KeyType { - fn deserialize(deserializer: D) -> std::result::Result - where - D: serde::Deserializer<'de>, - { - if deserializer.is_human_readable() { - String::deserialize(deserializer)? - .as_str() - .try_into() - .map_err(de::Error::custom) - } else { - i64::deserialize(deserializer)? - .try_into() - .map_err(de::Error::custom) - } + if now < not_before { + warn!("CoRIM is not active until timestamp: {}", not_before); + return false; } -} - -pub const INTERP_KEYS_EXT_ID: i128 = 65534; - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct TypedCryptoKey<'a> { - pub key: CryptoKeyTypeChoice<'a>, - #[serde(rename = "key-type")] - pub key_type: KeyType, -} - -impl From> for ExtensionValue<'_> { - fn from(value: TypedCryptoKey) -> Self { - let mut map: BTreeMap = BTreeMap::new(); - let key_ser = serde_json::to_string(&value.key).unwrap(); - map.insert("key".into(), key_ser.into()); - map.insert("key-type".into(), value.key_type.to_string().into()); - - ExtensionValue::Map(map) - } + true } -impl<'a> TryFrom<&ExtensionValue<'a>> for TypedCryptoKey<'a> { - type Error = Error; - - fn try_from(value: &ExtensionValue<'a>) -> std::result::Result { - if let ExtensionValue::Map(map) = value { - let key_json = map - .get(&Label::from("key")) - .ok_or(Error::custom("missing key entry in interp_keys map"))?; - - let key_type_text = map - .get(&Label::from("key-type")) - .ok_or(Error::custom("missing key-type entry in interp_keys map"))?; - - let key: CryptoKeyTypeChoice = serde_json::from_str( - key_json - .as_str() - .ok_or(Error::custom("invalid key entry"))?, - )?; - - let key_type: KeyType = KeyType::try_from( - key_type_text - .as_str() - .ok_or(Error::custom("invalid key-type entry"))?, - )?; - - Ok(TypedCryptoKey { key, key_type }) - } else { - Err(Error::custom(format!("expected map, found {:?}", value))) - } - } +fn measurementmap_vec_to_elemenetmap_vec<'a, 'b>( + mms: &Vec>, +) -> Vec> { + mms.iter().map(ElementMap::from).collect() } /// Reference value relation. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct RvRelation<'a> { - pub condition: Ect<'a>, - pub addition: Ect<'a>, + pub condition: ElementEct<'a>, + pub addition: ElementEct<'a>, } impl<'a> RvRelation<'a> { pub fn from_reference_triple_record<'b>( rvt: &ReferenceTripleRecord<'b>, profile: &Option>, - authority: &Vec>, + signer: &[CryptoKeyTypeChoice<'b>], ) -> Result> { - let condition: Ect<'a> = EctBuilder::new() - .cm_type(CmType::ReferenceValues) + let condition: ElementEct<'a> = ElementEctBuilder::new() .environment(rvt.ref_env.to_fully_owned()) - .element_list( - rvt.ref_claims - .iter() - .map(|e| ElementMap { - mkey: e.mkey.as_ref().map(|k| k.to_fully_owned()), - mval: e.mval.to_fully_owned(), - }) - .collect(), - ) + .element_list(measurementmap_vec_to_elemenetmap_vec(&rvt.ref_claims)) .build()?; - let addition: Ect<'a> = match profile { - Some(p) => EctBuilder::new().profile(p.to_fully_owned()), - None => EctBuilder::new(), + let addition: ElementEct<'a> = match profile { + Some(p) => ElementEctBuilder::new().profile(p.to_fully_owned()), + None => ElementEctBuilder::new(), } - .cm_type(CmType::ReferenceValues) + .cmtype(CmType::ReferenceValues) .environment(rvt.ref_env.to_fully_owned()) - .authority(authority.iter().map(|v| v.to_fully_owned()).collect()) + .authority(signer.iter().map(|v| v.to_fully_owned()).collect()) .build()?; Ok(RvRelation { @@ -195,37 +103,29 @@ impl<'a> RvRelation<'a> { /// Endorsed value relation. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct EvRelation<'a> { - pub condition: Vec>, - pub addition: Vec>, + pub condition: Vec>, + pub addition: Vec>, } impl<'a> EvRelation<'a> { pub fn from_endorsed_triple_record<'b>( evt: &EndorsedTripleRecord<'b>, profile: &Option>, - authority: &Vec>, + signer: &[CryptoKeyTypeChoice<'b>], ) -> Result> { - let condition = EctBuilder::new() - .cm_type(CmType::Endorsements) + let condition: ElementEct<'a> = ElementEctBuilder::new() .environment(evt.condition.to_fully_owned()) - .element_list( - evt.endorsement - .iter() - .map(|e| ElementMap { - mkey: e.mkey.as_ref().map(|k| k.to_fully_owned()), - mval: e.mval.to_fully_owned(), - }) - .collect(), - ) + // element list is not used for EV-triples, skipping .build()?; - let addition = match profile { - Some(p) => EctBuilder::new().profile(p.to_fully_owned()), - None => EctBuilder::new(), + let addition: ElementEct<'a> = match profile { + Some(p) => ElementEctBuilder::new().profile(p.to_fully_owned()), + None => ElementEctBuilder::new(), } - .cm_type(CmType::Endorsements) + .cmtype(CmType::Endorsements) .environment(evt.condition.to_fully_owned()) - .authority(authority.iter().map(|v| v.to_fully_owned()).collect()) + .element_list(measurementmap_vec_to_elemenetmap_vec(&evt.endorsement)) + .authority(signer.iter().map(|v| v.to_fully_owned()).collect()) .build()?; Ok(EvRelation { @@ -233,218 +133,181 @@ impl<'a> EvRelation<'a> { addition: vec![addition], }) } +} - pub fn from_conditional_endorsement_triple_record<'b>( - cet: &ConditionalEndorsementTripleRecord<'b>, - profile: &Option>, - authority: &Vec>, - ) -> Result> { - let condition: Result> = cet - .conditions - .iter() - .map(|cond| { - EctBuilder::new() - .cm_type(CmType::Endorsements) - .environment(cond.environment.to_fully_owned()) - .element_list( - cond.claims_list - .iter() - .map(|e| ElementMap { - mkey: e.mkey.as_ref().map(|k| k.to_fully_owned()), - mval: e.mval.to_fully_owned(), - }) - .collect(), - ) - .build() - }) - .collect(); - - if let Err(err) = condition { - return Err(Error::custom(format!("CET condition error: {}", err))); - } +/// Key relation. +// Key relation condition and addition ECT structure is inferred from \ +// transformation function given in corim draft (rev 11) figure 43 +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct KeyRelation<'a> { + pub condition: KeyEct<'a>, + pub addition: KeyEct<'a>, +} - let addition: Result> = cet - .endorsements - .iter() - .map(|end| { - match profile { - Some(p) => EctBuilder::new().profile(p.to_fully_owned()), - None => EctBuilder::new(), - } - .cm_type(CmType::Endorsements) - .environment(end.condition.to_fully_owned()) - .element_list( - end.endorsement - .iter() - .map(|e| ElementMap { - mkey: e.mkey.as_ref().map(|k| k.to_fully_owned()), - mval: e.mval.to_fully_owned(), - }) - .collect(), - ) - .authority(authority.iter().map(|v| v.to_fully_owned()).collect()) - .build() - }) - .collect(); - - if let Err(err) = addition { - return Err(Error::custom(format!("CET addition error: {}", err))); - } +/// Performs a deep copy of triple record conditions with lifetime conversion. +/// +/// This helper function creates a fully owned copy of a [TriplesRecordCondition], +/// converting all borrowed references to owned values with the target lifetime `'a`. +fn keytriplerecord_condition_deep_copy<'a>( + conds: &corim_rs::TriplesRecordCondition, +) -> corim_rs::TriplesRecordCondition<'a> { + let mut triple_record_conditions = corim_rs::TriplesRecordConditionBuilder::new(); + if let Some(mk) = &conds.mkey { + triple_record_conditions = triple_record_conditions.mkey(mk.to_fully_owned()); + } - Ok(EvRelation { - condition: condition.unwrap(), - addition: addition.unwrap(), - }) + if let Some(auth_by) = &conds.authorized_by { + triple_record_conditions = triple_record_conditions + .authorized_by(auth_by.iter().map(|c| c.to_fully_owned()).collect()); } + // Build can not panic since both field can not be empty at the same time. + triple_record_conditions + .build() + .expect("condition is always non-empty") +} - pub fn from_attest_key_triple_record<'b>( - akt: &AttestKeyTripleRecord<'b>, - profile: &Option>, - authority: &Vec>, - ) -> Result> { - let condition = match &akt.conditions { - Some(cond) => match &cond.authorized_by { - Some(auth_by) => EctBuilder::new() - .authority(auth_by.iter().map(|c| c.to_fully_owned()).collect()), - None => EctBuilder::new(), - }, - None => EctBuilder::new(), - } - .cm_type(CmType::Endorsements) - .environment(akt.environment.to_fully_owned()) - .element_list( - akt.key_list - .iter() - .map(|e| ElementMap { - mkey: match &akt.conditions { - Some(cond) => cond.mkey.as_ref().map(|k| k.to_fully_owned()), - None => None, - }, - mval: MeasurementValuesMapBuilder::new() - .add_extension( - INTERP_KEYS_EXT_ID, - TypedCryptoKey { - key: e.to_fully_owned(), - key_type: KeyType::AttestKey, - } - .into(), - ) - .build() - .unwrap(), - }) - .collect(), - ) - .build()?; +/// Trait for abstracting over different types of key triple records. +/// +/// This trait provides a unified interface to extract information from key triple records, +/// i.e. [AttestKeyTripleRecord] and [IdentityTripleRecord]. It allows for +/// generic handling of key-related triples regardless of their specific type. +trait KeyTripleRecord<'a> { + /// Returns the type of this key triple record (attestation or identity key). + fn get_key_triple_record_type(&self) -> KeyType; + + /// Returns the environment map associated with this key triple record. + fn get_key_triple_environment(&self) -> corim_rs::EnvironmentMap<'a>; + + /// Returns the list of cryptographic keys in this record. + fn get_key_triple_key_list(&self) -> Vec>; + + /// Returns any conditions associated with this key triple record. + /// + /// Conditions that must be met for a triple record to be valid. + fn get_key_triple_conditions(&self) -> Option>; +} - let addition = match profile { - Some(p) => EctBuilder::new().profile(p.to_fully_owned()), - None => EctBuilder::new(), - } - .cm_type(CmType::Endorsements) - .authority(authority.iter().map(|v| v.to_fully_owned()).collect()) - .build()?; +/// Implementation of [KeyTripleRecord] for attestation key triple records. +impl<'a, 'b> KeyTripleRecord<'a> for AttestKeyTripleRecord<'b> { + fn get_key_triple_record_type(&self) -> KeyType { + KeyType::AttestKey + } - Ok(EvRelation { - condition: vec![condition], - addition: vec![addition], - }) + fn get_key_triple_environment(&self) -> corim_rs::EnvironmentMap<'a> { + self.environment.to_fully_owned() } -} -/// Endorsed value series entry. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct EvsRelationSeriesEntry<'a> { - pub selection: Vec>, - pub addition: Vec>, + fn get_key_triple_key_list(&self) -> Vec> { + self.key_list.iter().map(|k| k.to_fully_owned()).collect() + } + + fn get_key_triple_conditions(&self) -> Option> { + self.conditions + .as_ref() + .map(keytriplerecord_condition_deep_copy) + } } -/// Endorsed value series relation. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct EvsRelation<'a> { - pub condition: Vec>, - pub series: Vec>, +/// Implementation of [KeyTripleRecord] for identity key triple records. +impl<'a, 'b> KeyTripleRecord<'a> for IdentityTripleRecord<'b> { + fn get_key_triple_record_type(&self) -> KeyType { + KeyType::IdentityKey + } + + fn get_key_triple_environment(&self) -> corim_rs::EnvironmentMap<'a> { + self.environment.to_fully_owned() + } + + fn get_key_triple_key_list(&self) -> Vec> { + self.key_list.iter().map(|k| k.to_fully_owned()).collect() + } + + fn get_key_triple_conditions(&self) -> Option> { + self.conditions + .as_ref() + .map(keytriplerecord_condition_deep_copy) + } } -impl<'a> EvsRelation<'a> { - pub fn from_conditional_endorsement_series_triple_record<'b>( - cest: &ConditionalEndorsementSeriesTripleRecord<'b>, - profile: &Option>, - authority: &Vec>, - ) -> Result> { - let condition = EctBuilder::new() - .cm_type(CmType::Endorsements) - .environment(cest.condition.environment.to_fully_owned()) - .element_list( - cest.condition - .claims_list - .iter() - .map(|e| ElementMap { - mkey: e.mkey.as_ref().map(|k| k.to_fully_owned()), - mval: e.mval.to_fully_owned(), - }) - .collect(), - ) - .build()?; +impl<'a> KeyRelation<'a> { + fn from_key_triple_record( + k: &T, + profile: &Option, + verifier_authority: &[CryptoKeyTypeChoice], + ) -> Result> + where + T: KeyTripleRecord<'a>, + { + // Building Condition ECT + let mut cond_builder = KeyEctBuilder::new() + .key_type(k.get_key_triple_record_type()) + .environment(k.get_key_triple_environment()) + .key_list(k.get_key_triple_key_list()); + + // Building Addition ECT + let mut add_builder = KeyEctBuilder::new() + .key_type(k.get_key_triple_record_type()) + .environment(k.get_key_triple_environment()); + + if let Some(triple_conditions) = k.get_key_triple_conditions() + && let Some(key_id) = triple_conditions.mkey + { + cond_builder = cond_builder.key_id(key_id.clone()); + add_builder = add_builder.key_id(key_id); + } - let series: Result> = cest - .series - .iter() - .map(|csr| { - let selection: Ect<'a> = EctBuilder::new() - .cm_type(CmType::Endorsements) - .environment(cest.condition.environment.to_fully_owned()) - .element_list( - csr.selection - .iter() - .map(|e| ElementMap { - mkey: e.mkey.as_ref().map(|k| k.to_fully_owned()), - mval: e.mval.to_fully_owned(), - }) - .collect(), - ) - .build()?; - - let addition: Ect<'a> = match profile { - Some(p) => EctBuilder::new().profile(p.to_fully_owned()), - None => EctBuilder::new(), - } - .cm_type(CmType::Endorsements) - .environment(cest.condition.environment.to_fully_owned()) - .element_list( - csr.addition - .iter() - .map(|e| ElementMap { - mkey: e.mkey.as_ref().map(|k| k.to_fully_owned()), - mval: e.mval.to_fully_owned(), - }) - .collect(), - ) - .authority(authority.iter().map(|v| v.to_fully_owned()).collect()) - .build()?; - - Ok(EvsRelationSeriesEntry { - selection: vec![selection], - addition: vec![addition], - }) - }) - .collect(); - - if let Err(err) = series { - return Err(Error::custom(format!("CEST series error: {}", err))); + if let Some(triple_conditions) = k.get_key_triple_conditions() + && let Some(authority) = triple_conditions.authorized_by + { + cond_builder = cond_builder.authority(authority); } - Ok(EvsRelation { - condition: vec![condition], - series: series.unwrap(), + if let Some(p) = profile { + add_builder = add_builder.profile(p.to_fully_owned()); + } + + // Adding "verifier's authority" as "addition KeyECT authority" + add_builder = add_builder.authority( + verifier_authority + .iter() + .map(|v| v.to_fully_owned()) + .collect(), + ); + + let condition = cond_builder.build()?; + let addition = add_builder.build()?; + + Ok(KeyRelation { + condition, + addition, }) } + + pub fn from_identity_key_triple_record<'b>( + ikt: &IdentityTripleRecord<'b>, + profile: &Option>, + signer: &[CryptoKeyTypeChoice<'b>], + ) -> Result> { + Self::from_key_triple_record(ikt, profile, signer) + } + + pub fn from_attest_key_triple_record<'b>( + akt: &AttestKeyTripleRecord<'b>, + profile: &Option>, + signer: &[CryptoKeyTypeChoice<'b>], + ) -> Result> { + Self::from_key_triple_record(akt, profile, signer) + } } +// TODO: Define Domain Membership and Trust Dependency Relations and +// transformation functions to populate defined data structure. + /// A store of reference and endorsed values extracted from CoRIMs. pub trait CorimStore<'a> { type RvIter: Iterator>; type EvIter: Iterator>; - type EvsIter: Iterator>; + type KeyIter: Iterator>; /// Add values from the specified `Corim` to the store. fn add(&mut self, corim: &Corim) -> Result<()>; @@ -461,18 +324,16 @@ pub trait CorimStore<'a> { /// Iterate over extracted [EvRelation]s. fn iter_ev(&self) -> Self::EvIter; - /// Iterate over extracted [EvsRelation]s. - fn iter_evs(&self) -> Self::EvsIter; + /// Iterate over extracted [KeyRelation]s. + fn iter_key(&self) -> Self::KeyIter; } #[derive(Clone, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] pub struct CorimParseResult<'a> { - #[serde(rename = "rv-list")] pub rv_list: Vec>, - #[serde(rename = "ev-list")] pub ev_list: Vec>, - #[serde(rename = "evs-list")] - pub evs_list: Vec>, + pub key_list: Vec>, } impl<'a> CorimParseResult<'a> { @@ -480,27 +341,28 @@ impl<'a> CorimParseResult<'a> { CorimParseResult { rv_list: vec![], ev_list: vec![], - evs_list: vec![], + key_list: vec![], } } pub fn extend(&mut self, other: CorimParseResult<'a>) { self.rv_list.extend(other.rv_list); self.ev_list.extend(other.ev_list); - self.evs_list.extend(other.evs_list); + self.key_list.extend(other.key_list); } pub fn append(&mut self, other: &mut CorimParseResult<'a>) { self.rv_list.append(other.rv_list.as_mut()); self.ev_list.append(other.ev_list.as_mut()); - self.evs_list.append(other.evs_list.as_mut()); + self.key_list.append(other.key_list.as_mut()); } pub fn update_from_comid<'b>( &mut self, comid: &ConciseMidTag<'b>, profile: &Option>, - authority: &Vec>, + authority: &[CryptoKeyTypeChoice<'b>], + verifier_authority: &[CryptoKeyTypeChoice<'b>], ) -> Result<()> { let mut updated = false; @@ -522,31 +384,12 @@ impl<'a> CorimParseResult<'a> { } } - if let Some(cets) = &comid.triples.conditional_endorsement_triples { - for cet in cets { - self.ev_list - .push(EvRelation::from_conditional_endorsement_triple_record( - cet, profile, authority, - )?); - updated = true; - } - } - - if let Some(cests) = &comid.triples.conditional_endorsement_series_triples { - for cest in cests { - self.evs_list.push( - EvsRelation::from_conditional_endorsement_series_triple_record( - cest, profile, authority, - )?, - ); - updated = true; - } - } - if let Some(akts) = &comid.triples.attest_key_triples { for akt in akts { - self.ev_list.push(EvRelation::from_attest_key_triple_record( - akt, profile, authority, + self.key_list.push(KeyRelation::from_key_triple_record( + akt, + profile, + verifier_authority, )?); updated = true; } @@ -567,7 +410,7 @@ impl Default for CorimParseResult<'_> { impl std::fmt::Debug for CorimParseResult<'_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let s = serde_json::to_string_pretty(&self).unwrap(); + let s = serde_json::to_string_pretty(&self).expect("Input object should be serialisable"); f.write_str(s.as_str()) } } @@ -590,20 +433,27 @@ impl MemCorimStore<'_, S> { impl<'a, S: KeyStore> CorimStore<'a> for MemCorimStore<'a, S> { type RvIter = IntoIter>; type EvIter = IntoIter>; - type EvsIter = IntoIter>; + type KeyIter = IntoIter>; #[allow(clippy::needless_lifetimes)] fn add<'b>(&mut self, corim: &Corim<'b>) -> Result<()> { - if let Some(signed) = corim.as_signed_ref() { - let key = self.keystore.get(signed.kid.as_slice())?; - let mut parsed = parse_corim(corim, &key).map_err(|e| { - Error::Parse(format!("CoRIM \"{}\"", signed.corim_map.id), e.to_string()) - })?; - self.items.append(&mut parsed); - Ok(()) - } else { - Err(Error::custom("unsigned CoRIMs not supported")) - } + // Get cryptographic key for signed corim, + // for unsigned corims, use verifier's cryptographic key + let corim_key: Vec = match corim.as_signed_ref() { + Some(signed) => self.keystore.get(signed.kid.as_slice())?, + None => self.keystore.get("verifier-key".as_bytes())?, + }; + + // Fetch verifier's key to use with Key addition Ect + let verifier_key = self.keystore.get("verifier-key".as_bytes())?; + let mut parsed = parse_corim(corim, &corim_key, &verifier_key).map_err(|e| { + Error::Parse( + format!("CoRIM \"{}\"", corim.as_map_ref().id), + e.to_string(), + ) + })?; + self.items.append(&mut parsed); + Ok(()) } fn iter_rv(&self) -> Self::RvIter { @@ -614,58 +464,142 @@ impl<'a, S: KeyStore> CorimStore<'a> for MemCorimStore<'a, S> { self.items.ev_list.clone().into_iter() } - fn iter_evs(&self) -> Self::EvsIter { - self.items.evs_list.clone().into_iter() + fn iter_key(&self) -> Self::KeyIter { + self.items.key_list.clone().into_iter() } } +/// Function to parse corims and add to corim-store. +/// `corim_key` define the authority who signed the corim, for unsigned corim, verifier's authority is used. +/// In case of unsigned corim, `corim_key` and `verifier_key` are same. #[allow(clippy::needless_lifetimes)] -pub fn parse_corim<'a, 'b>(corim: &Corim<'a>, key: &[u8]) -> Result> { - let verifier = OpensslSigner::public_key_from_pem(key)?; - let authority = vec![CryptoKeyTypeChoice::CoseKey(verifier.to_cose_key().into())]; - - if let Corim::Signed(signed) = corim { - match signed.verify_signature(verifier) { - Ok(_) => { - let profile = signed.corim_map.profile.clone(); - let mut result = CorimParseResult::new(); - - for tag in &signed.corim_map.tags { - if let ConciseTagTypeChoice::Mid(tagged_comid) = tag { - result.update_from_comid(tagged_comid.as_ref(), &profile, &authority)?; - } - } - - Ok(result) +pub fn parse_corim<'a, 'b>( + corim: &Corim<'a>, + corim_key: &[u8], + verifier_key: &[u8], +) -> Result> { + let corim_verifier = OpensslSigner::public_key_from_pem(corim_key)?; + let authority = vec![CryptoKeyTypeChoice::CoseKey( + corim_verifier.to_cose_key().into(), + )]; + + // key related to Verifier (person using CoVER) + let verifier = OpensslSigner::public_key_from_pem(verifier_key)?; + let verifier_authority = vec![CryptoKeyTypeChoice::CoseKey(verifier.to_cose_key().into())]; + + let corim_map = match corim { + Corim::Signed(signed) => match signed.verify_signature(corim_verifier) { + Ok(_) => &signed.corim_map, + Err(err) => { + return Err(Error::custom(format!( + "signature verification failed: {}", + err + ))); } - Err(err) => Err(Error::custom(format!( - "signature verification failed: {}", - err - ))), + }, + Corim::Unsigned(corim_map) => corim_map, + }; + + let profile = corim_map.profile.clone(); + let mut result = CorimParseResult::new(); + + for tag in &corim_map.tags { + if let ConciseTagTypeChoice::Mid(tagged_comid) = tag { + result.update_from_comid( + tagged_comid.as_ref(), + &profile, + &authority, + &verifier_authority, + )?; } - } else { - Err(Error::custom("unsigned CoRIMs not supported")) } + + Ok(result) } #[cfg(test)] mod test { use super::*; use crate::keystore::MemKeyStore; + use corim_rs::triples::EnvironmentMap; #[test] - fn parse_corim_test() { - let token = include_bytes!("../../test/corim/signed-corim-cca-ref-plat.cbor"); - let token_ta = include_bytes!("../../test/corim/signed-corim-cca-ta.cbor"); + fn rv_triple_record_creates_condition_and_addition_ects() { + let corim_bytes = include_bytes!("../../test/corim/signed-corim-cca-plat-rv.cbor"); + let corim_key = include_bytes!("../../test/corim/key.pub.pem"); + let parsed_corim = Corim::from_cbor(corim_bytes.as_slice()).unwrap(); + let corim_map = &parsed_corim.as_signed().unwrap().corim_map; + let profile = corim_map.profile.clone(); + let verifier = OpensslSigner::public_key_from_pem(corim_key).unwrap(); + let authority = vec![CryptoKeyTypeChoice::CoseKey(verifier.to_cose_key().into())]; + + let env = EnvironmentMap::default(); + let mut rv_triple = ReferenceTripleRecord { + ref_env: env, + ref_claims: vec![], + }; + for tag in &corim_map.tags { + if let ConciseTagTypeChoice::Mid(tagged_comid) = tag + && tagged_comid.triples.reference_triples.is_some() + { + rv_triple = tagged_comid + .as_ref() + .triples + .reference_triples + .clone() + .unwrap() + .first() + .unwrap() + .clone(); + break; + } + } + let relation = + RvRelation::from_reference_triple_record(&rv_triple, &profile, &authority).unwrap(); + + assert!(relation.addition.get_profile().is_some()); + assert!(!relation.condition.element_list.as_ref().unwrap().is_empty()); + } + + #[test] + fn parse_signed_corim() { + let token = include_bytes!("../../test/corim/signed-corim-cca-plat-rv.cbor"); + let token_ta = include_bytes!("../../test/corim/signed-corim-cca-plat-ta.cbor"); let key = include_bytes!("../../test/corim/key.pub.pem"); let mut keystore = MemKeyStore::new(); keystore.add("key.pub.pem".as_bytes(), key).unwrap(); + keystore.add("verifier-key".as_bytes(), key).unwrap(); let mut store = MemCorimStore::new(keystore); store.add_bytes(token.as_slice()).unwrap(); store.add_bytes(token_ta.as_slice()).unwrap(); - println!("{:?}", store.items); + assert!(!store.items.rv_list.is_empty()); + assert!(!store.items.key_list.is_empty()); + // Check if addition KeyECT has authority set. + assert!( + store + .items + .key_list + .first() + .unwrap() + .addition + .get_authority() + .is_some() + ); + } + + #[test] + fn parse_unsigned_corim() { + let token = include_bytes!("../../test/corim/corim-cca-plat-rv.cbor"); + let key = include_bytes!("../../test/corim/key.pub.pem"); + + let mut keystore = MemKeyStore::new(); + keystore.add("verifier-key".as_bytes(), key).unwrap(); + + let mut store = MemCorimStore::new(keystore); + store.add_bytes(token.as_slice()).unwrap(); + assert!(!store.items.rv_list.is_empty()); } } diff --git a/src/lib/ect.rs b/src/lib/ect.rs index 03a9870..0aacc36 100644 --- a/src/lib/ect.rs +++ b/src/lib/ect.rs @@ -1,11 +1,15 @@ +use std::collections::HashSet; use std::fmt::Display; +use std::hash::{Hash, Hasher}; use corim_rs::{ corim::ProfileTypeChoice, triples::{ - CryptoKeyTypeChoice, EnvironmentMap, MeasuredElementTypeChoice, MeasurementValuesMap, + CryptoKeyTypeChoice, EnvironmentMap, MeasuredElementTypeChoice, MeasurementMap, + MeasurementValuesMap, }, }; +use log::debug; use serde::{Deserialize, Serialize, de}; use crate::result::Error; @@ -16,9 +20,6 @@ pub enum CmType { ReferenceValues, Endorsements, Evidence, - AttestationResults, - Verifier, - Policy, } impl TryFrom<&str> for CmType { @@ -29,9 +30,6 @@ impl TryFrom<&str> for CmType { "reference-values" => Ok(CmType::ReferenceValues), "endorsements" => Ok(CmType::Endorsements), "evidence" => Ok(CmType::Evidence), - "attestation-results" => Ok(CmType::AttestationResults), - "verifier" => Ok(CmType::Verifier), - "policy" => Ok(CmType::Policy), s => Err(Error::invalid_value( s.to_string(), "a valid conceptual message type name", @@ -48,9 +46,6 @@ impl TryFrom for CmType { 0 => Ok(CmType::ReferenceValues), 1 => Ok(CmType::Endorsements), 2 => Ok(CmType::Evidence), - 3 => Ok(CmType::AttestationResults), - 4 => Ok(CmType::Verifier), - 5 => Ok(CmType::Policy), n => Err(Error::invalid_value( n, "an integer 0-5 indicating the conceptual message type", @@ -65,9 +60,6 @@ impl From<&CmType> for i64 { CmType::ReferenceValues => 0, CmType::Endorsements => 1, CmType::Evidence => 2, - CmType::AttestationResults => 3, - CmType::Verifier => 4, - CmType::Policy => 5, } } } @@ -78,9 +70,6 @@ impl Display for CmType { CmType::ReferenceValues => "reference-values", CmType::Endorsements => "endorsements", CmType::Evidence => "evidence", - CmType::AttestationResults => "attestation-results", - CmType::Verifier => "verifier", - CmType::Policy => "policy", }; f.write_str(text) @@ -118,46 +107,173 @@ impl<'de> Deserialize<'de> for CmType { } } -#[derive(Debug, Clone, Default, Serialize, Deserialize)] +// helper function to skip serialization of empty vector +fn vec_is_empty_or_none(vec: &Option>) -> bool { + vec.as_ref().is_none_or(Vec::is_empty) +} + +#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)] pub struct ElementMap<'a> { #[serde(skip_serializing_if = "Option::is_none")] pub mkey: Option>, pub mval: MeasurementValuesMap<'a>, } +// Required for HashSet +impl<'a> Hash for ElementMap<'a> { + fn hash(&self, state: &mut H) + where + H: Hasher, + { + let mut bytes = Vec::new(); + ciborium::into_writer(self, &mut bytes).expect("ElementMap should derive Serialize trait"); + bytes.hash(state); + } +} + +impl<'a, 'b> From<&MeasurementMap<'a>> for ElementMap<'b> { + fn from(value: &MeasurementMap<'a>) -> Self { + ElementMap { + mkey: value.mkey.as_ref().map(|k| k.to_fully_owned()), + mval: value.mval.to_fully_owned(), + } + } +} + /// Environment-claims tuple. This associates a set of claims with an environment and keeps track /// of the authority that originated the claims. [Ect]s are used in several different ways during -/// verification. An [Ect]'s intended use is indicated by the `cm_type` field. +/// verification. +/// An [Ect]'s intended use is indicated by the `cmtype` field. +/// +/// Top level enum to contain all types of Ects. #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct Ect<'a> { +#[serde(untagged)] +pub enum Ect<'a> { + Element(ElementEct<'a>), + Key(KeyEct<'a>), +} + +impl<'a> Ect<'a> { + pub fn as_element_ect(&self) -> Option<&ElementEct<'a>> { + match self { + Ect::Element(ect) => Some(ect), + Ect::Key(_) => None, + } + } + + pub fn as_key_ect(&self) -> Option<&KeyEct<'a>> { + match self { + Ect::Key(ect) => Some(ect), + Ect::Element(_) => None, + } + } + + /// Merge similar ECTs according to the definition defined in draft-ietf-rats-corim-11. + pub fn merge_similar_ects(ects: Vec) -> Vec { + let mut element_ects: Vec> = Vec::with_capacity(ects.len()); + let mut non_element_ects: Vec> = Vec::new(); + + for ect in ects { + match ect { + Ect::Element(element_ect) => element_ects.push(element_ect), + ect => non_element_ects.push(ect), + } + } + let element_ects_len = element_ects.len(); + let mut merged_element_ects: Vec> = Vec::with_capacity(element_ects_len); + for e_ect in element_ects { + let mut matched = false; + + for existing in &mut merged_element_ects { + if existing.merge_with(&e_ect) { + matched = true; + break; + } + } + + if !matched { + merged_element_ects.push(e_ect); + } + } + debug!( + "{} duplicate Element ECTs are merged", + element_ects_len - merged_element_ects.len() + ); + let mut merged: Vec> = merged_element_ects.into_iter().map(Ect::Element).collect(); + merged.extend(non_element_ects); + merged + } +} + +impl<'a> From> for Ect<'a> { + fn from(value: ElementEct<'a>) -> Self { + Ect::Element(value) + } +} + +impl<'a> From> for Ect<'a> { + fn from(value: KeyEct<'a>) -> Self { + Ect::Key(value) + } +} + +#[derive(Debug, Clone, Serialize, Deserialize, Default)] +pub struct EctCommon<'a> { /// The target environment. #[serde(skip_serializing_if = "Option::is_none")] pub environment: Option>, - /// The set of elements contained within the target environment. - #[serde(rename = "element-list", skip_serializing_if = "Option::is_none")] - pub element_list: Option>>, /// Authority that issued this ECT + #[serde(skip_serializing_if = "vec_is_empty_or_none")] pub authority: Option>>, - /// Conceptual Message Type that identifies the type of Conceptual Message that originated this - /// Environment-Claims Tuple. - #[serde(rename = "cm-type")] - pub cm_type: CmType, /// The profile associated with this tuple. #[serde(skip_serializing_if = "Option::is_none")] pub profile: Option>, } -impl<'a> Ect<'a> { - pub fn new(cm_type: CmType) -> Self { - Ect { - cm_type, - environment: None, - authority: None, - element_list: None, - profile: None, - } +#[derive(Debug, Clone, Serialize, Deserialize, Default)] +#[serde(rename_all = "kebab-case")] +pub struct ElementEct<'a> { + #[serde(flatten)] + pub ect_common: EctCommon<'a>, + /// The set of elements contained within the target environment. + #[serde(skip_serializing_if = "Option::is_none")] + pub element_list: Option>>, + /// Conceptual Message Type that identifies the type of Conceptual Message that originated this + /// Environment-Claims Tuple. + #[serde(skip_serializing_if = "Option::is_none")] + pub cmtype: Option, +} + +impl<'a> ElementEct<'a> { + pub fn new() -> Self { + ElementEct::default() } + /// Set type of message, [ElementEct] is representing. + pub fn cmtype(mut self, cmtype: CmType) -> Self { + self.cmtype = Some(cmtype); + self + } + + /// Set environment Ids inside [ElementEct] for identification + pub fn environment(mut self, env: EnvironmentMap<'a>) -> Self { + self.ect_common.environment = Some(env); + self + } + + /// Set eat profile of [ElementEct] + pub fn profile(mut self, profile: ProfileTypeChoice<'a>) -> Self { + self.ect_common.profile = Some(profile); + self + } + + /// Set the authority of the [ElementEct]. + pub fn authority(mut self, authority: Vec>) -> Self { + self.ect_common.authority = Some(authority); + self + } + + /// Insert measured elements into [ElementEct] pub fn add_element(&mut self, elt: ElementMap<'a>) { if let Some(elt_list) = self.element_list.as_mut() { elt_list.push(elt); @@ -166,104 +282,384 @@ impl<'a> Ect<'a> { } } + /// Add a key to the authority of the [ElementEct]. pub fn add_authority(&mut self, authority: CryptoKeyTypeChoice<'a>) { - if let Some(auth_list) = self.authority.as_mut() { + if let Some(auth_list) = self.ect_common.authority.as_mut() { auth_list.push(authority); } else { - self.authority = Some(vec![authority]); + self.ect_common.authority = Some(vec![authority]); } } - pub fn set_environment(&mut self, env: EnvironmentMap<'a>) { - self.environment = Some(env); + /// Getter method to obtain signig authority (public key) of [ElementEct] + pub fn get_authority(&self) -> &Option>> { + &self.ect_common.authority + } + + /// Getter method to obtain environment map [ElementEct] + pub fn get_environment(&self) -> &Option> { + &self.ect_common.environment } - pub fn set_profile(&mut self, profile: ProfileTypeChoice<'a>) { - self.profile = Some(profile); + /// Getter method to obtain Eat profile of [ElementEct] + pub fn get_profile(&self) -> &Option> { + &self.ect_common.profile + } + + /// Merge Rule: + /// If two Element ECTs have the same environment, cmtype, authority and profile + /// then their element-lists are merged. Two element-maps containing duplicate codepoints + /// and with non-equivalent measurement values MUST NOT be merged. These are effectively + /// two different acceptable states that need to be processed separately. + pub fn merge_with(&mut self, other: &Self) -> bool { + if !self.is_matching(other) { + return false; + } + + if other.element_list.as_ref().is_none_or(Vec::is_empty) { + debug!("other element list is empty, nothing to merge"); + return true; + }; + + match self.element_list.as_mut() { + // self has no elements — just clone other's list directly + None => { + self.element_list = other.element_list.clone(); + } + Some(self_list) => { + // cloned() is required because mutuable reference can not be used as + // immutable which is required for creating hashset. + let existing: HashSet = self_list.iter().cloned().collect(); + + // Only push elements not already in self + for other_elt in other.element_list.as_ref().unwrap() { + if !existing.contains(other_elt) { + self_list.push(other_elt.clone()); + } + } + } + } + true + } + + fn is_matching(&self, other: &Self) -> bool { + self.get_environment() == other.get_environment() + && self.cmtype == other.cmtype + && self.get_authority() == other.get_authority() + && self.get_profile() == other.get_profile() } } -/// Allows construction of an [Ect] by chaining method calls. +/// Allows construction of an [ElementEct] by chaining method calls. #[derive(Default)] -pub struct EctBuilder<'a> { - environment: Option>, +pub struct ElementEctBuilder<'a> { + ect_common: EctCommon<'a>, element_list: Option>>, - authority: Option>>, - cm_type: Option, - profile: Option>, + cmtype: Option, } -impl<'a> EctBuilder<'a> { +impl<'a> ElementEctBuilder<'a> { pub fn new() -> Self { Self::default() } - /// Set the [CmType] of the [Ect]. - pub fn cm_type(mut self, cm_type: CmType) -> Self { - self.cm_type = Some(cm_type); + /// Set the [CmType] of the [ElementEct]. + pub fn cmtype(mut self, cmtype: CmType) -> Self { + self.cmtype = Some(cmtype); + self + } + + /// Set the environment of the [ElementEct]. + pub fn environment(mut self, env: EnvironmentMap<'a>) -> Self { + self.ect_common.environment = Some(env); + self + } + + /// Set the profile of the [ElementEct]. + pub fn profile(mut self, profile: ProfileTypeChoice<'a>) -> Self { + self.ect_common.profile = Some(profile); self } - /// Set the element list of the [Ect]. + /// Set the authority of the [ElementEct]. + pub fn authority(mut self, authority: Vec>) -> Self { + self.ect_common.authority = Some(authority); + self + } + + /// Set the element list of the [ElementEct]. pub fn element_list(mut self, element_list: Vec>) -> Self { self.element_list = Some(element_list); self } - /// Add an element to the [Ect]'s element list, creating the list if doesn't already exit. - pub fn add_element(mut self, elt: ElementMap<'a>) -> Self { + /// Add a key to the authority of the [ElementEct]. + pub fn add_authority(&mut self, authority: CryptoKeyTypeChoice<'a>) { + if let Some(auth_list) = self.ect_common.authority.as_mut() { + auth_list.push(authority); + } else { + self.ect_common.authority = Some(vec![authority]); + } + } + + /// Add an element to the [ElementEct]'s element list, creating the list if doesn't already exit. + pub fn add_element(&mut self, elt: ElementMap<'a>) { if let Some(elt_list) = self.element_list.as_mut() { elt_list.push(elt); } else { self.element_list = Some(vec![elt]); } - self } - /// Set the authority of the [Ect]. + /// Construct the [Element-Ect] from the values set with then [ElementEctBuilder]. + pub fn build(self) -> Result, Error> { + Ok(ElementEct { + cmtype: self.cmtype, + ect_common: self.ect_common, + element_list: self.element_list, + }) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub enum KeyType { + AttestKey, + IdentityKey, +} + +impl TryFrom<&str> for KeyType { + type Error = Error; + + fn try_from(value: &str) -> Result { + match value { + "attest-key" => Ok(Self::AttestKey), + "identity-key" => Ok(Self::IdentityKey), + s => Err(Error::invalid_value( + s.to_string(), + "a valid KeyType: \"attest-key\" or \"identity-key\"", + )), + } + } +} + +impl TryFrom for KeyType { + type Error = Error; + + fn try_from(value: i64) -> Result { + match value { + 0 => Ok(Self::AttestKey), + 1 => Ok(Self::IdentityKey), + n => Err(Error::invalid_value( + n, + "an integer 0-1 indicating the key ECT type", + )), + } + } +} + +impl From<&KeyType> for i64 { + fn from(value: &KeyType) -> Self { + match value { + KeyType::AttestKey => 0, + KeyType::IdentityKey => 1, + } + } +} + +impl Display for KeyType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let text = match self { + KeyType::AttestKey => "attest-key", + KeyType::IdentityKey => "identity-key", + }; + + f.write_str(text) + } +} + +impl Serialize for KeyType { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + if serializer.is_human_readable() { + self.to_string().serialize(serializer) + } else { + i64::from(self).serialize(serializer) + } + } +} + +impl<'de> Deserialize<'de> for KeyType { + fn deserialize(deserializer: D) -> Result + where + D: de::Deserializer<'de>, + { + if deserializer.is_human_readable() { + String::deserialize(deserializer)? + .as_str() + .try_into() + .map_err(de::Error::custom) + } else { + i64::deserialize(deserializer)? + .try_into() + .map_err(de::Error::custom) + } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize, Default)] +#[serde(rename_all = "kebab-case")] +pub struct KeyEct<'a> { + #[serde(flatten)] + pub ect_common: EctCommon<'a>, + /// The key identifier within the target environment. + /// "mkey" in comid triple is named as key-id in ECT + #[serde(skip_serializing_if = "Option::is_none")] + pub key_id: Option>, + /// The set of keys associated with the environment. + #[serde(skip_serializing_if = "Option::is_none")] + pub key_list: Option>>, + /// The semantic type of the keys in the tuple. + #[serde(skip_serializing_if = "Option::is_none")] + pub key_type: Option, +} + +impl<'a> KeyEct<'a> { + pub fn new() -> Self { + KeyEct::default() + } + pub fn authority(mut self, authority: Vec>) -> Self { - self.authority = Some(authority); + self.ect_common.authority = Some(authority); + self + } + + pub fn environment(mut self, env: EnvironmentMap<'a>) -> Self { + self.ect_common.environment = Some(env); + self + } + + pub fn profile(mut self, profile: ProfileTypeChoice<'a>) -> Self { + self.ect_common.profile = Some(profile); self } - /// Add a key to the authority of the [Ect]. - pub fn add_authority(mut self, authority: CryptoKeyTypeChoice<'a>) -> Self { - if let Some(auth_list) = self.authority.as_mut() { + pub fn key_id(mut self, key_id: MeasuredElementTypeChoice<'a>) -> Self { + self.key_id = Some(key_id); + self + } + + pub fn key_type(mut self, key_type: KeyType) -> Self { + self.key_type = Some(key_type); + self + } + + pub fn key_list(mut self, key_list: Vec>) -> Self { + self.key_list = Some(key_list); + self + } + + pub fn add_authority(&mut self, authority: CryptoKeyTypeChoice<'a>) { + if let Some(auth_list) = self.ect_common.authority.as_mut() { auth_list.push(authority); } else { - self.authority = Some(vec![authority]); + self.ect_common.authority = Some(vec![authority]); + } + } + + pub fn add_key(&mut self, key: CryptoKeyTypeChoice<'a>) { + if let Some(keys) = self.key_list.as_mut() { + keys.push(key); + } else { + self.key_list = Some(vec![key]); } + } + + pub fn get_authority(&self) -> &Option>> { + &self.ect_common.authority + } + + pub fn get_environment(&self) -> &Option> { + &self.ect_common.environment + } + + pub fn get_profile(&self) -> &Option> { + &self.ect_common.profile + } +} + +#[derive(Default)] +pub struct KeyEctBuilder<'a> { + ect_common: EctCommon<'a>, + // "mkey" in comid triple is named as key-id in ECT + key_id: Option>, + key_list: Option>>, + key_type: Option, +} + +impl<'a> KeyEctBuilder<'a> { + pub fn new() -> Self { + Self::default() + } + + pub fn key_type(mut self, key_type: KeyType) -> Self { + self.key_type = Some(key_type); self } - /// Set the environment of the [Ect]. + pub fn authority(mut self, authority: Vec>) -> Self { + self.ect_common.authority = Some(authority); + self + } pub fn environment(mut self, env: EnvironmentMap<'a>) -> Self { - self.environment = Some(env); + self.ect_common.environment = Some(env); self } - /// Set the profile of the [Ect]. pub fn profile(mut self, profile: ProfileTypeChoice<'a>) -> Self { - self.profile = Some(profile); + self.ect_common.profile = Some(profile); + self + } + + pub fn key_id(mut self, key_id: MeasuredElementTypeChoice<'a>) -> Self { + self.key_id = Some(key_id); + self + } + + pub fn key_list(mut self, key_list: Vec>) -> Self { + self.key_list = Some(key_list); self } - /// Construct the [Ect] from the values set with then [EctBuilder]. - pub fn build(self) -> Result, Error> { - if self.cm_type.is_none() { - return Err(Error::missing_field("Ect", "cm_type")); + pub fn add_authority(&mut self, authority: CryptoKeyTypeChoice<'a>) { + if let Some(auth_list) = self.ect_common.authority.as_mut() { + auth_list.push(authority); + } else { + self.ect_common.authority = Some(vec![authority]); } + } - Ok(Ect { - cm_type: self.cm_type.unwrap(), - authority: self.authority, - environment: self.environment, - profile: self.profile, - element_list: self.element_list, + pub fn add_key(&mut self, key: CryptoKeyTypeChoice<'a>) { + if let Some(keys) = self.key_list.as_mut() { + keys.push(key); + } else { + self.key_list = Some(vec![key]); + } + } + + pub fn build(self) -> Result, Error> { + Ok(KeyEct { + ect_common: self.ect_common, + key_id: self.key_id, + key_list: self.key_list, + key_type: self.key_type, }) } } +// TODO: Implement Domain Membership (M)-ECT and Trust Dependency (T)-ECT + #[cfg(test)] mod test { use std::collections::BTreeMap; @@ -287,35 +683,95 @@ mod test { const PSA_REFVAL_SIGNER_ID: Integer = Integer(5); #[test] - fn ect_serialize() { - let ect: Ect = Ect { - cm_type: CmType::Endorsements, - environment: Some( - EnvironmentMapBuilder::default() - .class( - ClassMapBuilder::default() - .class_id(ClassIdTypeChoice::Extension(ExtensionValue::Tag( - PSA_IMPL_ID, - Box::new(ExtensionValue::Bytes(Bytes::from(vec![ - 0x61, 0x63, 0x6d, 0x65, 0x2d, 0x69, 0x6d, 0x70, 0x6c, 0x65, - 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, - 0x69, 0x64, 0x2d, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x31, - ]))), - ))) - .layer(0.into()) - .build() - .unwrap(), - ) - .build() - .unwrap(), - ), - authority: Some(vec![CryptoKeyTypeChoice::CertThumbprint( - CertThumbprintType::from(Digest { - alg: HashAlgorithm::Sha256, - val: Bytes::from([0x01, 0x02, 0x03].as_slice()), - }), - )]), + fn element_map_hash() { + let digest_a = Digest { + alg: HashAlgorithm::Sha256, + val: Bytes::from(vec![0x0a, 0x0b, 0x0c]), + }; + let digest_b = Digest { + alg: HashAlgorithm::Sha256, + val: Bytes::from(vec![0x0d, 0x0e, 0x0f]), + }; + let digest_c = Digest { + alg: HashAlgorithm::Sha256, + val: Bytes::from(vec![0x0c, 0x0a, 0x0b]), + }; + + let el_map1 = ElementMap { + mkey: Some("cca.item".into()), + mval: MeasurementValuesMapBuilder::default() + .digest(vec![digest_a.clone()]) + .build() + .unwrap(), + }; + + let el_map2 = ElementMap { + mkey: Some("cca.item".into()), + mval: MeasurementValuesMapBuilder::default() + .digest(vec![digest_b.clone()]) + .build() + .unwrap(), + }; + let el_map3 = ElementMap { + mkey: Some("cca.other".into()), + mval: MeasurementValuesMapBuilder::default() + .digest(vec![digest_b.clone()]) + .build() + .unwrap(), + }; + + let el_map4 = ElementMap { + mkey: Some("cca.other".into()), + mval: MeasurementValuesMapBuilder::default() + .digest(vec![digest_c.clone()]) + .build() + .unwrap(), + }; + + let el_list = [el_map1.clone(), el_map2.clone(), el_map3.clone()]; + + let el_hashset: HashSet<&ElementMap> = el_list.iter().collect(); + assert!(el_hashset.contains(&el_map1)); + assert!(el_hashset.contains(&el_map2)); + assert!(el_hashset.contains(&el_map3)); + assert!(!el_hashset.contains(&el_map4)); + } + + #[test] + fn element_ect_serialize() { + let ect: ElementEct = ElementEct { + cmtype: Some(CmType::Endorsements), + ect_common: EctCommon { + environment: Some( + EnvironmentMapBuilder::default() + .class( + ClassMapBuilder::default() + .class_id(ClassIdTypeChoice::Extension(ExtensionValue::Tag( + PSA_IMPL_ID, + Box::new(ExtensionValue::Bytes(Bytes::from(vec![ + 0x61, 0x63, 0x6d, 0x65, 0x2d, 0x69, 0x6d, 0x70, 0x6c, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, + 0x69, 0x64, 0x2d, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x31, + ]))), + ))) + .layer(0.into()) + .build() + .unwrap(), + ) + .build() + .unwrap(), + ), + authority: Some(vec![CryptoKeyTypeChoice::CertThumbprint( + CertThumbprintType::from(Digest { + alg: HashAlgorithm::Sha256, + val: Bytes::from([0x01, 0x02, 0x03].as_slice()), + }), + )]), + profile: Some(ProfileTypeChoice::Uri(Uri::from(Text::from( + "http://arm.com/psa/iot/1", + )))), + }, element_list: Some(vec![ElementMap { mkey: Some(MeasuredElementTypeChoice::Extension(ExtensionValue::Tag( PSA_REFVAL_ID, @@ -350,25 +806,23 @@ mod test { .build() .unwrap(), }]), - profile: Some(ProfileTypeChoice::Uri(Uri::from(Text::from( - "http://arm.com/psa/iot/1", - )))), }; let actual = serde_json::to_string(&ect).unwrap(); + println!("{}:", actual); - let expected = r#"{"environment":{"class":{"class-id":{"tag":600,"value":"[base64]:YWNtZS1pbXBsZW1lbnRhdGlvbi1pZC0wMDAwMDAwMDE"},"layer":0}},"element-list":[{"mkey":{"tag":601,"value":{"1":"BL","4":"1.2.3","5":"[base64]:rLsRx-TaIXIFUjzkzhokWuGiOa48a_2eeHH35di66Gs"}},"mval":{"digests":["sha-256;AmOCmYm2_ZVPcrqvL8ZLwuLwHWktTecphuqAj26ZgT8"]}}],"authority":[{"type":"cert-thumbprint","value":"sha-256;AQID"}],"cm-type":"endorsements","profile":{"type":"uri","value":"http://arm.com/psa/iot/1"}}"#; + let expected = r#"{"environment":{"class":{"class-id":{"tag":600,"value":"[base64]:YWNtZS1pbXBsZW1lbnRhdGlvbi1pZC0wMDAwMDAwMDE"},"layer":0}},"authority":[{"type":"cert-thumbprint","value":"sha-256;AQID"}],"profile":{"type":"uri","value":"http://arm.com/psa/iot/1"},"element-list":[{"mkey":{"tag":601,"value":{"1":"BL","4":"1.2.3","5":"[base64]:rLsRx-TaIXIFUjzkzhokWuGiOa48a_2eeHH35di66Gs"}},"mval":{"digests":["sha-256;AmOCmYm2_ZVPcrqvL8ZLwuLwHWktTecphuqAj26ZgT8"]}}],"cmtype":"endorsements"}"#; assert_eq!(actual, expected); } #[test] - fn ect_deserialize() { + fn element_ect_deserialize() { let text = std::fs::read_to_string("test/policy/cca-platform/input.json").unwrap(); - let ects: Vec = serde_json::from_str(&text).unwrap(); + let ects: Vec = serde_json::from_str(&text).unwrap(); assert_eq!(ects.len(), 4); - assert_eq!(ects[0].cm_type, CmType::Evidence); + assert_eq!(ects[0].cmtype, Some(CmType::Evidence)); let digest = &ects[0].element_list.as_ref().unwrap()[2] .mval @@ -388,4 +842,118 @@ mod test { } ); } + + #[test] + fn element_ect_merge_rule() { + let env = EnvironmentMapBuilder::default() + .class( + ClassMapBuilder::default() + .class_id(ClassIdTypeChoice::Bytes(Bytes::from(vec![1, 2, 3]).into())) + .build() + .unwrap(), + ) + .build() + .unwrap(); + + let profile = ProfileTypeChoice::Uri(Uri::from(Text::from("https://example.test/profile"))); + let authority = vec![CryptoKeyTypeChoice::CertThumbprint( + CertThumbprintType::from(Digest { + alg: HashAlgorithm::Sha256, + val: Bytes::from(vec![0x01, 0x02, 0x03]), + }), + )]; + + let digest_a = Digest { + alg: HashAlgorithm::Sha256, + val: Bytes::from(vec![0x0a, 0x0b, 0x0c]), + }; + let digest_b = Digest { + alg: HashAlgorithm::Sha256, + val: Bytes::from(vec![0x0d, 0x0e, 0x0f]), + }; + + let ect1 = Ect::from(ElementEct { + ect_common: EctCommon { + environment: Some(env.clone()), + authority: Some(authority.clone()), + profile: Some(profile.clone()), + }, + element_list: Some(vec![ElementMap { + mkey: Some("cca.item".into()), + mval: MeasurementValuesMapBuilder::default() + .digest(vec![digest_a.clone()]) + .build() + .unwrap(), + }]), + cmtype: Some(CmType::Evidence), + }); + + let ect2 = Ect::from(ElementEct { + ect_common: EctCommon { + environment: Some(env.clone()), + authority: Some(authority.clone()), + profile: Some(profile.clone()), + }, + element_list: Some(vec![ + ElementMap { + mkey: Some("cca.item".into()), + mval: MeasurementValuesMapBuilder::default() + .digest(vec![digest_a.clone()]) + .build() + .unwrap(), + }, + ElementMap { + mkey: Some("cca.item".into()), + mval: MeasurementValuesMapBuilder::default() + .digest(vec![digest_b.clone()]) + .build() + .unwrap(), + }, + ElementMap { + mkey: Some("cca.other".into()), + mval: MeasurementValuesMapBuilder::default() + .digest(vec![digest_b.clone()]) + .build() + .unwrap(), + }, + ]), + cmtype: Some(CmType::Evidence), + }); + + let merged = Ect::merge_similar_ects(vec![ect1, ect2]); + + assert_eq!(merged.len(), 1); + let merged_ect = &merged[0]; + let items = merged_ect + .as_element_ect() + .unwrap() + .element_list + .as_ref() + .unwrap(); + assert_eq!(items.len(), 3); + assert!(items.iter().any(|i| { + i.mkey == Some("cca.item".into()) + && i.mval + == MeasurementValuesMapBuilder::default() + .digest(vec![digest_a.clone()]) + .build() + .unwrap() + })); + assert!(items.iter().any(|i| { + i.mkey == Some("cca.item".into()) + && i.mval + == MeasurementValuesMapBuilder::default() + .digest(vec![digest_b.clone()]) + .build() + .unwrap() + })); + assert!(items.iter().any(|i| { + i.mkey == Some("cca.other".into()) + && i.mval + == MeasurementValuesMapBuilder::default() + .digest(vec![digest_b.clone()]) + .build() + .unwrap() + })); + } } diff --git a/src/lib/keystore.rs b/src/lib/keystore.rs index 509f530..220f6b9 100644 --- a/src/lib/keystore.rs +++ b/src/lib/keystore.rs @@ -94,7 +94,7 @@ impl MemKeyStore { impl KeyStore for MemKeyStore { fn add(&mut self, kid: &[u8], key: &[u8]) -> Result<()> { - debug!("adding kid {:x?}", kid); + debug!("Adding into Memory Key Store, kid: {:x?}", kid); self.items.insert(kid.to_vec(), key.to_vec()); Ok(()) } @@ -119,3 +119,59 @@ impl Default for MemKeyStore { Self::new() } } + +#[cfg(test)] +mod tests { + use super::*; + use std::{ + fs, + path::PathBuf, + process, + time::{SystemTime, UNIX_EPOCH}, + unreachable, + }; + + fn temp_dir() -> PathBuf { + let unique = SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_nanos(); + std::env::temp_dir().join(format!("cover-keystore-{unique}-{}", process::id())) + } + + #[test] + fn mem_keystore_round_trips_values_and_removes_them() { + let mut store = MemKeyStore::new(); + + store.add(b"kid-1", b"secret-value").unwrap(); + assert_eq!(store.get(b"kid-1").unwrap(), b"secret-value".as_slice()); + + store.delete(b"kid-1").unwrap(); + assert!(matches!(store.get(b"kid-1"), Err(Error::KidNotFound(_)))); + } + + #[test] + fn fs_keystore_round_trips_values_and_removes_them() { + let dir = temp_dir(); + fs::create_dir_all(&dir).unwrap(); + let mut store = FsKeyStore::create(dir.to_str().unwrap()).unwrap(); + + store.add(b"kid-1", b"secret-value").unwrap(); + assert_eq!(store.get(b"kid-1").unwrap(), b"secret-value".as_slice()); + + store.delete(b"kid-1").unwrap(); + assert!(store.get(b"kid-1").is_err()); + + fs::remove_dir_all(&dir).unwrap(); + } + + #[test] + fn fs_keystore_create_rejects_missing_directory() { + let dir = temp_dir(); + let res = FsKeyStore::create(dir.to_str().unwrap()); + match res { + Err(err) => assert!(matches!(err, Error::Custom(_))), + Ok(_) => unreachable!(), + } + } +} diff --git a/src/lib/lib.rs b/src/lib/lib.rs index fb37140..80e62cc 100644 --- a/src/lib/lib.rs +++ b/src/lib/lib.rs @@ -1,99 +1,111 @@ +//! # cover +//! //! Cover (COrim VERifier) is an implementation of CoRIM-based verifier as outline in CoRIM draft -//! spec (rev 8.) Section 9\[[1]\]. It attempts follow the outlined algorithm up to phase 4 (ACS -//! generation). In lieu of subsequent phases, it uses a Rego-based policy engine for policy +//! spec (rev 11) Section 8\[[1]\]. It follows the outlined algorithm up to phase 4 (ACS generation). +//! In lieu of subsequent phases, it uses a Rego-based policy engine for policy //! evaluation, and generates an attestation result in EAR\[[2]\] format. //! //! This implementation is intended as a Proof-of-Concept only. It has the following limitations: +//! //! - Arm CCA is the only attestation scheme that is currently implemented. -//! - Only signed CoRIMs are supported. //! - Only basic in-memory implementation of key and CoRIM stores are implemented. //! -//! The verification flow proceeds as follows. +//! ## Verification Flow +//! +//! The verification flow proceeds as follows: //! -//! - CoRIMs are processed by validating their signatures and extracting contained measurements -//! into the "corim store" as RV (reference values), EV (endorsed values), and EVS (endorsed -//! values series) relations. +//! - CoRIMs are processed by validating their signatures for signed CoRIMs and extracting contained +//! measurements into the "corim store" as RV (reference values), EV (endorsed values) or Key relations. +//! - Unsigned CoRIM verification is not done and it is assumed that user has already verified the +//! CoRIMs before passing into the verifier. //! - The signature on the evidence is verified using a trust anchor obtained from the corim store //! based on an identifier inside the evidence. This is scheme-specific. For CCA, the instance ID //! is used. Evidence claims are then extracted as ECT (environment-claims tuple) records. //! - The evidence ECTs are then matched to the relations in the corim store. This results in the -//! ACS (appraisal claims set) -- a vector of ECT records containing evidence claims and matched +//! ACS (appraisal claims set) - a vector of ECT records containing evidence claims and matched //! reference values and endorsements. //! - The ACS is used as an input into the policy engine along with scheme-specific policies. Each //! policy results in an appraisal containing an AR4SI\[[3]\] trust vector. //! - The appraisals are added to an attestation result in EAR\[[2]\] format. //! -//! [1]: https://www.ietf.org/archive/id/draft-ietf-rats-corim-08.html#name-example-verifier-algorithm -//! [2]: https://www.ietf.org/archive/id/draft-fv-rats-ear-05.html -//! [3]: https://www.ietf.org/archive/id/draft-ietf-rats-ar4si-09.html +//! [1]: https://www.ietf.org/archive/id/draft-ietf-rats-corim-11.html#name-reference-verifier +//! [2]: https://www.ietf.org/archive/id/draft-ietf-rats-ear-04.html +//! [3]: https://www.ietf.org/archive/id/draft-ietf-rats-ar4si-10.html //! //! -//! # API +//! ## API //! //! Verification flow consists of the following components: +//! //! - A key store that contains keys that are used to verify signatures on CoRIMs. The key for a -//! CoRIM is looked up from the store based on the `kid` inside the CoRIM. +//! CoRIM is looked up from the store based on the `kid` inside the CoRIM. For unsigned CoRIMs, +//! it is assumed that CoRIM is already verified by user and user provided pub key is used as +//! verifying authority of the CoRIM. //! - A CoRIM store that loads endorsements and reference values from CoRIMs. //! - A scheme that defines how evidence is processed to extract claims, and what policy is applied //! to create an attestation result. //! - A verifier that is actually responsible for appraising the evidence to generate an attestation //! result in EAR format. //! -//! ```rust -//! use std::fs; -//! use std::collections::HashMap; -//! use cover::{CcaScheme, CorimStore, KeyStore, MemKeyStore, MemCorimStore, Scheme, Verifier}; -//! -//! // load the key used to verify CoRIM signatures -//! let mut keystore = MemKeyStore::new(); -//! let key = fs::read("test/corim/key.pub.pem").unwrap(); -//! keystore.add("key.pub.pem".as_bytes(), &key).unwrap(); -//! -//! // load CoRIMs -//! let mut store = MemCorimStore::new(keystore); -//! for path in [ -//! "test/corim/signed-corim-cca-ref-plat.cbor", -//! "test/corim/signed-corim-cca-ref-realm.cbor", -//! "test/corim/signed-corim-cca-ta.cbor", -//! ] { -//! let bytes = fs::read(path).unwrap(); -//! store.add_bytes(&bytes).unwrap(); -//! } -//! -//! // load supported attestation schemes -//! let mut schemes = HashMap::new(); -//! let cca_scheme: Box = Box::new(CcaScheme::new()); -//! schemes.insert("cca".to_string(), cca_scheme); -//! -//! // create the verifier -//! let verifier = Verifier::new(store, schemes); -//! -//! // load evidence -//! let evidence = fs::read("test/cca/cca-token-01.cbor").unwrap(); -//! -//! /// appraise evidence and produce the attestation result -//! let result = verifier.verify("cca", evidence.as_slice(), None).unwrap(); -//! -//! // assert that appraisal status for all submods in the result is "affirming". -//! for (_, appraisal) in &result.ear.submods { -//! assert_eq!(appraisal.status.to_string(), "affirming"); -//! } -//! +//! ### Example +//! +//! ```no_run +//! use std::fs; +//! use std::collections::HashMap; +//! use cover::{CcaScheme, CorimStore, KeyStore, MemKeyStore, MemCorimStore, Scheme, Verifier}; +//! +//! // load the key used to verify CoRIM signatures +//! let mut keystore = MemKeyStore::new(); +//! let key = fs::read("test/corim/key.pub.pem").unwrap(); +//! keystore.add("key.pub.pem".as_bytes(), &key).unwrap(); +//! +//! // load CoRIMs +//! let mut store = MemCorimStore::new(keystore); +//! for path in [ +//! "test/corim/signed-corim-cca-ref-plat.cbor", +//! "test/corim/signed-corim-cca-ref-realm.cbor", +//! "test/corim/signed-corim-cca-ta.cbor", +//! ] { +//! let bytes = fs::read(path).unwrap(); +//! store.add_bytes(&bytes).unwrap(); +//! } +//! +//! // load supported attestation schemes +//! let mut schemes = HashMap::new(); +//! let cca_scheme: Box = Box::new(CcaScheme::new()); +//! schemes.insert("cca".to_string(), cca_scheme); +//! +//! // create the verifier +//! let verifier = Verifier::new(store, schemes); +//! +//! // load evidence +//! let evidence = fs::read("test/cca/cca-token-03.cbor").unwrap(); +//! +//! // appraise evidence and produce the attestation result +//! let result = verifier.verify("cca", evidence.as_slice(), None).unwrap(); +//! +//! // assert that appraisal status for all submods in the result is "affirming". +//! for (_, appraisal) in &result.ear.submods { +//! assert_eq!(appraisal.status.to_string(), "affirming"); +//! } //! ``` //! -//! # CLI +//! ## CLI //! -//! This crate includes the `cover-cli` executable that can be used to run the verifier, -//! producing an EAR serialized as JSON. +//! This crate includes the `cover-cli` executable that can be used to run the verifier, +//! producing an EAR serialized as JSON. //! //! ```bash -//! target/debug/cover-cli --corim-dir test/corim/ \ -//! --key test/corim/key.pub.pem --pretty test/cca/cca-token-01.cbor \ -//! --nonce adfadaewafewr32r --output cca-token-01.ear.json +//! target/debug/cover-cli --corim-dir test/corim/ \ +//! --key test/corim/key.pub.pem \ +//! --verifier-key test/corim/key.pub.pem \ +//! --pretty test/cca/cca-token-03.cbor \ +//! --nonce adfadaewafewr32r --output cca-token-03.ear.json //! ``` //! -//! use `-h` to see the full list of command line arguments. +//! Use `-h` to see the full list of command line arguments. //! + pub mod authority; pub mod cca; pub mod corim; @@ -107,10 +119,12 @@ pub mod verifier; pub use authority::jwk_to_crypto_key; pub use cca::CcaScheme; -pub use corim::{CorimStore, EvRelation, EvsRelation, MemCorimStore, RvRelation}; -pub use ect::{CmType, Ect, EctBuilder, ElementMap}; +pub use corim::{CorimStore, EvRelation, MemCorimStore, RvRelation}; +pub use ect::{ + CmType, Ect, ElementEct, ElementEctBuilder, ElementMap, KeyEct, KeyEctBuilder, KeyType, +}; pub use keystore::{FsKeyStore, KeyStore, MemKeyStore}; pub use policy::{Policy, appraise}; pub use result::{Error, Result}; pub use scheme::Scheme; -pub use verifier::{Verification, Verifier}; +pub use verifier::{VerificationResult, Verifier}; diff --git a/src/lib/policy.rs b/src/lib/policy.rs index 0a4ff19..ce0f9ec 100644 --- a/src/lib/policy.rs +++ b/src/lib/policy.rs @@ -1,12 +1,11 @@ use std::fs; use std::io; +use crate::result::Error; use anyhow::Result; use ear::{Appraisal, RawValue}; use regorus::{Engine, Value}; -use crate::result::Error; - /// A [Policy] describes how inputs should be evaluated to generated an attestation result. /// Policy rules are writen using [Rego policy /// language](https://www.openpolicyagent.org/docs/policy-language). @@ -49,12 +48,12 @@ use crate::result::Error; /// /// refvals contains ect if { /// ect = platform[_] -/// ect["cm-type"] == "reference-values" +/// ect["cmtype"] == "reference-values" /// } /// /// evidence contains ect if { /// ect = platform[_] -/// ect["cm-type"] == "evidence" +/// ect["cmtype"] == "evidence" /// } /// /// # NOTE: APPROVED_CONFIG and UNSAFE_CONFIG are defined in the preamble @@ -100,11 +99,13 @@ const PREAMBLE: &str = include_str!("preamble.rego"); pub fn appraise(input: &str, policy: &Policy) -> Result { let mut engine = Engine::new(); - engine.add_policy("preamble".to_string(), PREAMBLE.to_string())?; + let policy_id = "preamble".to_string(); + engine.add_policy(policy_id.clone(), PREAMBLE.to_string())?; engine.add_policy(policy.path.clone(), policy.text.clone())?; engine.set_input(Value::from_json_str(input)?); let mut appraisal = Appraisal::new(); + appraisal.policy_ids = vec![policy_id, policy.id.clone()]; appraisal.status = engine .eval_rule("data.policy.status".to_string())? .as_i8()? @@ -149,9 +150,10 @@ pub fn appraise(input: &str, policy: &Policy) -> Result { .eval_rule("data.policy.sourced_data".to_string())? .as_i8()?, ); + appraisal.update_status_from_trust_vector(); - appraisal.policy_claims = + appraisal.verifier_claims = match rego_to_ear(engine.eval_rule("data.policy.policy_claims".to_string())?) { RawValue::Map(m) => m .iter() @@ -196,7 +198,6 @@ fn rego_to_ear(val: Value) -> RawValue { #[cfg(test)] mod test { - use std::fs; use std::path::Path; use ear::Appraisal; diff --git a/src/lib/result.rs b/src/lib/result.rs index f47f6a9..164fd1b 100644 --- a/src/lib/result.rs +++ b/src/lib/result.rs @@ -138,4 +138,10 @@ impl From for Error { } } +impl From for Error { + fn from(value: cmw::Error) -> Self { + Self::Custom(value.to_string()) + } +} + pub type Result = std::result::Result; diff --git a/src/lib/scheme.rs b/src/lib/scheme.rs index 298b0ef..b76a5fe 100644 --- a/src/lib/scheme.rs +++ b/src/lib/scheme.rs @@ -1,29 +1,71 @@ -use corim_rs::{CryptoKeyTypeChoice, EnvironmentMap}; +use log::debug; +use corim_rs::{Corim, CryptoKeyTypeChoice, EnvironmentMap, ProfileTypeChoice}; + +use crate::corim::is_rim_valid; use crate::ect::Ect; use crate::policy::Policy; -use crate::result::Error; +use crate::result::Result; /// Scheme represents a verifier scheme. It handles tasks that require domain-specific knowledge, /// such as parsing attestation evidence and providing a policy for its appraisal. pub trait Scheme { /// The name of the scheme. Used specify the scheme to the verifier. fn name(&self) -> String; + /// Profile that will be set in the attestation result when this scheme is used. fn profile(&self) -> String; + + /// Return supported Corim profiles for endorsements. + fn get_supported_corim_profiles(&self) -> Vec; + + /// Return true when the CoRIM profile is compatible with this scheme. + // Scheme not supporting use of Profile in corim do not need to use this method. + fn supports_profile(&self, profile: Option<&ProfileTypeChoice<'_>>) -> bool { + let scheme_supported_profiles = self.get_supported_corim_profiles(); + + if scheme_supported_profiles.is_empty() && profile.is_none() { + debug!( + "Input CoRIM profile field is empty and scheme does not support profile field in Corim CDDL" + ); + return true; + } + let corim_profile = match profile { + Some(ProfileTypeChoice::Uri(uri)) => uri.to_string(), + Some(ProfileTypeChoice::Oid(oid)) => oid.to_string(), + _ => { + debug!("Extension value not supported"); + return false; + } + }; + + for p in self.get_supported_corim_profiles() { + if corim_profile == p { + return true; + } + } + debug!("Unsupported profile \"{}\" ", corim_profile); + false + } + + fn supports_corim(&self, corim: &Corim<'_>) -> bool { + self.supports_profile(corim.as_map_ref().profile.as_ref()) + && is_rim_valid(corim.as_map_ref().rim_validity.as_ref()) + } + /// Indicates whether the specified input matches the evidence format expected by the scheme. /// This maybe used to "guess" which scheme should be used for evaluating evidence when one is /// not identified by name. fn match_evidence(&self, evidence: &[u8]) -> bool; /// Get trust anchor id from the evidence. This is used to obtain a trust anchor that may be /// used to validate the evidence signature. - fn get_trust_anchor_id<'a>(&self, evidence: &[u8]) -> Result, Error>; + fn get_trust_anchor_id<'a>(&self, evidence: &[u8]) -> Result>; /// Validate evidence using provided trust anchor, and parse it into a series of [Ect]s. fn validate_and_parse_evidence<'a>( &self, evidence: &[u8], - trust_anchor: &CryptoKeyTypeChoice<'a>, - ) -> Result>, Error>; + trust_anchors: &[CryptoKeyTypeChoice<'a>], + ) -> Result>>; /// Get [Policy] instances associated with the scheme. fn get_policies(&self) -> Vec; } diff --git a/src/lib/util.rs b/src/lib/util.rs index 5d3d627..db44e67 100644 --- a/src/lib/util.rs +++ b/src/lib/util.rs @@ -11,7 +11,7 @@ pub fn b64decode(v: &str) -> Result, Error> { // Helper function to convert PEM-encoded SubjectPublicKeyInfo into JWK pub fn pem_spki_to_jwk_string(pem_bytes: &[u8]) -> Result { - use elliptic_curve::sec1::{FromEncodedPoint, ModulusSize, ToEncodedPoint}; + use elliptic_curve::sec1::{FromSec1Point, ModulusSize, ToSec1Point}; use elliptic_curve::{AffinePoint, CurveArithmetic, FieldBytesSize}; use elliptic_curve::{PublicKey as EcPublicKey, pkcs8::DecodePublicKey}; use p256::NistP256; @@ -36,10 +36,10 @@ pub fn pem_spki_to_jwk_string(pem_bytes: &[u8]) -> Result { fn extract_ec_point_x_y(ec_pub: EcPublicKey) -> Result<(String, String), Error> where C: CurveArithmetic, - AffinePoint: FromEncodedPoint + ToEncodedPoint, + AffinePoint: FromSec1Point + ToSec1Point, FieldBytesSize: ModulusSize, { - let point = ec_pub.to_encoded_point(false); + let point = ec_pub.to_sec1_point(false); if let Some(x) = point.x() && let Some(y) = point.y() { @@ -133,22 +133,15 @@ mod test { #[test] fn pem_to_jwk_256() { - let pem_bytes = include_bytes!("../../test/keys/pkey_256.pem"); - let expected_jwk = include_str!("../../test/keys/pkey_256.json"); + let pem_bytes = include_bytes!("../../test/cca/keys/iak-ec256.pub.pem"); + let expected_jwk = include_str!("../../test/cca/keys/iak-ec256.pub.json"); pem_to_jwk(pem_bytes, expected_jwk); } #[test] fn pem_to_jwk_384() { - let pem_bytes = include_bytes!("../../test/keys/pkey_384.pem"); - let expected_jwk = include_str!("../../test/keys/pkey_384.json"); - pem_to_jwk(pem_bytes, expected_jwk); - } - - #[test] - fn pem_to_jwk_521() { - let pem_bytes = include_bytes!("../../test/keys/pkey_521.pem"); - let expected_jwk = include_str!("../../test/keys/pkey_521.json"); + let pem_bytes = include_bytes!("../../test/cca/keys/rak-ec384.pub.pem"); + let expected_jwk = include_str!("../../test/cca/keys/rak-ec384.pub.json"); pem_to_jwk(pem_bytes, expected_jwk); } } diff --git a/src/lib/verifier.rs b/src/lib/verifier.rs index b9f81e6..f708c7e 100644 --- a/src/lib/verifier.rs +++ b/src/lib/verifier.rs @@ -1,26 +1,28 @@ use std::{ collections::{BTreeMap, HashMap}, + str::FromStr, time::{SystemTime, UNIX_EPOCH}, }; use base64::{self, Engine as _, engine::general_purpose::URL_SAFE_NO_PAD}; +use cmw::{CMW, Indicator, Mime, Monad}; use corim_rs::{ConciseRimTypeChoice, CryptoKeyTypeChoice, EnvironmentMap}; -use ear::{Appraisal, Ear, Extensions, VerifierID}; +use ear::{Appraisal, EAR_PROFILE, Ear, VerifierID}; use crate::{ - corim::{CorimStore, INTERP_KEYS_EXT_ID, KeyType, TypedCryptoKey}, - ect::Ect, + corim::CorimStore, + ect::{Ect, ElementEct}, policy::{Policy, appraise}, result::{Error, Result}, scheme::Scheme, }; -/// A Verification is produced by the [Verifier] when verifying evidence. +/// A VerificationResult is produced by the [Verifier] when verifying evidence. #[derive(Debug)] -pub struct Verification<'a> { +pub struct VerificationResult<'a> { /// The result of evidence verification in EAR (EAT Attestation Result) format. pub ear: Ear, - /// The ACS containing imputs used in [Policy] eveluation. + /// The ACS containing imputs used in [Policy] evaluation. pub acs: Vec>, /// [Policy] instances evaluated to generate the attestation result. pub policies: Vec, @@ -65,63 +67,76 @@ impl<'a, S: CorimStore<'a>> Verifier<'a, S> { scheme_name: &str, evidence: &[u8], nonce: Option<&[u8]>, - ) -> Result> { + ) -> Result> { let scheme = self .get_scheme(scheme_name) .ok_or(Error::scheme_not_found(scheme_name))?; let ta_id = scheme.get_trust_anchor_id(evidence)?; - let trust_anchor = self.get_trust_anchor(&ta_id)?; + let trust_anchors = self.get_trust_anchors(&ta_id)?; - let mut evidence_ects = scheme.validate_and_parse_evidence(evidence, &trust_anchor)?; - - let mut ref_vals = self.match_reference_values(&evidence_ects); + let mut evidence_ects = scheme.validate_and_parse_evidence(evidence, &trust_anchors)?; let mut acs = Vec::new(); acs.append(&mut evidence_ects); + + let mut ref_vals = self.match_reference_values(&acs); acs.append(&mut ref_vals); let mut ev_vals = self.match_endorsement_values(&acs); - acs.append(&mut ev_vals); + acs = Ect::merge_similar_ects(acs); + let acs_text = serde_json::to_string(&acs)?; let policies = scheme.get_policies(); - let ear = Ear { - profile: scheme.profile(), - iat: SystemTime::now() - .duration_since(UNIX_EPOCH)? - .as_secs() - .try_into()?, - vid: VerifierID { - build: format!("{} {}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION")), - developer: "https://veraison-project.org".to_string(), - }, - raw_evidence: Some(evidence.into()), - nonce: match nonce { - Some(bytes) => Some(URL_SAFE_NO_PAD.encode(bytes).try_into()?), - None => None, - }, - submods: policies - .iter() - .map(|pol| Ok((pol.id.clone(), appraise(&acs_text, pol)?))) - .collect::>>()?, - extensions: Extensions::new(), - }; + let mut ear = Ear::new(); - Ok(Verification { ear, acs, policies }) + ear.profile = EAR_PROFILE.to_string(); + ear.iat = SystemTime::now() + .duration_since(UNIX_EPOCH)? + .as_secs() + .try_into()?; + ear.vid = VerifierID { + build: format!("{} {}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION")), + developer: "https://veraison-project.org".to_string(), + }; + ear.raw_evidence = Some(CMW::Monad(Monad::new_media_type( + Mime::from_str("application/eat-cwt").unwrap(), + evidence.to_vec(), + Some(Indicator::EVIDENCE), + )?)); + ear.nonce = match nonce { + Some(bytes) => Some(URL_SAFE_NO_PAD.encode(bytes).try_into()?), + None => None, + }; + ear.submods = policies + .iter() + .map(|pol| Ok((pol.id.clone(), appraise(&acs_text, pol)?))) + .collect::>>()?; + Ok(VerificationResult { ear, acs, policies }) } /// Add a CoRIM to the verifier's store. pub fn add_corim(&mut self, corim: &ConciseRimTypeChoice<'a>) -> Result<()> { - self.corims.add(corim) + let supported = self + .schemes + .values() + .any(|scheme| scheme.as_ref().supports_corim(corim)); + + if supported { + self.corims.add(corim) + } else { + Err(Error::Custom("unsupported CoRIM input".to_string())) + } } /// Add CBOR-encoded CoRIM bytes to the verifier's store. pub fn add_corim_bytes(&mut self, corim: &'a [u8]) -> Result<()> { - self.corims.add_bytes(corim) + let corim = ConciseRimTypeChoice::from_cbor(corim)?; + self.add_corim(&corim) } /// Add an attestation [Scheme] to the verifier. @@ -130,76 +145,57 @@ impl<'a, S: CorimStore<'a>> Verifier<'a, S> { Ok(()) } - fn match_reference_values(&self, acs: &Vec>) -> Vec> { - let mut res: Vec = Vec::new(); + fn match_reference_values(&self, acs: &[Ect<'a>]) -> Vec> { + let mut res: Vec> = Vec::new(); for rv in self.corims.iter_rv() { for acs_ect in acs { + let Some(acs_ect) = acs_ect.as_element_ect() else { + continue; + }; + if !ect_match(&rv.condition, acs_ect) { continue; } let mut addition = rv.addition.clone(); addition.element_list = acs_ect.element_list.clone(); - res.push(addition); + res.push(Ect::from(addition)); } } res } - fn match_endorsement_values(&self, act: &Vec>) -> Vec> { - let mut res: Vec = Vec::new(); + fn match_endorsement_values(&self, act: &[Ect<'a>]) -> Vec> { + let mut res: Vec> = Vec::new(); for ev in self.corims.iter_ev() { let mut conditions_match = true; for cond in &ev.condition { + let mut matched = false; + for acs_ect in act { - if !ect_match(cond, acs_ect) { - conditions_match = false; + let Some(acs_ect) = acs_ect.as_element_ect() else { + continue; + }; + + if ect_match(cond, acs_ect) { + matched = true; break; } } - } - if conditions_match { - for add_ect in &ev.addition { - res.push(add_ect.clone()); - } - } - } - - for evs in self.corims.iter_evs() { - let mut conditions_match = true; - - for cond in &evs.condition { - for acs_ect in act { - if !ect_match(cond, acs_ect) { - conditions_match = false; - break; - } + if !matched { + conditions_match = false; + break; } } if conditions_match { - for entry in &evs.series { - for acs_ect in act { - let mut selection_matched = true; - for select in &entry.selection { - if !ect_match(select, acs_ect) { - selection_matched = false; - break; - } - } - - if selection_matched { - for add_ect in &entry.addition { - res.push(add_ect.clone()); - } - break; - } - } + for add_ect in &ev.addition { + res.push(Ect::from(add_ect.clone())); } } } @@ -211,62 +207,36 @@ impl<'a, S: CorimStore<'a>> Verifier<'a, S> { self.schemes.get(name).map(|s| s.as_ref()) } - fn get_trust_anchor(&self, id: &EnvironmentMap<'a>) -> Result> { - let mut found: Option = None; - - for ev in self.corims.iter_ev() { - for cond in &ev.condition { - if cond.environment.as_ref().unwrap().matches(id) - && let Some(elts) = &cond.element_list - { - for elt in elts { - if let Some(exts) = &elt.mval.extensions - && let Some(interp_keys_ext) = exts.get(INTERP_KEYS_EXT_ID.into()) - { - let interp_key = TypedCryptoKey::try_from(interp_keys_ext).unwrap(); - if interp_key.key_type == KeyType::AttestKey { - if found.is_some() { - return Err(Error::custom(format!( - "duplicate trust anchor for {:?}", - id - ))); - } - - found = Some(interp_key.key) - } - } - } - } + fn get_trust_anchors(&self, id: &EnvironmentMap<'a>) -> Result>> { + for kv in self.corims.iter_key() { + let cond = kv.condition; + if cond.get_environment().as_ref().unwrap().matches(id) + && let Some(elts) = cond.key_list + { + return Ok(elts); } } - - match found { - Some(key) => Ok(key), - None => Err(Error::custom(format!("no trust anchor found for {:?}", id))), - } + Err(Error::custom(format!("no trust anchor found for {:?}", id))) } } -fn ect_match(condition: &Ect, acs_ect: &Ect) -> bool { +fn ect_match(condition: &ElementEct, acs_ect: &ElementEct) -> bool { if !condition - .environment + .get_environment() .as_ref() .unwrap() - .matches(acs_ect.environment.as_ref().unwrap()) + .matches(acs_ect.get_environment().as_ref().unwrap()) { return false; } - // note: sect. 9.4.3 states authorities should be matched here, but it's not clear how given - // that evidence and reference/endorsement values obviously come from different sources... - for cond_elt in condition.element_list.as_ref().unwrap() { let mut elt_matched = false; - for act_elt in acs_ect.element_list.as_ref().unwrap() { - match (&cond_elt.mkey, &act_elt.mkey) { - (Some(rv_mkey), Some(act_mkey)) => { - if rv_mkey != act_mkey { + for acs_elt in acs_ect.element_list.as_ref().unwrap() { + match (&cond_elt.mkey, &acs_elt.mkey) { + (Some(rv_mkey), Some(acs_mkey)) => { + if rv_mkey != acs_mkey { continue; } } @@ -277,7 +247,7 @@ fn ect_match(condition: &Ect, acs_ect: &Ect) -> bool { (None, None) => (), } - if cond_elt.mval.matches(&act_elt.mval) { + if cond_elt.mval.matches(&acs_elt.mval) { elt_matched = true; break; } @@ -293,6 +263,7 @@ fn ect_match(condition: &Ect, acs_ect: &Ect) -> bool { #[cfg(test)] mod test { + use std::assert_eq; use std::collections::HashMap; use super::*; @@ -302,14 +273,15 @@ mod test { #[test] fn verifier_test() { - let corim_rv_plat = include_bytes!("../../test/corim/signed-corim-cca-ref-plat.cbor"); - let corim_rv_realm = include_bytes!("../../test/corim/signed-corim-cca-ref-realm.cbor"); - let corim_ta = include_bytes!("../../test/corim/signed-corim-cca-ta.cbor"); + let corim_rv_plat = include_bytes!("../../test/corim/signed-corim-cca-plat-rv.cbor"); + let corim_rv_realm = include_bytes!("../../test/corim/signed-corim-cca-realm-rv.cbor"); + let corim_ta = include_bytes!("../../test/corim/signed-corim-cca-plat-ta.cbor"); let key = include_bytes!("../../test/corim/key.pub.pem"); - let evidence = include_bytes!("../../test/cca/cca-token-01.cbor"); + let evidence = include_bytes!("../../test/cca/cca-token-03.cbor"); let mut keystore = MemKeyStore::new(); keystore.add("key.pub.pem".as_bytes(), key).unwrap(); + keystore.add("verifier-key".as_bytes(), key).unwrap(); let mut store = MemCorimStore::new(keystore); store.add_bytes(corim_rv_plat.as_slice()).unwrap(); @@ -327,4 +299,38 @@ mod test { assert_eq!(appraisal.status.to_string(), "affirming"); } } + + #[test] + fn add_corim_bytes_invalid_profile() { + let corim_inv_profile = + include_bytes!("../../test/corim/signed-corim-cca-plat-unsupported-profile.cbor"); + let key = include_bytes!("../../test/corim/key.pub.pem"); + let mut keystore = MemKeyStore::new(); + keystore.add("key.pub.pem".as_bytes(), key).unwrap(); + let store = MemCorimStore::new(keystore); + let mut schemes = HashMap::new(); + let cca_scheme: Box = Box::new(CcaScheme::new()); + schemes.insert("arm-cca".to_string(), cca_scheme); + let mut verifier = Verifier::new(store, schemes); + let _res = verifier.add_corim_bytes(corim_inv_profile); + assert_eq!(verifier.corims.items.rv_list.len(), 0); + assert_eq!(verifier.corims.items.ev_list.len(), 0); + assert_eq!(verifier.corims.items.key_list.len(), 0); + } + + #[test] + fn add_corim_bytes_expired_corim() { + let corim_inv_profile = + include_bytes!("../../test/corim/signed-corim-cca-plat-expired-validity.cbor"); + let key = include_bytes!("../../test/corim/key.pub.pem"); + let mut keystore = MemKeyStore::new(); + keystore.add("key.pub.pem".as_bytes(), key).unwrap(); + let store = MemCorimStore::new(keystore); + let mut schemes = HashMap::new(); + let cca_scheme: Box = Box::new(CcaScheme::new()); + schemes.insert("arm-cca".to_string(), cca_scheme); + let mut verifier = Verifier::new(store, schemes); + let _res = verifier.add_corim_bytes(corim_inv_profile); + assert_eq!(verifier.corims.items.rv_list.len(), 0); + } } diff --git a/test/cca/cca-claims-03.json b/test/cca/cca-claims-03.json new file mode 100644 index 0000000..069d793 --- /dev/null +++ b/test/cca/cca-claims-03.json @@ -0,0 +1,85 @@ +{ + "cca-platform-token": { + "cca-platform-profile": "tag:arm.com,2024:cca_platform#2.0.0", + "cca-platform-challenge": "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE=", + "cca-platform-implementation-id": "f0VMRgIBAQAAAAAAAAAAAAMAPgABAAAAUFgAAAAAAAA=", + "cca-platform-instance-id": "AQcGBQQDAgEADw4NDAsKCQgXFhUUExIREB8eHRwbGhkY", + "cca-platform-config": "AQcGBQQDAgEADw4NDAsKCQgXFhUUExIREB8eHRwbGhkY", + "cca-platform-lifecycle": 12291, + "cca-platform-sw-components": [ + { + "measurement-type": "BL", + "measurement-value": "BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg=", + "version": "3.4.2", + "signer-id": "BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg=", + "measurement-description": "sha-256" + }, + { + "measurement-type": "M1", + "measurement-value": "BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg=", + "version": "1.2", + "signer-id": "BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg=" + }, + { + "measurement-type": "M2", + "measurement-value": "BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg=", + "version": "1.2.3", + "signer-id": "BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg=" + }, + { + "measurement-type": "M3", + "measurement-value": "BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg=", + "version": "1", + "signer-id": "BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg=" + } + ], + "cca-platform-service-indicator": "https://veraison.example/v1/challenge-response", + "cca-platform-hash-algo-id": "sha-256", + "cca-platform-client-id": 1, + "cca-platform-manufacturing-config": "AQID", + "cca-platform-peer-signers": "BQUFBQU=", + "cca-platform-extension": [ + { + "hash-algo-id": "sha-256", + "device-measurements-digest": "3q2+796tvu/erb7v3q2+796tvu/erb7v3q2+796tvu8=", + "certificate-chain-digest": "3q2+796tvu/erb7v3q2+796tvu/erb7v3q2+796tvu/erb7v3q2+796tvu/erb7v3q2+796tvu/erb7v3q2+7w==", + "uses-ide": true, + "protocol": "spdm-1.2.0", + "vca-digest": "AAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P", + "device-type": "cxl-type-3", + "encryption-type": 0 + }, + { + "device-measurements-digest": "3q2+796tvu/erb7v3q2+796tvu/erb7v3q2+796tvu8=", + "certificate-chain-digest": "3q2+796tvu/erb7v3q2+796tvu/erb7v3q2+796tvu/erb7v3q2+796tvu/erb7v3q2+796tvu/erb7v3q2+7w==", + "uses-ide": true, + "protocol": "other-protocol-1.2.3", + "device-type": "other-device-2" + } + ], + "cca-platform-tbb-rotpk": [ + { + "name": "DM", + "active-array-index": 0, + "index": 0, + "hash": "BwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwc=" + } + ] + }, + "cca-realm-delegated-token": { + "cca-realm-profile": "tag:arm.com,2024:realm#2.0.0", + "cca-realm-challenge": "q6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urqw==", + "cca-realm-personalization-value": "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIDEzIGxhenkgZG9ncy5UaGUgcXVpY2sgYnJvd24gZm94IA==", + "cca-realm-initial-measurement": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", + "cca-realm-extensible-measurements": [ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" + ], + "cca-realm-hash-algo-id": "sha-256", + "cca-realm-public-key": "pCACIVgwgvvRMqm1w5aHn7sVNA2QUJeOVcedUnmiug6VhU834gzS9k87crVwu9dz7uLOdoQlIlgw7fVF7b6J/6/g6Wu9RuJw8geWxEi5ja9Gp2TSdELm5u2E+M7IF+bsxqcdOj3n1n7NAQI=", + "cca-realm-public-key-hash-algo-id": "sha-256", + "cca-realm-mec-policy": "private" + } +} \ No newline at end of file diff --git a/test/cca/cca-token-01.cbor b/test/cca/cca-token-01.cbor deleted file mode 100644 index e40f8b7..0000000 Binary files a/test/cca/cca-token-01.cbor and /dev/null differ diff --git a/test/cca/cca-token-03.cbor b/test/cca/cca-token-03.cbor new file mode 100644 index 0000000..6820525 Binary files /dev/null and b/test/cca/cca-token-03.cbor differ diff --git a/test/cca/keys/iak-ec256.priv.json b/test/cca/keys/iak-ec256.priv.json new file mode 100644 index 0000000..fe7009f --- /dev/null +++ b/test/cca/keys/iak-ec256.priv.json @@ -0,0 +1,7 @@ +{ + "kty": "EC", + "crv": "P-256", + "x": "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4", + "y": "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM", + "d": "870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE" +} diff --git a/test/cca/keys/iak-ec256.pub.json b/test/cca/keys/iak-ec256.pub.json new file mode 100644 index 0000000..53a6e4d --- /dev/null +++ b/test/cca/keys/iak-ec256.pub.json @@ -0,0 +1,6 @@ +{ + "kty": "EC", + "crv": "P-256", + "x": "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4", + "y": "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM" +} diff --git a/test/cca/keys/iak-ec256.pub.pem b/test/cca/keys/iak-ec256.pub.pem new file mode 100644 index 0000000..7da76d3 --- /dev/null +++ b/test/cca/keys/iak-ec256.pub.pem @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEMKBCTNIcKUSDii11ySs3526iDZ8A +iTo7Tu6KPAqv7D7gS2XpJFbZiItSs3m9+9Ue6GnvHw/GW2ZZaVtszggXIw== +-----END PUBLIC KEY----- diff --git a/test/cca/keys/rak-ec384.priv.json b/test/cca/keys/rak-ec384.priv.json new file mode 100644 index 0000000..cd97e3a --- /dev/null +++ b/test/cca/keys/rak-ec384.priv.json @@ -0,0 +1,8 @@ +{ + "kid": "example-rak", + "kty": "EC", + "crv": "P-384", + "x": "gvvRMqm1w5aHn7sVNA2QUJeOVcedUnmiug6VhU834gzS9k87crVwu9dz7uLOdoQl", + "y": "7fVF7b6J_6_g6Wu9RuJw8geWxEi5ja9Gp2TSdELm5u2E-M7IF-bsxqcdOj3n1n7N", + "d": "ODkwMTIzNDU2Nzg5MDEyMz7deMbyLt8g4cjcxozuIoygLLlAeoQ1AfM9TSvxkFHJ" +} \ No newline at end of file diff --git a/test/cca/keys/rak-ec384.pub.json b/test/cca/keys/rak-ec384.pub.json new file mode 100644 index 0000000..520b86b --- /dev/null +++ b/test/cca/keys/rak-ec384.pub.json @@ -0,0 +1,6 @@ +{ + "kty": "EC", + "crv": "P-384", + "x": "gvvRMqm1w5aHn7sVNA2QUJeOVcedUnmiug6VhU834gzS9k87crVwu9dz7uLOdoQl", + "y": "7fVF7b6J_6_g6Wu9RuJw8geWxEi5ja9Gp2TSdELm5u2E-M7IF-bsxqcdOj3n1n7N" +} \ No newline at end of file diff --git a/test/cca/keys/rak-ec384.pub.pem b/test/cca/keys/rak-ec384.pub.pem new file mode 100644 index 0000000..be71863 --- /dev/null +++ b/test/cca/keys/rak-ec384.pub.pem @@ -0,0 +1,6 @@ +-----BEGIN PUBLIC KEY----- +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEgvvRMqm1w5aHn7sVNA2QUJeOVcedUnmi +ug6VhU834gzS9k87crVwu9dz7uLOdoQl7fVF7b6J/6/g6Wu9RuJw8geWxEi5ja9G +p2TSdELm5u2E+M7IF+bsxqcdOj3n1n7N +-----END PUBLIC KEY----- + diff --git a/test/cca/pkey.json b/test/cca/pkey.json deleted file mode 100644 index 0cefd99..0000000 --- a/test/cca/pkey.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "crv": "P-384", - "kty": "EC", - "x": "IShnxS4rlQiwpCCpBWDzlNLfqiG911FP8akBr-fh94uxHU5m-Kijivp2r2oxxN6M", - "y": "hM4tr8mWQli1P61xh3T0ViDREbF26DGOEYfbAjWjGNN7pZf-6A4OTHYqEryz6m7U" -} diff --git a/test/cca/rebuild.sh b/test/cca/rebuild.sh new file mode 100755 index 0000000..0f2a0bd --- /dev/null +++ b/test/cca/rebuild.sh @@ -0,0 +1,18 @@ +rm -rf deps +mkdir deps + +pushd deps + +git clone https://github.com/veraison/evcli.git --depth 1 ./evcli.dir + +pushd evcli.dir +go build -o ../evcli main.go +popd + +popd + +./deps/evcli cca create \ + --claims=cca-claims-03.json \ + --iak=keys/iak-ec256.priv.json \ + --rak=keys/rak-ec384.priv.json \ + --token=cca-token-03.cbor \ No newline at end of file diff --git a/test/corim/corim-cca-plat-expired-validity.json b/test/corim/corim-cca-plat-expired-validity.json new file mode 100644 index 0000000..8d80605 --- /dev/null +++ b/test/corim/corim-cca-plat-expired-validity.json @@ -0,0 +1,135 @@ +{ + "id": "00000000-0000-0000-cca4-000000000000", + "profile": { + "type": "uri", + "value": "tag:arm.com,2025:endorsements/cca_platform#1.0.0" + }, + "rim-validity": { + "not-after": { + "type": "time", + "value": 1785495958 + } + }, + "tags": [ + { + "type": "comid", + "value": { + "language": "en-GB", + "tag-identity": { + "tag-id": "43bbe37f-2e61-4b33-aed3-53cff1428b16" + }, + "entities": [ + { + "entity-name": "ACME Ltd.", + "reg-id": { + "type": "uri", + "value": "https://acme.example" + }, + "role": [ + "tag-creator", + "creator", + "maintainer" + ] + } + ], + "triples": { + "reference-triples": [ + [ + { + "class": { + "class-id": { + "type": "bytes", + "value": "f0VMRgIBAQAAAAAAAAAAAAMAPgABAAAAUFgAAAAAAAA" + } + } + }, + [ + { + "mkey": "cca.platform-config", + "mval": { + "raw-value": { + "type": "bytes", + "value": "AQcGBQQDAgEADw4NDAsKCQgXFhUUExIREB8eHRwbGhkY" + } + } + }, + { + "mkey": "cca.software-component", + "mval": { + "name": "BL", + "version": { + "version": "3.4.2" + }, + "digests": [ + "sha-256;BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg" + ], + "cryptokeys": [ + { + "type": "bytes", + "value": "BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg" + } + ] + } + }, + { + "mkey": "cca.software-component", + "mval": { + "name": "M1", + "version": { + "version": "1.2" + }, + "digests": [ + "sha-256;BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg" + ], + "cryptokeys": [ + { + "type": "bytes", + "value": "BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg" + } + ] + } + }, + { + "mkey": "cca.software-component", + "mval": { + "name": "M2", + "version": { + "version": "1.2.3" + }, + "digests": [ + "sha-256;BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg" + ], + "cryptokeys": [ + { + "type": "bytes", + "value": "BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg" + } + ] + } + }, + { + "mkey": "cca.software-component", + "mval": { + "name": "M3", + "version": { + "version": "1" + }, + "digests": [ + "sha-256;BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg" + ], + "cryptokeys": [ + { + "type": "bytes", + "value": "BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg" + } + ] + } + } + ] + ] + ] + } + } + } + ] +} \ No newline at end of file diff --git a/test/corim/corim-cca-plat-rv.cbor b/test/corim/corim-cca-plat-rv.cbor new file mode 100644 index 0000000..427dfb3 Binary files /dev/null and b/test/corim/corim-cca-plat-rv.cbor differ diff --git a/test/corim/corim-cca-plat-rv.json b/test/corim/corim-cca-plat-rv.json new file mode 100644 index 0000000..7448c35 --- /dev/null +++ b/test/corim/corim-cca-plat-rv.json @@ -0,0 +1,129 @@ +{ + "id": "00000000-0000-0000-cca4-000000000000", + "profile": { + "type": "uri", + "value": "tag:arm.com,2025:endorsements/cca_platform#1.0.0" + }, + "tags": [ + { + "type": "comid", + "value": { + "language": "en-GB", + "tag-identity": { + "tag-id": "43bbe37f-2e61-4b33-aed3-53cff1428b16" + }, + "entities": [ + { + "entity-name": "ACME Ltd.", + "reg-id": { + "type": "uri", + "value": "https://acme.example" + }, + "role": [ + "tag-creator", + "creator", + "maintainer" + ] + } + ], + "triples": { + "reference-triples": [ + [ + { + "class": { + "class-id": { + "type": "bytes", + "value": "f0VMRgIBAQAAAAAAAAAAAAMAPgABAAAAUFgAAAAAAAA" + } + } + }, + [ + { + "mkey": "cca.platform-config", + "mval": { + "raw-value": { + "type": "bytes", + "value": "AQcGBQQDAgEADw4NDAsKCQgXFhUUExIREB8eHRwbGhkY" + } + } + }, + { + "mkey": "cca.software-component", + "mval": { + "name": "BL", + "version": { + "version": "3.4.2" + }, + "digests": [ + "sha-256;BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg" + ], + "cryptokeys": [ + { + "type": "bytes", + "value": "BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg" + } + ] + } + }, + { + "mkey": "cca.software-component", + "mval": { + "name": "M1", + "version": { + "version": "1.2" + }, + "digests": [ + "sha-256;BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg" + ], + "cryptokeys": [ + { + "type": "bytes", + "value": "BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg" + } + ] + } + }, + { + "mkey": "cca.software-component", + "mval": { + "name": "M2", + "version": { + "version": "1.2.3" + }, + "digests": [ + "sha-256;BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg" + ], + "cryptokeys": [ + { + "type": "bytes", + "value": "BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg" + } + ] + } + }, + { + "mkey": "cca.software-component", + "mval": { + "name": "M3", + "version": { + "version": "1" + }, + "digests": [ + "sha-256;BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg" + ], + "cryptokeys": [ + { + "type": "bytes", + "value": "BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg" + } + ] + } + } + ] + ] + ] + } + } + } + ] +} \ No newline at end of file diff --git a/test/corim/corim-cca-ta.json b/test/corim/corim-cca-plat-ta.json similarity index 73% rename from test/corim/corim-cca-ta.json rename to test/corim/corim-cca-plat-ta.json index 3d0915c..48753ad 100644 --- a/test/corim/corim-cca-ta.json +++ b/test/corim/corim-cca-plat-ta.json @@ -1,5 +1,9 @@ { "id": "test ta corim id", + "profile": { + "type": "uri", + "value": "tag:arm.com,2025:endorsements/cca_platform#1.0.0" + }, "tags": [ { "type": "comid", @@ -39,8 +43,8 @@ }, [ { - "type": "bytes", - "value": "ewogICJjcnYiOiAiUC0zODQiLAogICJrdHkiOiAiRUMiLAogICJ4IjogIklTaG54UzRybFFpd3BDQ3BCV0R6bE5MZnFpRzkxMUZQOGFrQnItZmg5NHV4SFU1bS1LaWppdnAycjJveHhONk0iLAogICJ5IjogImhNNHRyOG1XUWxpMVA2MXhoM1QwVmlEUkViRjI2REdPRVlmYkFqV2pHTk43cFpmLTZBNE9USFlxRXJ5ejZtN1UiCn0K" + "type": "pkix-base64-key", + "value": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFTUtCQ1ROSWNLVVNEaWkxMXlTczM1MjZpRFo4QQppVG83VHU2S1BBcXY3RDdnUzJYcEpGYlppSXRTczNtOSs5VWU2R252SHcvR1cyWlphVnRzemdnWEl3PT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg" } ] ] @@ -49,4 +53,4 @@ } } ] -} +} \ No newline at end of file diff --git a/test/corim/corim-cca-ref-plat.json b/test/corim/corim-cca-plat-unsupported-profile.json similarity index 96% rename from test/corim/corim-cca-ref-plat.json rename to test/corim/corim-cca-plat-unsupported-profile.json index a51956f..7b71fa7 100644 --- a/test/corim/corim-cca-ref-plat.json +++ b/test/corim/corim-cca-plat-unsupported-profile.json @@ -1,5 +1,9 @@ { - "id": "test corim id", + "id": "00000000-0000-0000-cca4-000000000000", + "profile": { + "type": "uri", + "value": "tag:arm.com,2025:endorsements/bad_profile#1.0.0" + }, "tags": [ { "type": "comid", @@ -122,4 +126,4 @@ } } ] -} +} \ No newline at end of file diff --git a/test/corim/corim-cca-ref-realm.json b/test/corim/corim-cca-realm-rv.json similarity index 94% rename from test/corim/corim-cca-ref-realm.json rename to test/corim/corim-cca-realm-rv.json index a3f9e13..1b972f3 100644 --- a/test/corim/corim-cca-ref-realm.json +++ b/test/corim/corim-cca-realm-rv.json @@ -1,5 +1,9 @@ { - "id": "test corim id", + "id": "00000000-0000-0000-cca6-000000000000", + "profile": { + "type": "uri", + "value": "tag:arm.com,2025:endorsements/cca_realm#1.0.0" + }, "tags": [ { "type": "comid", @@ -90,4 +94,4 @@ } } ] -} +} \ No newline at end of file diff --git a/test/corim/rebuild.sh b/test/corim/rebuild.sh index 30e6b34..7b3edf2 100755 --- a/test/corim/rebuild.sh +++ b/test/corim/rebuild.sh @@ -2,9 +2,11 @@ set -euo pipefail corims=( - cca-ref-plat - cca-ref-realm - cca-ta + cca-plat-rv + cca-plat-ta + cca-realm-rv + cca-plat-expired-validity + cca-plat-unsupported-profile ) for name in "${corims[@]}"; do diff --git a/test/corim/signed-corim-cca-plat-expired-validity.cbor b/test/corim/signed-corim-cca-plat-expired-validity.cbor new file mode 100644 index 0000000..24314a1 Binary files /dev/null and b/test/corim/signed-corim-cca-plat-expired-validity.cbor differ diff --git a/test/corim/signed-corim-cca-plat-rv.cbor b/test/corim/signed-corim-cca-plat-rv.cbor new file mode 100644 index 0000000..c5ce3df Binary files /dev/null and b/test/corim/signed-corim-cca-plat-rv.cbor differ diff --git a/test/corim/signed-corim-cca-plat-ta.cbor b/test/corim/signed-corim-cca-plat-ta.cbor new file mode 100644 index 0000000..62784de Binary files /dev/null and b/test/corim/signed-corim-cca-plat-ta.cbor differ diff --git a/test/corim/signed-corim-cca-plat-unsupported-profile.cbor b/test/corim/signed-corim-cca-plat-unsupported-profile.cbor new file mode 100644 index 0000000..159b70e Binary files /dev/null and b/test/corim/signed-corim-cca-plat-unsupported-profile.cbor differ diff --git a/test/corim/signed-corim-cca-realm-rv.cbor b/test/corim/signed-corim-cca-realm-rv.cbor new file mode 100644 index 0000000..ba1d292 Binary files /dev/null and b/test/corim/signed-corim-cca-realm-rv.cbor differ diff --git a/test/corim/signed-corim-cca-ref-plat.cbor b/test/corim/signed-corim-cca-ref-plat.cbor deleted file mode 100644 index 84276bf..0000000 Binary files a/test/corim/signed-corim-cca-ref-plat.cbor and /dev/null differ diff --git a/test/corim/signed-corim-cca-ref-realm.cbor b/test/corim/signed-corim-cca-ref-realm.cbor deleted file mode 100644 index 60e0c6c..0000000 Binary files a/test/corim/signed-corim-cca-ref-realm.cbor and /dev/null differ diff --git a/test/corim/signed-corim-cca-ta.cbor b/test/corim/signed-corim-cca-ta.cbor deleted file mode 100644 index e6cd1ae..0000000 Binary files a/test/corim/signed-corim-cca-ta.cbor and /dev/null differ diff --git a/test/keys/pkey_256.json b/test/keys/pkey_256.json deleted file mode 100644 index 007c271..0000000 --- a/test/keys/pkey_256.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "crv": "P-256", - "kty": "EC", - "x": "tgbU5ewCDfgHLy1nxeMsgVvx9bnSic7qN74vRJ_Uwto", - "y": "BUhhTCrq8kJ87rghGBlvrZVi_CVtbWxmKTTNs5-bv9c" -} \ No newline at end of file diff --git a/test/keys/pkey_256.pem b/test/keys/pkey_256.pem deleted file mode 100644 index 1d7190a..0000000 --- a/test/keys/pkey_256.pem +++ /dev/null @@ -1,4 +0,0 @@ ------BEGIN PUBLIC KEY----- -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEtgbU5ewCDfgHLy1nxeMsgVvx9bnS -ic7qN74vRJ/UwtoFSGFMKuryQnzuuCEYGW+tlWL8JW1tbGYpNM2zn5u/1w== ------END PUBLIC KEY----- \ No newline at end of file diff --git a/test/keys/pkey_384.json b/test/keys/pkey_384.json deleted file mode 100644 index b7584d8..0000000 --- a/test/keys/pkey_384.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "crv": "P-384", - "kty": "EC", - "x": "mxOLLqA9CwehvuiSwmTXrPpsLv0b02UhUktcFrNSVGX4xw1SduiC485rga8dhszE", - "y": "LwNj95ahl1DM59pn-gm4iLc8km1J-CzLY4zEvVB13lYLC5KweOM17AasKfBtIV6y" -} \ No newline at end of file diff --git a/test/keys/pkey_384.pem b/test/keys/pkey_384.pem deleted file mode 100644 index b43ef53..0000000 --- a/test/keys/pkey_384.pem +++ /dev/null @@ -1,5 +0,0 @@ ------BEGIN PUBLIC KEY----- -MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEmxOLLqA9CwehvuiSwmTXrPpsLv0b02Uh -UktcFrNSVGX4xw1SduiC485rga8dhszELwNj95ahl1DM59pn+gm4iLc8km1J+CzL -Y4zEvVB13lYLC5KweOM17AasKfBtIV6y ------END PUBLIC KEY----- \ No newline at end of file diff --git a/test/keys/pkey_521.json b/test/keys/pkey_521.json deleted file mode 100644 index 2d5d396..0000000 --- a/test/keys/pkey_521.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "crv": "P-521", - "kty": "EC", - "x": "Abc8mbQKS796c-64-nisJ_uy0iVt8uoMsZICrmk8XvCZ1jt4kijzzYIHyTfxpfSIPg-LiADyyzaf7V2fPUpqDWv0", - "y": "ABqW6xEwm_JJqRF5ZnieolL6nBC18BfB-3k1raBt9INw6mHuCW9-hKoMmsC-LAv9eMiv-rbmuC3I-phVddwayiA7" -} \ No newline at end of file diff --git a/test/keys/pkey_521.pem b/test/keys/pkey_521.pem deleted file mode 100644 index e40b901..0000000 --- a/test/keys/pkey_521.pem +++ /dev/null @@ -1,6 +0,0 @@ ------BEGIN PUBLIC KEY----- -MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBtzyZtApLv3pz7rj6eKwn+7LSJW3y -6gyxkgKuaTxe8JnWO3iSKPPNggfJN/Gl9Ig+D4uIAPLLNp/tXZ89SmoNa/QAGpbr -ETCb8kmpEXlmeJ6iUvqcELXwF8H7eTWtoG30g3DqYe4Jb36EqgyawL4sC/14yK/6 -tua4Lcj6mFV13BrKIDs= ------END PUBLIC KEY----- \ No newline at end of file diff --git a/test/policy/added-claims/appraisal.json b/test/policy/added-claims/appraisal.json index c6ff7ea..da33203 100644 --- a/test/policy/added-claims/appraisal.json +++ b/test/policy/added-claims/appraisal.json @@ -1,6 +1,6 @@ { - "ear.status": 0, - "ear.trustworthiness-vector": { + "ear_status": 0, + "ear_trustworthiness_vector": { "instance-identity": 0, "configuration": 0, "executables": 0, @@ -10,8 +10,12 @@ "storage-opaque": 0, "sourced-data": 0 }, - "ear.veraison.policy-claims": { + "ear_verifier_claims": { "foo": 1, "bar": 2 - } -} + }, + "ear_appraisal_policy_ids": [ + "preamble", + "added-claims" + ] +} \ No newline at end of file diff --git a/test/policy/cca-platform/appraisal.json b/test/policy/cca-platform/appraisal.json index d71aa82..8cc6945 100644 --- a/test/policy/cca-platform/appraisal.json +++ b/test/policy/cca-platform/appraisal.json @@ -1,6 +1,6 @@ { - "ear.status": "affirming", - "ear.trustworthiness-vector": { + "ear_status": "affirming", + "ear_trustworthiness_vector": { "instance-identity": 2, "configuration": 2, "executables": 3, @@ -9,5 +9,9 @@ "runtime-opaque": 2, "storage-opaque": 2, "sourced-data": 0 - } -} + }, + "ear_appraisal_policy_ids": [ + "preamble", + "cca-platform" + ] +} \ No newline at end of file diff --git a/test/policy/cca-platform/input.json b/test/policy/cca-platform/input.json index 92cdaf0..df716d8 100644 --- a/test/policy/cca-platform/input.json +++ b/test/policy/cca-platform/input.json @@ -99,7 +99,7 @@ } } ], - "cm-type": "evidence", + "cmtype": "evidence", "profile": { "type": "uri", "value": "http://arm.com/CCA-SSD/1.0.0" @@ -146,7 +146,7 @@ } } ], - "cm-type": "evidence", + "cmtype": "evidence", "profile": { "type": "uri", "value": "" @@ -252,7 +252,7 @@ } } ], - "cm-type": "reference-values" + "cmtype": "reference-values" }, { "environment": { @@ -295,6 +295,6 @@ } } ], - "cm-type": "reference-values" + "cmtype": "reference-values" } ] diff --git a/test/policy/cca-platform/policy.rego b/test/policy/cca-platform/policy.rego index b2c5bc9..163cb8a 100644 --- a/test/policy/cca-platform/policy.rego +++ b/test/policy/cca-platform/policy.rego @@ -21,12 +21,12 @@ platform contains ect if { refvals contains ect if { ect = platform[_] - ect["cm-type"] == "reference-values" + ect["cmtype"] == "reference-values" } evidence contains ect if { ect = platform[_] - ect["cm-type"] == "evidence" + ect["cmtype"] == "evidence" } lifecycle := ret if { diff --git a/test/policy/cca-realm/appraisal.json b/test/policy/cca-realm/appraisal.json index ef15bca..ccac4f8 100644 --- a/test/policy/cca-realm/appraisal.json +++ b/test/policy/cca-realm/appraisal.json @@ -1,6 +1,6 @@ { - "ear.status": "affirming", - "ear.trustworthiness-vector": { + "ear_status": "affirming", + "ear_trustworthiness_vector": { "instance-identity": 2, "configuration": 0, "executables": 2, @@ -9,5 +9,9 @@ "runtime-opaque": 2, "storage-opaque": 0, "sourced-data": 0 - } -} + }, + "ear_appraisal_policy_ids": [ + "preamble", + "cca-realm" + ] +} \ No newline at end of file diff --git a/test/policy/cca-realm/policy.rego b/test/policy/cca-realm/policy.rego index 197463a..de60b85 100644 --- a/test/policy/cca-realm/policy.rego +++ b/test/policy/cca-realm/policy.rego @@ -7,12 +7,12 @@ realm contains ect if { refvals contains ect if { ect = realm[_] - ect["cm-type"] == "reference-values" + ect["cmtype"] == "reference-values" } evidence contains ect if { ect = realm[_] - ect["cm-type"] == "evidence" + ect["cmtype"] == "evidence" } # If cryptographic verification completes (implicit in getting here), instance diff --git a/test/policy/empty/appraisal.json b/test/policy/empty/appraisal.json index 7ee989b..86c80ce 100644 --- a/test/policy/empty/appraisal.json +++ b/test/policy/empty/appraisal.json @@ -9,5 +9,9 @@ "runtime-opaque": 0, "storage-opaque": 0, "sourced-data": 0 - } + }, + "ear_appraisal_policy_ids": [ + "preamble", + "empty" + ] }