diff --git a/Cargo.lock b/Cargo.lock index f6dbc8d..70f3b85 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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce2b2dcc879c3bae0d371e77c99f2238400ef24ec001394befa67b6e543add9e" +dependencies = [ + "aws-lc-sys", + "untrusted 0.7.1", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.44.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "f09fae7be8bb3174e05c6afdb34199e6dc0c7c04ba9fa237b1967adfbde27483" +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.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5da9b3d9f6f585199287a473f4f8dfab6566cf827d15c00c219f53c645687ead" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" [[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 = "3eeab4423108c5d7c744f4d234de88d18d636100093ae04caf4825134b9c3a32" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "bstr" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +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,27 +265,30 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.17" +version = "1.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a" +checksum = "0ad534f4357a5264cce5019c989cf66a4f0dc4e0d1b1d15f8aacec0ff7360273" 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=870c83f#870c83f83c9690643c4eb8e5986ef1a4779fc596" dependencies = [ "base64 0.21.7", - "bitmask", + "bitflags 2.13.1", "ciborium", "clap", "cose-rust", - "ear 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ear 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex", "hex-literal", - "jsonwebtoken", + "jsonwebtoken 10.4.0", "multimap", "openssl", "serde", @@ -229,17 +299,27 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "chacha20" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81" +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.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071" +checksum = "473c7e07f409a8d772161724aa8db6a765a2532a70f9667eeb7b49d3d02fbdca" dependencies = [ "clap_builder", "clap_derive", @@ -318,9 +387,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.37" +version = "4.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2" +checksum = "7b48fea5a88e9ae728a2dcbedbfc0e730f7d60da42e1cb049a83c9fb8b789889" dependencies = [ "anstream", "anstyle", @@ -330,59 +399,103 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.32" +version = "4.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" +checksum = "d012d2b9d65aca7f18f4d9878a045bc17899bba951561ba5ec3c2ba1eed9a061" dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 3.0.4", ] [[package]] name = "clap_lex" -version = "0.7.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[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.20", + "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.20", ] [[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" @@ -392,13 +505,15 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[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 +523,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,72 +548,97 @@ 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.5.0 (git+https://github.com/veraison/rust-ear?rev=084529d)", "elliptic-curve", "env_logger", - "jsonwebtoken", + "jsonwebtoken 10.4.0", "log", "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.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" 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.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" dependencies = [ "darling_core", "darling_macro", @@ -506,40 +646,70 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.21.3" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" +checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" dependencies = [ - "fnv", "ident_case", "proc-macro2", "quote", "strsim", - "syn", + "syn 2.0.119", ] [[package]] name = "darling_macro" -version = "0.21.3" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" +checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" dependencies = [ "darling_core", "quote", - "syn", + "syn 2.0.119", ] [[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.20", +] [[package]] name = "der" -version = "0.7.10" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +checksum = "a69dedd701da44b0536442edf09c81a64b0ab97a7a4a5e3d1971f00027cbc63d" dependencies = [ "const-oid", "pem-rfc7468", @@ -548,57 +718,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.4", ] +[[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 +783,79 @@ checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" [[package]] name = "ear" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bc48a3976de4a3c2f6661a74836abbd7d458ef10e391fedcf47bcc4c983abc1" +checksum = "5aec2877d084955915f48086ae07f49f4c89e33e3826d1f7af33b342274f8100" dependencies = [ "base64 0.22.1", "ciborium", "cose-rust", "hex", - "jsonwebtoken", + "jsonwebtoken 10.4.0", "lazy_static", "openssl", - "phf 0.11.3", + "phf 0.13.1", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.20", ] [[package]] name = "ear" -version = "0.4.0" -source = "git+https://github.com/veraison/rust-ear?rev=15184e9a#15184e9a47f642eece82f176b5b1802ab69dbc25" +version = "0.5.0" +source = "git+https://github.com/veraison/rust-ear?rev=084529d#084529d6c48260cf5917124c41e85f0ee341d7b6" dependencies = [ "base64 0.22.1", "ciborium", + "cmw", "cose-rust", "hex", - "jsonwebtoken", + "jsonwebtoken 11.0.0", "lazy_static", "openssl", "phf 0.13.1", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.20", ] [[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 +870,32 @@ 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.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + [[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 +903,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 +920,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 +943,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.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d45db016d36b838f563236e9193d0ee6ce38f3f68b6c94e914b4929c96bbb890" + [[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 +986,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 +1009,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 = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + +[[package]] +name = "futures-channel" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" dependencies = [ - "typenum", - "version_check", - "zeroize", + "futures-core", + "futures-sink", ] [[package]] -name = "getrandom" -version = "0.2.15" +name = "futures-core" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" + +[[package]] +name = "futures-io" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +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 = [ - "cfg-if", - "js-sys", - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", - "wasm-bindgen", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "slab", ] [[package]] name = "getrandom" -version = "0.3.2" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", "libc", - "r-efi", - "wasi 0.14.2+wasi-0.2.4", + "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.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +checksum = "7fd1a1c7a5206c5b7a3f5a0d7ccd3ff85d0c8f5133d62a02680255b0004af5f4" dependencies = [ "ff", - "rand_core 0.6.4", + "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.0", + "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 +1179,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 +1210,146 @@ 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.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707114b52a152fa7bdb290cd7cd5912d9467273b6d74e21b8d81aca1f8533f6b" +dependencies = [ + "subtle", + "typenum", + "zeroize", +] + +[[package]] +name = "hyper" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d22053281f852e11534f5198498373cbb59295120a20771d90f7ed1897490a72" +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.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" +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.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "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 +1371,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 +1396,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 +1460,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 +1471,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 +1492,188 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.8.0" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" 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.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +checksum = "6a756c3fac73139e83f14c2d742155dd2b78d3ee56597b419a0579b7bdd6dd78" [[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.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49" +checksum = "668b7183bd07af9a4885f5c35b0cc5c83c4607a913c16b7e17291832910d2dcc" 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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7feca88439efe53da3754500c1851dedf3cb36c524dd5cf8225cc0794de95d09" +dependencies = [ + "defmt", ] [[package]] name = "jiff-static" -version = "0.2.15" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" +checksum = "3a69dcb3a21cfb32ce1cd056169337ca284af0766dd766e7878819b251a49204" 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.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +checksum = "0e0c1080212aad755ea003d18543e8768dd432c48819efd73a7bf1e39b7a5a3a" 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 = "10.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde" +checksum = "eba32bfb4ffdeaca3e34431072faf01745c9b26d25504aa7a6cf5684334fc4fc" 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]] +name = "jsonwebtoken" +version = "11.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "881733cbc631fc9e472e24447ce32a64bedf2da498d6d8570b08edc87de71f65" +dependencies = [ + "aws-lc-rs", + "base64 0.22.1", + "getrandom 0.2.17", + "js-sys", + "pem 3.0.6", "serde", "serde_json", + "signature 2.2.0", "simple_asn1", + "zeroize", ] [[package]] @@ -1200,53 +1684,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 = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" [[package]] -name = "md-5" -version = "0.10.6" +name = "lru" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +checksum = "5d2f2f9b4ba7e6b24d95e7e899329d35be83bcded72c8540cdd5368932d1d90a" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "micromap" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +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 = "memchr" -version = "2.7.4" +name = "minicbor" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "c12b4033ffaa92fbf9df03df38d19324f52bad130dd223f811734a8006dd2d69" [[package]] -name = "minimal-lexical" -version = "0.2.1" +name = "minicbor-derive" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +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 = "mio" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.61.2", +] + +[[package]] +name = "msvc_spectre_libs" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29e871a9861f3664f18b7e04e9301d4edd55090c2dadb4b1c602e26ab32b1f5b" +dependencies = [ + "cc", +] [[package]] name = "multimap" @@ -1258,13 +1805,20 @@ dependencies = [ ] [[package]] -name = "nom" -version = "7.1.3" +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 +1827,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 +1837,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 +1872,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 +1901,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 +1926,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.1", "cfg-if", "foreign-types", "libc", - "once_cell", "openssl-macros", "openssl-sys", ] @@ -1390,23 +1958,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 +1997,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,60 +2048,59 @@ 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]] @@ -1533,31 +2109,11 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" dependencies = [ - "phf_macros 0.13.1", + "phf_macros", "phf_shared 0.13.1", "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" @@ -1568,37 +2124,24 @@ dependencies = [ "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", -] - [[package]] name = "phf_macros" version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef" dependencies = [ - "phf_generator 0.13.1", + "phf_generator", "phf_shared 0.13.1", "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", ] @@ -1625,9 +2168,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 +2179,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 +2190,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 +2208,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.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a63d338dec139f56dacc692ca63ad35a6be6a797442479b55acd611d79e906" +checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" 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 +2260,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.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" +checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" 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 +2352,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.1", ] [[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.4", ] [[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 +2415,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 +2427,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 +2438,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.0", + "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.2", "regex", - "scientific", "semver", "serde", "serde_json", "serde_yaml", - "sha2", + "spin", + "thiserror 2.0.20", "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 +2535,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.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +dependencies = [ + "bitflags 2.13.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls" +version = "0.23.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0283386ce02abc0151e1761d08802dfe86c173b0b494af5cbc086574e453da06" +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 +2631,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 +2641,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 +2649,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.1", + "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 +2712,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.4", ] [[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", - "ryu", "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", ] [[package]] name = "serde_with" -version = "3.15.0" +version = "3.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6093cd8c01b25262b84927e0f7151692158fab02d961e04c979d3903eba7ecc5" +checksum = "ee78f1fbe43ac4a0e47aadb3dbd357b69eb0d3793e948624cd03dd2750ab1c0a" dependencies = [ "base64 0.22.1", + "bs58", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.8.0", + "indexmap 2.14.0", + "jiff", "schemars 0.9.0", - "schemars 1.0.4", + "schemars 1.2.2", "serde_core", "serde_json", "serde_with_macros", @@ -2076,34 +2778,44 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.15.0" +version = "3.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7e6c180db0816026a61afa1cff5344fb7ebded7e4d3062772179f2501481c27" +checksum = "8705578779c2b6bd90d84d66eb2e206b708b1a4d7b9f17641b293545bf1c7e46" dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "serde_yaml" version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +dependencies = [ + "indexmap 2.14.0", + "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 = [ - "indexmap 2.8.0", - "itoa", - "ryu", + "base16ct", "serde", - "unsafe-libyaml", ] [[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 +2824,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 +2834,70 @@ 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 = "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.20", "time", ] [[package]] name = "siphasher" -version = "1.0.1" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" + +[[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.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" + +[[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 +2905,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 +2915,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,24 +2941,78 @@ 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.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +checksum = "e6275cddf4610d1775e6d1fe9469b2e77d0f39fd98fb7450901b821e0c53649f" 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.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", +] + +[[package]] +name = "system-configuration" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" +dependencies = [ + "bitflags 2.13.1", + "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]] @@ -2218,7 +3033,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -2229,7 +3044,7 @@ checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", "test-case-core", ] @@ -2244,11 +3059,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.16" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0" +checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" dependencies = [ - "thiserror-impl 2.0.16", + "thiserror-impl 2.0.20", ] [[package]] @@ -2259,46 +3074,45 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "thiserror-impl" -version = "2.0.16" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960" +checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.4", ] [[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 +3120,164 @@ 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.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.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.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +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.1", + "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.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unsafe-libyaml" @@ -2338,6 +3285,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 +3299,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 +3323,14 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.16.0" +version = "1.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9" +checksum = "b5772d71c9be8a8a6ac2117d949c5b224c1b72241bb611d9a3012edcf8af7812" dependencies = [ - "getrandom 0.3.2", - "rand 0.9.0", + "getrandom 0.4.3", + "js-sys", + "rand 0.10.2", + "wasm-bindgen", ] [[package]] @@ -2390,7 +3340,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b082222b4f6619906941c17eb2297fff4c2fb96cb60164170522942a200bd8" dependencies = [ "outref", - "uuid", "vsimd", ] @@ -2413,51 +3362,57 @@ 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.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +checksum = "1b70935747edd64d89de3efa29d73789b806c15798f8e7dca4d8ac356b50ce70" 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.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +checksum = "6b7777d5cc23d0e91404e53ce2d5e8ec7acae3026b16233dba62cd3246457950" dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", + "js-sys", + "wasm-bindgen", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.100" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "77775f8f3f7217702089053b94958f8f54061a3f663417df76e19cbdcca29bc1" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2465,45 +3420,41 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.100" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "e11d33f857dc2fb11b8bc75aee111aa9cbeb12cd9f25efd3d4c2a3dd4e235284" dependencies = [ + "bumpalo", "proc-macro2", "quote", - "syn", - "wasm-bindgen-backend", + "syn 2.0.119", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.100" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "7ef64dbcc55df09c7e5a46182d181c2cfa3e925f3da937ea764728b4bbb9dcbf" dependencies = [ "unicode-ident", ] [[package]] -name = "wax" -version = "0.6.0" +name = "web-sys" +version = "0.3.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d12a78aa0bab22d2f26ed1a96df7ab58e8a93506a3e20adb47c51a93b4e1357" +checksum = "c435338968042f4f59a557f690a253676d47ce13ceb55d70100e7facf6620a30" 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,40 @@ 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.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +checksum = "ab12e7090f27e2ffd9322651492942d50c2926094af30601e1964337db39daf1" dependencies = [ - "bitflags", + "ff", + "group", + "hybrid-array", ] [[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 +3644,93 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.5" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", "synstructure", ] [[package]] name = "zerocopy" -version = "0.7.35" +version = "0.8.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +checksum = "556764e583adb45a9f8d413c2a147fa7e8d821e48e12b14fd560b607998b75eb" dependencies = [ - "zerocopy-derive 0.7.35", + "zerocopy-derive", ] [[package]] -name = "zerocopy" -version = "0.8.24" +name = "zerocopy-derive" +version = "0.8.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" +checksum = "f2ab42fc20575779bd240faa45f94a74256f755c0fa9e89f0ede20d91d0cdfc1" 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.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", + "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 +3739,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.4", ] + +[[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..c5aa16c 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 = "870c83f" } 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 = "084529d" } +env_logger = { version = "0.11.11", features = ["kv"] } +jsonwebtoken = "10.3.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..8dafb36 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. @@ -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 \ + # 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-01.cbor \ --nonce adfadaewafewr32r --output cca-token-01.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..7e0ed74 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -12,6 +12,7 @@ use base64::{ }; use clap::{ArgAction, Parser}; use clap_verbosity_flag::{InfoLevel, Verbosity}; +use corim_rs::Corim; use log::{debug, error, info}; use cover::{ @@ -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/identiy 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,37 @@ 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) + .unwrap_or(false) + }) { + corim_store.add(&parsed_corim)?; + corim_loaded = true; + } else { + info!( + "skipping CoRIM {:?} because it does not match a supported scheme profile or is expired", + corim + ); + } } for dir in &args.corim_dirs { @@ -136,15 +161,33 @@ 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) + .unwrap_or(false) + }) { + corim_store.add(&parsed_corim)?; + corim_loaded = true; + } else { + info!( + "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 +212,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 +238,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..669224c 100644 --- a/src/lib/authority.rs +++ b/src/lib/authority.rs @@ -36,23 +36,26 @@ 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))) + } } } @@ -107,7 +110,7 @@ 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 { diff --git a/src/lib/cca/mod.rs b/src/lib/cca/mod.rs index 97537be..fc9b90c 100644 --- a/src/lib/cca/mod.rs +++ b/src/lib/cca/mod.rs @@ -1,3 +1,5 @@ +mod profile; +pub use profile::CcaCorimProfile; use std::borrow::Cow; use ccatoken::{ @@ -7,8 +9,8 @@ use ccatoken::{ 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 +21,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 +50,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 +69,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() } @@ -173,33 +180,45 @@ 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); - - ect.set_environment( - EnvironmentMapBuilder::default() - .class( - ClassMapBuilder::default() - .class_id(ClassIdTypeChoice::Bytes(plat.impl_id.as_slice().into())) - .build() - .unwrap(), - ) - .build() - .unwrap(), - ); +fn platform_to_ect<'a>( + plat: &Platform, + cpak_pub: &CryptoKeyTypeChoice<'a>, +) -> Result, Error> { + // TODO: + // Implement platform evidence profile check here once rust-ccatoken is updated. + // This does not have any impact on end result, since all the current supported profiles by + // ccaguest and one specificed in draft-ydb-rats-cca-endorsements-04, produce same Evidence object. + + 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)?; @@ -218,6 +237,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,7 +246,7 @@ fn platform_to_ect<'a>(plat: &Platform) -> Result, Error> { mval: MeasurementValuesMapBuilder::default() .add_extension( RAW_INT_LABEL.into(), - ExtensionValue::Int( + corim_rs::ExtensionValue::Int( match plat.lifecycle { 0x0000..=0x00ff => Ok(LC_UNKNOWN), 0x1000..=0x10ff => Ok(LC_ASSEMBLY_AND_TEST), @@ -277,31 +298,39 @@ 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); - - ect.set_environment( - EnvironmentMapBuilder::default() - .class( - ClassMapBuilder::default() - .class_id(ClassIdTypeChoice::Bytes(TaggedBytes::from(Bytes::from( - realm.rim.clone(), - )))) - .build() - .unwrap(), - ) - .build() - .unwrap(), - ); - - ect.set_profile(ProfileTypeChoice::Uri(Uri::from(Text::from( - realm.profile.to_string(), - )))); + // TODO: + // Implement realm evidence profile check here once rust-ccatoken is updated. + // This does not have any impact on end result, since all the current supported profiles by + // ccaguest and one specificed in draft-ydb-rats-cca-endorsements-04, produce same Evidence object. + + 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(), + )))); let hash_alg = HashAlgorithm::try_from(realm.hash_alg.as_str()).map_err(Error::custom)?; @@ -342,7 +371,7 @@ fn realm_to_ect<'a>(realm: &Realm) -> Result, Error> { .map_err(Error::custom)?, }); - Ok(ect) + Ok(Ect::from(ect)) } #[cfg(test)] 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..15be41e 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 chrono::DateTime; +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")), - } +/// 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 now = SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap_or_default() + .as_secs(); + + let not_before = validity + .not_before + .as_ref() + .map(|t| t.as_i128() as u64) + .unwrap_or(0); + + let not_after = validity.not_after.as_i128() as u64; + + if not_before > not_after { + warn!( + "Corim validity, Not before: {} is greater than Not After: {}", + DateTime::from_timestamp(not_before as i64, 0).expect("validity is never none"), + DateTime::from_timestamp(not_after as i64, 0).expect("validity is never none") + ); + return false; + } else if now > not_after { + warn!( + "CoRIM expired on: {}", + DateTime::from_timestamp(not_after as i64, 0).expect("validity is never none") + ); + return false; + } else if now < not_before { + warn!( + "CoRIM is not active till: {}", + DateTime::from_timestamp(not_before as i64, 0).expect("validity is never none") + ); + return false; } -} -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", - }) - } + true } -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\"", - )), - } - } -} - -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) - } - } -} - -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) - } - } -} - -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) - } -} - -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,176 @@ 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: &[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.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 +319,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 +336,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 +379,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 +405,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 +428,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 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, &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 +459,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. +/// `key` define the authority who signed the corim, for unsigned corim, verifier's authority is used. +/// In case of unsigned 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>, + key: &[u8], + verifier_key: &[u8], +) -> Result> { + let corim_verifier = OpensslSigner::public_key_from_pem(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 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(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..f6b6779 100644 --- a/src/lib/keystore.rs +++ b/src/lib/keystore.rs @@ -94,7 +94,8 @@ impl MemKeyStore { impl KeyStore for MemKeyStore { fn add(&mut self, kid: &[u8], key: &[u8]) -> Result<()> { - debug!("adding kid {:x?}", kid); + debug!("Key kid : \"{}\"", str::from_utf8(kid).unwrap()); + debug!("Adding into Memory Key Store.."); self.items.insert(kid.to_vec(), key.to_vec()); Ok(()) } @@ -119,3 +120,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..df687d6 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-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"); +//! } //! ``` //! -//! # 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-01.cbor \ +//! --nonce adfadaewafewr32r --output cca-token-01.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..0464021 100644 --- a/src/lib/policy.rs +++ b/src/lib/policy.rs @@ -2,11 +2,9 @@ use std::fs; use std::io; use anyhow::Result; -use ear::{Appraisal, RawValue}; +use ear::Appraisal; 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 +47,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 @@ -151,52 +149,11 @@ pub fn appraise(input: &str, policy: &Policy) -> Result { ); appraisal.update_status_from_trust_vector(); - appraisal.policy_claims = - match rego_to_ear(engine.eval_rule("data.policy.policy_claims".to_string())?) { - RawValue::Map(m) => m - .iter() - .map(|(x, y)| { - if let RawValue::String(s) = x { - Ok((s.to_owned(), y.to_owned())) - } else { - Err(Error::PolicyClaims(RawValue::Map(m.to_owned()))) - } - }) - .collect(), - r => Err(Error::PolicyClaims(r)), - }?; - Ok(appraisal) } -fn rego_to_ear(val: Value) -> RawValue { - match val { - Value::Null => RawValue::Null, - Value::Undefined => RawValue::Null, - Value::Bool(v) => RawValue::Bool(v), - Value::Number(v) => { - if let Some(i) = v.as_i64() { - RawValue::Integer(i) - } else if let Some(f) = v.as_f64() { - RawValue::Float(f) - } else { - RawValue::Null - } - } - Value::String(v) => RawValue::String(v.to_string()), - Value::Array(v) => RawValue::Array(v.iter().map(|x| rego_to_ear(x.to_owned())).collect()), - Value::Set(v) => RawValue::Array(v.iter().map(|x| rego_to_ear(x.to_owned())).collect()), - Value::Object(v) => RawValue::Map( - v.iter() - .map(|(x, y)| (rego_to_ear(x.to_owned()), rego_to_ear(y.to_owned()))) - .collect(), - ), - } -} - #[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..9bb6c0c 100644 --- a/src/lib/scheme.rs +++ b/src/lib/scheme.rs @@ -1,29 +1,71 @@ -use corim_rs::{CryptoKeyTypeChoice, EnvironmentMap}; +use log::{debug, info}; +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; + } + } + info!("Unsupported profile \"{}\" ", corim_profile); + false + } + + fn supports_corim(&self, corim: &Corim<'_>) -> Result { + Ok(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>; + ) -> 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..86b6898 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() { diff --git a/src/lib/verifier.rs b/src/lib/verifier.rs index b9f81e6..f71d84f 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,7 +67,7 @@ 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))?; @@ -76,42 +78,45 @@ impl<'a, S: CorimStore<'a>> Verifier<'a, S> { let mut evidence_ects = scheme.validate_and_parse_evidence(evidence, &trust_anchor)?; - let mut ref_vals = self.match_reference_values(&evidence_ects); - 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. @@ -121,7 +126,17 @@ impl<'a, S: CorimStore<'a>> Verifier<'a, S> { /// 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)?; + let supported = self + .schemes + .values() + .any(|scheme| scheme.as_ref().supports_corim(&corim).unwrap_or(false)); + + if supported { + self.corims.add(&corim) + } else { + Ok(()) + } } /// 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())); } } } @@ -214,29 +210,12 @@ impl<'a, S: CorimStore<'a>> Verifier<'a, S> { 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) - } - } - } - } + 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 + { + found = elts.first().cloned(); } } @@ -247,26 +226,23 @@ impl<'a, S: CorimStore<'a>> Verifier<'a, S> { } } -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 +253,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 +269,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 +279,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 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 +305,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/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 93% rename from test/corim/corim-cca-ta.json rename to test/corim/corim-cca-plat-ta.json index 3d0915c..ac66485 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", @@ -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..c6d7a0d 100755 --- a/test/corim/rebuild.sh +++ b/test/corim/rebuild.sh @@ -2,13 +2,16 @@ 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 echo "Rebuilding signed-corim-${name}.cbor..." + # echo "compile corim-${name}.json -o signed-corim-${name}.cbor --kid key.pub.pem --key key.priv.pem -f" corim-tool compile "corim-${name}.json" -o "signed-corim-${name}.cbor" --kid key.pub.pem --key key.priv.pem -f done echo "Done." 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..58f14e4 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..0cd6585 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..5a36f72 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..4565873 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..c5ac436 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/policy/cca-platform/appraisal.json b/test/policy/cca-platform/appraisal.json index d71aa82..97460be 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, 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..4c43fb5 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, 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