diff --git a/demos/vc_issuer/Cargo.lock b/demos/vc_issuer/Cargo.lock new file mode 100644 index 0000000000..575d14b2dd --- /dev/null +++ b/demos/vc_issuer/Cargo.lock @@ -0,0 +1,3276 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "ascii-canvas" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6" +dependencies = [ + "term", +] + +[[package]] +name = "assert_matches" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base-x" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base32" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23ce669cd6c8588f79e15cf450314f9638f967fc5770ff1c7c1deb0925ea7cfa" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "beef" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "binread" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16598dfc8e6578e9b597d9910ba2e73618385dc9f4b1d43dd92c349d6be6418f" +dependencies = [ + "binread_derive", + "lazy_static", + "rustversion", +] + +[[package]] +name = "binread_derive" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d9672209df1714ee804b1f4d4f68c8eb2a90b1f7a07acf472f88ce198ef1fed" +dependencies = [ + "either", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "byte-unit" +version = "4.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da78b32057b8fdfc352504708feeba7216dcd65a2c9ab02978cbd288d1279b6c" +dependencies = [ + "serde", + "utf8-width", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "cached" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec6d20b3d24b6c74e2c5331d2d3d8d1976a9883c7da179aa851afa4c90d62e36" +dependencies = [ + "hashbrown 0.12.3", + "instant", + "once_cell", + "thiserror", +] + +[[package]] +name = "candid" +version = "0.9.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "465c1ce01d8089ee5b49ba20d3a9da15a28bba64c35cdff2aa256d37e319625d" +dependencies = [ + "anyhow", + "binread", + "byteorder", + "candid_derive", + "codespan-reporting", + "convert_case 0.6.0", + "crc32fast", + "data-encoding", + "hex", + "lalrpop", + "lalrpop-util", + "leb128", + "logos", + "num-bigint", + "num-traits", + "num_enum", + "paste", + "pretty", + "serde", + "serde_bytes", + "sha2 0.10.8", + "stacker", + "thiserror", +] + +[[package]] +name = "candid_derive" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "201ea498d901add0822653ac94cb0f8a92f9b1758a5273f4dafbb6673c9a5020" +dependencies = [ + "lazy_static", + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "canister_sig_util" +version = "0.1.0" +dependencies = [ + "candid", + "ic-certified-map", + "lazy_static", + "sha2 0.10.8", +] + +[[package]] +name = "canister_tests" +version = "0.1.0" +dependencies = [ + "base64 0.21.4", + "candid", + "flate2", + "hex", + "ic-cdk", + "ic-representation-independent-hash", + "ic-test-state-machine-client", + "identity_jose", + "internet_identity_interface", + "lazy_static", + "regex", + "serde", + "serde_bytes", + "serde_cbor", + "sha2 0.10.8", + "vc_util", +] + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets", +] + +[[package]] +name = "ciborium" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" + +[[package]] +name = "ciborium-ll" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" +dependencies = [ + "ciborium-io", + "half", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "comparable" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb513ee8037bf08c5270ecefa48da249f4c58e57a71ccfce0a5b0877d2a20eb2" +dependencies = [ + "comparable_derive", + "comparable_helper", + "pretty_assertions", + "serde", +] + +[[package]] +name = "comparable_derive" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a54b9c40054eb8999c5d1d36fdc90e4e5f7ff0d1d9621706f360b3cbc8beb828" +dependencies = [ + "convert_case 0.4.0", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "comparable_helper" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5437e327e861081c91270becff184859f706e3e50f5301a9d4dc8eb50752c3" +dependencies = [ + "convert_case 0.6.0", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "const-oid" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "cpufeatures" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "platforms", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "curve25519-dalek-ng" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.6.4", + "subtle-ng", + "zeroize", +] + +[[package]] +name = "cvt" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ae9bf77fbf2d39ef573205d554d87e86c12f1994e9ea335b0651b9b278bcf1" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "darling" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" +dependencies = [ + "darling_core", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "data-encoding" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" + +[[package]] +name = "data-encoding-macro" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c904b33cc60130e1aeea4956ab803d08a3f4a0ca82d64ed757afac3891f2bb99" +dependencies = [ + "data-encoding", + "data-encoding-macro-internal", +] + +[[package]] +name = "data-encoding-macro-internal" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fdf3fce3ce863539ec1d7fd1b6dcc3c645663376b43ed376bbf887733e4f772" +dependencies = [ + "data-encoding", + "syn 1.0.109", +] + +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" +dependencies = [ + "serde", +] + +[[package]] +name = "derive_more" +version = "0.99.8-alpha.0" +source = "git+https://github.com/dfinity-lab/derive_more?branch=master#9f1b894e6fde640da4e9ea71a8fc0e4dd98d01da" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "did_url" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70d5f6334e473e3bb5650ab4ef3e4c910296b76968e62758e7c66157ff767c05" +dependencies = [ + "form_urlencoded", + "serde", +] + +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "ecdsa" +version = "0.16.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" +dependencies = [ + "der", + "digest 0.10.7", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "ed25519" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60f6d271ca33075c88028be6f04d502853d63a5ece419d269c15315d4fc1cf1d" +dependencies = [ + "signature", +] + +[[package]] +name = "ed25519-consensus" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c8465edc8ee7436ffea81d21a019b16676ee3db267aa8d5a8d729581ecf998b" +dependencies = [ + "curve25519-dalek-ng", + "hex", + "rand_core 0.6.4", + "serde", + "sha2 0.9.9", + "thiserror", + "zeroize", +] + +[[package]] +name = "ed25519-zebra" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d9ce6874da5d4415896cd45ffbc4d1cfc0c4f9c079427bd870742c30f2f65a9" +dependencies = [ + "curve25519-dalek 4.1.1", + "ed25519", + "hashbrown 0.14.1", + "hex", + "rand_core 0.6.4", + "sha2 0.10.8", + "zeroize", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "elliptic-curve" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest 0.10.7", + "ff 0.13.0", + "generic-array", + "group 0.13.0", + "pem-rfc7468", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "ena" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c533630cf40e9caa44bd91aadc88a75d75a4c3a12b4cfde353cbed41daa1e1f1" +dependencies = [ + "log", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "erased-serde" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" +dependencies = [ + "serde", +] + +[[package]] +name = "errno" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "fiat-crypto" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0870c84016d4b481be5c9f323c24f65e31e901ae618f0e80f4308fb00de1d2d" + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "flate2" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff 0.12.1", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff 0.13.0", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "half" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ic-base-types" +version = "0.8.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "base32", + "byte-unit", + "bytes", + "candid", + "comparable", + "crc32fast", + "ic-crypto-sha2", + "ic-protobuf", + "ic-stable-structures 0.5.6", + "phantom_newtype", + "prost", + "serde", + "strum 0.24.1", + "strum_macros 0.24.3", +] + +[[package]] +name = "ic-btc-interface" +version = "0.1.0" +source = "git+https://github.com/dfinity/bitcoin-canister?rev=be0143a014ad4bccbc2eec5e2bcbe30317c5a84c#be0143a014ad4bccbc2eec5e2bcbe30317c5a84c" +dependencies = [ + "candid", + "serde", + "serde_bytes", +] + +[[package]] +name = "ic-btc-types-internal" +version = "0.1.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "candid", + "ic-btc-interface", + "ic-error-types", + "ic-protobuf", + "serde", + "serde_bytes", +] + +[[package]] +name = "ic-cdk" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d4c0b932bf454d5d60e61e13c3c944972fcfd74dc82b9ed5c8b0a75979cf50" +dependencies = [ + "candid", + "ic-cdk-macros", + "ic0", + "serde", + "serde_bytes", +] + +[[package]] +name = "ic-cdk-macros" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "411c0dd4c149132b68e679274d397053332ee29996c6a541075895881916333b" +dependencies = [ + "candid", + "proc-macro2", + "quote", + "serde", + "serde_tokenstream", + "syn 1.0.109", +] + +[[package]] +name = "ic-certification" +version = "0.8.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "hex", + "ic-crypto-tree-hash", + "ic-crypto-utils-threshold-sig", + "ic-crypto-utils-threshold-sig-der", + "ic-types", + "serde", + "serde_cbor", + "tree-deserializer", +] + +[[package]] +name = "ic-certified-map" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "197524aecec47db0b6c0c9f8821aad47272c2bd762c7a0ffe9715eaca0364061" +dependencies = [ + "serde", + "serde_bytes", + "sha2 0.10.8", +] + +[[package]] +name = "ic-constants" +version = "0.8.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" + +[[package]] +name = "ic-crypto-ecdsa-secp256k1" +version = "0.1.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "k256", + "lazy_static", + "num-bigint", + "pem", + "rand", + "simple_asn1", + "zeroize", +] + +[[package]] +name = "ic-crypto-ecdsa-secp256r1" +version = "0.1.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "ic-crypto-getrandom-for-wasm", + "lazy_static", + "num-bigint", + "p256", + "pem", + "rand", + "rand_chacha", + "simple_asn1", + "zeroize", +] + +[[package]] +name = "ic-crypto-getrandom-for-wasm" +version = "0.1.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "getrandom 0.2.10", +] + +[[package]] +name = "ic-crypto-iccsa" +version = "0.1.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "ic-crypto-internal-basic-sig-iccsa", +] + +[[package]] +name = "ic-crypto-internal-basic-sig-cose" +version = "0.1.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "ic-crypto-internal-basic-sig-der-utils", + "ic-crypto-internal-basic-sig-ecdsa-secp256r1", + "ic-crypto-internal-basic-sig-rsa-pkcs1", + "ic-types", + "serde", + "serde_cbor", + "simple_asn1", +] + +[[package]] +name = "ic-crypto-internal-basic-sig-der-utils" +version = "0.8.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "hex", + "ic-types", + "simple_asn1", + "zeroize", +] + +[[package]] +name = "ic-crypto-internal-basic-sig-ecdsa-secp256k1" +version = "0.8.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "base64 0.13.1", + "ic-crypto-ecdsa-secp256k1", + "ic-crypto-internal-basic-sig-der-utils", + "ic-crypto-internal-types", + "ic-crypto-secrets-containers", + "ic-types", + "serde", + "serde_bytes", + "simple_asn1", + "zeroize", +] + +[[package]] +name = "ic-crypto-internal-basic-sig-ecdsa-secp256r1" +version = "0.8.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "base64 0.13.1", + "ic-crypto-ecdsa-secp256r1", + "ic-crypto-internal-basic-sig-der-utils", + "ic-crypto-internal-types", + "ic-crypto-secrets-containers", + "ic-types", + "p256", + "rand", + "serde", + "serde_bytes", + "simple_asn1", + "zeroize", +] + +[[package]] +name = "ic-crypto-internal-basic-sig-ed25519" +version = "0.8.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "base64 0.13.1", + "curve25519-dalek 3.2.0", + "ed25519-consensus", + "hex", + "ic-crypto-internal-basic-sig-der-utils", + "ic-crypto-internal-seed", + "ic-crypto-internal-types", + "ic-crypto-secrets-containers", + "ic-protobuf", + "ic-types", + "rand", + "rand_chacha", + "serde", + "simple_asn1", + "zeroize", +] + +[[package]] +name = "ic-crypto-internal-basic-sig-iccsa" +version = "0.8.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "base64 0.13.1", + "hex", + "ic-certification", + "ic-crypto-internal-basic-sig-der-utils", + "ic-crypto-internal-types", + "ic-crypto-sha2", + "ic-crypto-tree-hash", + "ic-types", + "serde", + "serde_bytes", + "serde_cbor", + "simple_asn1", +] + +[[package]] +name = "ic-crypto-internal-basic-sig-rsa-pkcs1" +version = "0.8.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "ic-crypto-getrandom-for-wasm", + "ic-crypto-internal-basic-sig-der-utils", + "ic-crypto-sha2", + "ic-types", + "num-bigint", + "num-traits", + "pkcs8", + "rsa", + "serde", + "sha2 0.10.8", + "simple_asn1", +] + +[[package]] +name = "ic-crypto-internal-bls12-381-type" +version = "0.1.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "hex", + "ic-crypto-getrandom-for-wasm", + "ic_bls12_381", + "itertools 0.10.5", + "lazy_static", + "pairing", + "paste", + "rand", + "rand_chacha", + "sha2 0.9.9", + "subtle", + "zeroize", +] + +[[package]] +name = "ic-crypto-internal-seed" +version = "0.1.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "hex", + "ic-crypto-sha2", + "ic-types", + "rand", + "rand_chacha", + "serde", + "zeroize", +] + +[[package]] +name = "ic-crypto-internal-sha2" +version = "0.8.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "sha2 0.10.8", +] + +[[package]] +name = "ic-crypto-internal-threshold-sig-bls12381" +version = "0.8.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "base64 0.13.1", + "cached", + "hex", + "ic-crypto-internal-bls12-381-type", + "ic-crypto-internal-seed", + "ic-crypto-internal-threshold-sig-bls12381-der", + "ic-crypto-internal-types", + "ic-crypto-secrets-containers", + "ic-crypto-sha2", + "ic-types", + "lazy_static", + "parking_lot", + "rand", + "rand_chacha", + "serde", + "serde_bytes", + "serde_cbor", + "strum_macros 0.24.3", + "subtle", + "zeroize", +] + +[[package]] +name = "ic-crypto-internal-threshold-sig-bls12381-der" +version = "0.8.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "simple_asn1", +] + +[[package]] +name = "ic-crypto-internal-types" +version = "0.8.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "arrayvec", + "hex", + "ic-protobuf", + "phantom_newtype", + "serde", + "serde_cbor", + "strum 0.24.1", + "strum_macros 0.24.3", + "thiserror", + "zeroize", +] + +[[package]] +name = "ic-crypto-secrets-containers" +version = "0.8.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "serde", + "zeroize", +] + +[[package]] +name = "ic-crypto-sha2" +version = "0.8.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "ic-crypto-internal-sha2", +] + +[[package]] +name = "ic-crypto-standalone-sig-verifier" +version = "0.8.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "ic-crypto-iccsa", + "ic-crypto-internal-basic-sig-cose", + "ic-crypto-internal-basic-sig-der-utils", + "ic-crypto-internal-basic-sig-ecdsa-secp256k1", + "ic-crypto-internal-basic-sig-ecdsa-secp256r1", + "ic-crypto-internal-basic-sig-ed25519", + "ic-crypto-internal-basic-sig-iccsa", + "ic-crypto-internal-basic-sig-rsa-pkcs1", + "ic-crypto-internal-types", + "ic-crypto-sha2", + "ic-types", +] + +[[package]] +name = "ic-crypto-tree-hash" +version = "0.8.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "assert_matches", + "ic-crypto-internal-types", + "ic-crypto-sha2", + "ic-protobuf", + "serde", + "serde_bytes", + "thiserror", +] + +[[package]] +name = "ic-crypto-utils-threshold-sig" +version = "0.8.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "base64 0.13.1", + "ic-crypto-internal-threshold-sig-bls12381", + "ic-crypto-internal-types", + "ic-types", +] + +[[package]] +name = "ic-crypto-utils-threshold-sig-der" +version = "0.8.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "base64 0.13.1", + "ic-crypto-internal-threshold-sig-bls12381-der", + "ic-crypto-internal-types", + "ic-types", +] + +[[package]] +name = "ic-error-types" +version = "0.8.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "ic-utils", + "serde", + "strum 0.24.1", + "strum_macros 0.24.3", +] + +[[package]] +name = "ic-ic00-types" +version = "0.8.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "candid", + "ic-base-types", + "ic-btc-interface", + "ic-btc-types-internal", + "ic-error-types", + "ic-protobuf", + "num-traits", + "serde", + "serde_bytes", + "serde_cbor", + "strum 0.24.1", + "strum_macros 0.24.3", +] + +[[package]] +name = "ic-protobuf" +version = "0.8.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "bincode", + "candid", + "erased-serde", + "maplit", + "prost", + "serde", + "serde_json", + "slog", +] + +[[package]] +name = "ic-representation-independent-hash" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "410e3ccb16b86e8c4bca7270981370f6961492f1921f29f5dd1de621efb869ea" +dependencies = [ + "leb128", + "sha2 0.10.8", +] + +[[package]] +name = "ic-stable-structures" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95dce29e3ceb0e6da3e78b305d95365530f2efd2146ca18590c0ef3aa6038568" + +[[package]] +name = "ic-stable-structures" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4867a1d9f232e99ca68682161d1fc67dff9501f4f1bf42d69a9358289ad0f8" + +[[package]] +name = "ic-sys" +version = "0.8.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "hex", + "ic-crypto-sha2", + "lazy_static", + "libc", + "nix", + "phantom_newtype", + "wsl", +] + +[[package]] +name = "ic-test-state-machine-client" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cadf6ac4a193a8a45287da67c6c385f118d9266f46d6d98e40fbbd469d3822e" +dependencies = [ + "candid", + "ciborium", + "serde", + "serde_bytes", +] + +[[package]] +name = "ic-types" +version = "0.8.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "base64 0.13.1", + "bincode", + "candid", + "chrono", + "derive_more", + "hex", + "ic-base-types", + "ic-btc-types-internal", + "ic-constants", + "ic-crypto-internal-types", + "ic-crypto-sha2", + "ic-crypto-tree-hash", + "ic-error-types", + "ic-ic00-types", + "ic-protobuf", + "ic-utils", + "maplit", + "once_cell", + "phantom_newtype", + "prost", + "serde", + "serde_bytes", + "serde_cbor", + "serde_json", + "serde_with", + "strum 0.24.1", + "strum_macros 0.24.3", + "thiserror", + "thousands", +] + +[[package]] +name = "ic-utils" +version = "0.8.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "cvt", + "hex", + "ic-sys", + "libc", + "nix", + "prost", + "rand", + "scoped_threadpool", + "serde", + "thiserror", +] + +[[package]] +name = "ic0" +version = "0.18.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16efdbe5d9b0ea368da50aedbf7640a054139569236f1a5249deb5fd9af5a5d5" + +[[package]] +name = "ic_bls12_381" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c682cb199cd8fcb582a6023325d571a6464edda26c8063fe04b6f6082a1a363c" +dependencies = [ + "digest 0.9.0", + "ff 0.12.1", + "group 0.12.1", + "pairing", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "identity_core" +version = "0.7.0-alpha.6" +source = "git+https://github.com/frederikrothenberger/identity.rs.git?branch=frederik/wasm-test#c0538f9a3d6f0025b8bf698646289d5bcb875ba9" +dependencies = [ + "ic-cdk", + "iota-crypto", + "multibase", + "serde", + "serde_json", + "strum 0.25.0", + "thiserror", + "time", + "url", + "zeroize", +] + +[[package]] +name = "identity_credential" +version = "0.7.0-alpha.6" +source = "git+https://github.com/frederikrothenberger/identity.rs.git?branch=frederik/wasm-test#c0538f9a3d6f0025b8bf698646289d5bcb875ba9" +dependencies = [ + "identity_core", + "identity_did", + "identity_document", + "identity_verification", + "indexmap", + "itertools 0.11.0", + "once_cell", + "serde", + "serde_repr", + "strum 0.25.0", + "thiserror", + "url", +] + +[[package]] +name = "identity_did" +version = "0.7.0-alpha.6" +source = "git+https://github.com/frederikrothenberger/identity.rs.git?branch=frederik/wasm-test#c0538f9a3d6f0025b8bf698646289d5bcb875ba9" +dependencies = [ + "did_url", + "form_urlencoded", + "identity_core", + "serde", + "strum 0.25.0", + "thiserror", +] + +[[package]] +name = "identity_document" +version = "0.7.0-alpha.6" +source = "git+https://github.com/frederikrothenberger/identity.rs.git?branch=frederik/wasm-test#c0538f9a3d6f0025b8bf698646289d5bcb875ba9" +dependencies = [ + "did_url", + "identity_core", + "identity_did", + "identity_verification", + "indexmap", + "serde", + "strum 0.25.0", + "thiserror", +] + +[[package]] +name = "identity_jose" +version = "0.7.0-alpha.6" +source = "git+https://github.com/frederikrothenberger/identity.rs.git?branch=frederik/wasm-test#c0538f9a3d6f0025b8bf698646289d5bcb875ba9" +dependencies = [ + "ic-crypto-standalone-sig-verifier", + "ic-types", + "identity_core", + "iota-crypto", + "serde", + "serde_bytes", + "serde_cbor", + "serde_json", + "subtle", + "thiserror", + "zeroize", +] + +[[package]] +name = "identity_verification" +version = "0.7.0-alpha.6" +source = "git+https://github.com/frederikrothenberger/identity.rs.git?branch=frederik/wasm-test#c0538f9a3d6f0025b8bf698646289d5bcb875ba9" +dependencies = [ + "identity_core", + "identity_did", + "identity_jose", + "serde", + "strum 0.25.0", + "thiserror", +] + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +dependencies = [ + "equivalent", + "hashbrown 0.14.1", + "serde", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "internet_identity_interface" +version = "0.1.0" +dependencies = [ + "candid", + "ic-cdk", + "serde", + "serde_bytes", +] + +[[package]] +name = "iota-crypto" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5d5a986d972c3a703d48ced24fdc0bf16fb2d02959ff4b152fa77b9132f6fb0" +dependencies = [ + "autocfg", + "curve25519-dalek 3.2.0", + "digest 0.10.7", + "ed25519-zebra", + "k256", + "serde", + "sha2 0.10.8", + "x25519-dalek", + "zeroize", +] + +[[package]] +name = "is-terminal" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +dependencies = [ + "hermit-abi", + "rustix", + "windows-sys", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "js-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "k256" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2 0.10.8", +] + +[[package]] +name = "lalrpop" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da4081d44f4611b66c6dd725e6de3169f9f63905421e8626fcb86b6a898998b8" +dependencies = [ + "ascii-canvas", + "bit-set", + "diff", + "ena", + "is-terminal", + "itertools 0.10.5", + "lalrpop-util", + "petgraph", + "pico-args", + "regex", + "regex-syntax 0.7.5", + "string_cache", + "term", + "tiny-keccak", + "unicode-xid", +] + +[[package]] +name = "lalrpop-util" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f35c735096c0293d313e8f2a641627472b83d01b937177fe76e5e2708d31e0d" +dependencies = [ + "regex", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin", +] + +[[package]] +name = "leb128" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" + +[[package]] +name = "libc" +version = "0.2.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "linux-raw-sys" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" + +[[package]] +name = "lock_api" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "logos" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c000ca4d908ff18ac99b93a062cb8958d331c3220719c52e77cb19cc6ac5d2c1" +dependencies = [ + "logos-derive", +] + +[[package]] +name = "logos-codegen" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc487311295e0002e452025d6b580b77bb17286de87b57138f3b5db711cded68" +dependencies = [ + "beef", + "fnv", + "proc-macro2", + "quote", + "regex-syntax 0.6.29", + "syn 2.0.38", +] + +[[package]] +name = "logos-derive" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbfc0d229f1f42d790440136d941afd806bc9e949e2bcb8faa813b0f00d1267e" +dependencies = [ + "logos-codegen", +] + +[[package]] +name = "maplit" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "multibase" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b3539ec3c1f04ac9748a260728e855f261b4977f5c3406612c884564f329404" +dependencies = [ + "base-x", + "data-encoding", + "data-encoding-macro", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" + +[[package]] +name = "nix" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset", +] + +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_enum" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2 0.10.8", +] + +[[package]] +name = "pairing" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135590d8bdba2b31346f9cd1fb2a912329f5135e832a4f422942eb6ead8b6b3b" +dependencies = [ + "group 0.12.1", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.3.5", + "smallvec", + "windows-targets", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "pem" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" +dependencies = [ + "base64 0.13.1", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "petgraph" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +dependencies = [ + "fixedbitset", + "indexmap", +] + +[[package]] +name = "phantom_newtype" +version = "0.8.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "candid", + "serde", + "slog", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pico-args" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" + +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "platforms" +version = "3.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4503fa043bf02cee09a9582e9554b4c6403b2ef55e4612e96561d294419429f8" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "pretty" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b55c4d17d994b637e2f4daf6e5dc5d660d209d5642377d675d7a1c3ab69fa579" +dependencies = [ + "arrayvec", + "typed-arena", + "unicode-width", +] + +[[package]] +name = "pretty_assertions" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" +dependencies = [ + "diff", + "yansi", +] + +[[package]] +name = "primeorder" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c2fcef82c0ec6eefcc179b978446c399b3cdf73c392c35604e399eee6df1ee3" +dependencies = [ + "elliptic-curve", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-derive" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +dependencies = [ + "anyhow", + "itertools 0.10.5", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "psm" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874" +dependencies = [ + "cc", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.10", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom 0.2.10", + "redox_syscall 0.2.16", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebee201405406dbf528b8b672104ae6d6d63e6d118cb10e4d51abbc7b58044ff" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax 0.7.5", +] + +[[package]] +name = "regex-automata" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.7.5", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "rsa" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86ef35bf3e7fe15a53c4ab08a998e42271eab13eb0db224126bc7bc4c4bad96d" +dependencies = [ + "const-oid", + "digest 0.10.7", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core 0.6.4", + "sha2 0.10.8", + "signature", + "spki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "scoped_threadpool" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "semver" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad977052201c6de01a8ef2aa3378c4bd23217a056337d1d6da40468d267a4fb0" + +[[package]] +name = "serde" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_bytes" +version = "0.11.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab33ec92f677585af6d88c65593ae2375adde54efdbf16d597f2cbc7a6d368ff" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_cbor" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +dependencies = [ + "half", + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "serde_json" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "serde_tokenstream" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "797ba1d80299b264f3aac68ab5d12e5825a561749db4df7cd7c8083900c5d4e9" +dependencies = [ + "proc-macro2", + "serde", + "syn 1.0.109", +] + +[[package]] +name = "serde_with" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678b5a069e50bf00ecd22d0cd8ddf7c236f68581b03db652061ed5eb13a312ff" +dependencies = [ + "serde", + "serde_with_macros", +] + +[[package]] +name = "serde_with_macros" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "signature" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "simple_asn1" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" +dependencies = [ + "num-bigint", + "num-traits", + "thiserror", + "time", +] + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "slog" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8347046d4ebd943127157b94d63abb990fcf729dc4e9978927fdf4ac3c998d06" +dependencies = [ + "erased-serde", +] + +[[package]] +name = "smallvec" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spki" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "stacker" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c886bd4480155fd3ef527d45e9ac8dd7118a898a46530b7b94c3e21866259fce" +dependencies = [ + "cc", + "cfg-if", + "libc", + "psm", + "winapi", +] + +[[package]] +name = "string_cache" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" +dependencies = [ + "new_debug_unreachable", + "once_cell", + "parking_lot", + "phf_shared", + "precomputed-hash", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strum" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" +dependencies = [ + "strum_macros 0.24.3", +] + +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +dependencies = [ + "strum_macros 0.25.2", +] + +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 1.0.109", +] + +[[package]] +name = "strum_macros" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8d03b598d3d0fff69bf533ee3ef19b8eeb342729596df84bcc7e1f96ec4059" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.38", +] + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "subtle-ng" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "term" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" +dependencies = [ + "dirs-next", + "rustversion", + "winapi", +] + +[[package]] +name = "termcolor" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "thousands" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bf63baf9f5039dadc247375c29eb13706706cfde997d0330d05aa63a77d8820" + +[[package]] +name = "time" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "426f806f4089c493dcac0d24c29c01e2c38baf8e30f1b716ee37e83d200b18fe" +dependencies = [ + "deranged", + "itoa", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +dependencies = [ + "time-core", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +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 = "toml_datetime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tree-deserializer" +version = "0.8.0" +source = "git+https://github.com/dfinity/ic?rev=bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e#bf9bc00b032a18d2dbcfcfcfb7a76a562f350c9e" +dependencies = [ + "ic-crypto-tree-hash", + "leb128", + "serde", +] + +[[package]] +name = "typed-arena" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "url" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf8-width" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5190c9442dcdaf0ddd50f37420417d219ae5261bbf5db120d0f9bab996c9cba1" + +[[package]] +name = "vc_issuer" +version = "0.1.0" +dependencies = [ + "assert_matches", + "candid", + "canister_sig_util", + "canister_tests", + "hex", + "ic-cdk", + "ic-cdk-macros", + "ic-certified-map", + "ic-stable-structures 0.6.0", + "ic-test-state-machine-client", + "identity_core", + "identity_credential", + "identity_jose", + "internet_identity_interface", + "lazy_static", + "serde", + "serde_bytes", + "serde_cbor", + "serde_json", + "sha2 0.10.8", + "vc_util", +] + +[[package]] +name = "vc_util" +version = "0.1.0" +dependencies = [ + "candid", + "canister_sig_util", + "ic-cdk", + "ic-certified-map", + "ic-crypto-standalone-sig-verifier", + "ic-types", + "identity_core", + "identity_credential", + "identity_jose", + "serde", + "serde_bytes", + "serde_cbor", + "serde_json", + "sha2 0.10.8", +] + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.38", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "winnow" +version = "0.5.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037711d82167854aff2018dfd193aa0fef5370f456732f0d5a0c59b0f1b4b907" +dependencies = [ + "memchr", +] + +[[package]] +name = "wsl" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dab7ac864710bdea6594becbea5b5050333cf34fefb0dc319567eb347950d4" + +[[package]] +name = "x25519-dalek" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a0c105152107e3b96f6a00a65e86ce82d9b125230e1c4302940eca58ff71f4f" +dependencies = [ + "curve25519-dalek 3.2.0", + "rand_core 0.5.1", + "zeroize", +] + +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" + +[[package]] +name = "zeroize" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] diff --git a/demos/vc_issuer/Cargo.toml b/demos/vc_issuer/Cargo.toml new file mode 100644 index 0000000000..73a0328307 --- /dev/null +++ b/demos/vc_issuer/Cargo.toml @@ -0,0 +1,37 @@ +[workspace] + +[package] +name = "vc_issuer" +description = "Verifiable Credentials Issuer" +version = "0.1.0" +edition = "2021" + +[dependencies] +# local dependencies +canister_sig_util = { path = "../../src/canister_sig_util" } +internet_identity_interface = { path = "../../src/internet_identity_interface" } +vc_util = { path = "../../src/vc_util" } +# ic dependencies +candid = "0.9" +ic-cdk = "0.10" +ic-cdk-macros = "0.7" +ic-certified-map = "0.4" +ic-stable-structures = "0.6.0" +# vc dependencies +identity_core = { git = "https://github.com/frederikrothenberger/identity.rs.git", branch = "frederik/wasm-test", default-features = false} +identity_credential = {git = "https://github.com/frederikrothenberger/identity.rs.git", branch = "frederik/wasm-test", default-features = false, features = ["credential"]} +identity_jose = { git = "https://github.com/frederikrothenberger/identity.rs.git", branch = "frederik/wasm-test", default-features = false, features = ["iccs"]} + +# other dependencies +hex = "0.4" +serde = { version = "1", features = ["derive"] } +serde_bytes = "0.11" +serde_cbor = "0.11" +serde_json = "1" +sha2 = "^0.10" # set bound to match ic-certified-map bound + +[dev-dependencies] +assert_matches = "1.5.0" +ic-test-state-machine-client = "3" +canister_tests = { path = "../../src/canister_tests" } +lazy_static = "1.4" diff --git a/demos/vc_issuer/README.md b/demos/vc_issuer/README.md new file mode 100644 index 0000000000..2a16643c86 --- /dev/null +++ b/demos/vc_issuer/README.md @@ -0,0 +1,15 @@ +# An example issuer of verifiable credentials + +This is an example implementation of an issuer of verifiable credentials for +the [attribute sharing flow on the IC](https://github.com/dfinity/wg-identity-authentication/blob/main/topics/attribute-sharing.md). + +## Supported Behavior + +The app implements the interface of the issuer from [the spec](../../docs/vc-spec.md), plus some additional +APIs for configuring and testing, cf. [vc_issuer.did](./vc_issuer.did). +Please note that this issuer is for demonstrating the use of issuer APIS, and is **not meant +for real-world deployment**, as it does not have proper management of user data. + +## Development + +Run `./build.sh` script to build the issuer canister. diff --git a/demos/vc_issuer/build.sh b/demos/vc_issuer/build.sh new file mode 100755 index 0000000000..a7d2f2ffeb --- /dev/null +++ b/demos/vc_issuer/build.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -euo pipefail + + +# Make sure we always run from the issuer root +VC_ISSUER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +cd "$VC_ISSUER_DIR" + +cargo build --release --target wasm32-unknown-unknown --manifest-path ./Cargo.toml -j1 +ic-wasm "target/wasm32-unknown-unknown/release/vc_issuer.wasm" -o "./vc_issuer.wasm" shrink +ic-wasm vc_issuer.wasm -o vc_issuer.wasm metadata candid:service -f vc_issuer.did -v public +gzip --no-name --force "vc_issuer.wasm" + diff --git a/demos/vc_issuer/dfx.json b/demos/vc_issuer/dfx.json new file mode 100644 index 0000000000..eff25f4949 --- /dev/null +++ b/demos/vc_issuer/dfx.json @@ -0,0 +1,28 @@ +{ + "canisters": { + "internet_identity": { + "type": "custom", + "candid": "../../src/internet_identity/internet_identity.did", + "wasm": "../../internet_identity.wasm.gz", + + "remote": { + "id": { + "ic": "rdmx6-jaaaa-aaaaa-aaadq-cai" + } + } + }, + + "issuer": { + "type": "custom", + "candid": "vc_issuer.did", + "wasm": "vc_issuer.wasm.gz", + "build": "./build.sh" + } + }, + "defaults": { + "build": { + "packtool": "" + } + }, + "version": 1 +} diff --git a/demos/vc_issuer/src/main.rs b/demos/vc_issuer/src/main.rs new file mode 100644 index 0000000000..6f7fe6dc6a --- /dev/null +++ b/demos/vc_issuer/src/main.rs @@ -0,0 +1,524 @@ +use candid::{candid_method, CandidType, Deserialize, Principal}; +use canister_sig_util::signature_map::{SignatureMap, LABEL_SIG}; +use canister_sig_util::{extract_raw_root_pk_from_der, CanisterSigPublicKey, IC_ROOT_PK_DER}; +use ic_cdk::api::{caller, data_certificate, set_certified_data, time}; +use ic_cdk::trap; +use ic_cdk_macros::{init, query, update}; +use ic_certified_map::{Hash, HashTree}; +use ic_stable_structures::storable::Bound; +use ic_stable_structures::{DefaultMemoryImpl, RestrictedMemory, StableCell, Storable}; +use identity_core::common::Url; +use identity_core::convert::FromJson; +use identity_credential::credential::{Credential, CredentialBuilder, Subject}; +use serde::Serialize; +use serde_bytes::ByteBuf; +use serde_json::json; +use sha2::{Digest, Sha256}; +use std::borrow::Cow; +use std::cell::RefCell; +use std::collections::{HashMap, HashSet}; +use vc_util::issuer_api::{ + ArgumentValue, CredentialSpec, GetCredentialRequest, GetCredentialResponse, Icrc21ConsentInfo, + Icrc21ConsentMessageResponse, Icrc21Error, Icrc21ErrorInfo, Icrc21VcConsentMessageRequest, + IssueCredentialError, IssuedCredentialData, PrepareCredentialRequest, + PrepareCredentialResponse, PreparedCredentialData, SignedIdAlias, +}; +use vc_util::{ + did_for_principal, vc_jwt_to_jws, vc_signing_input, vc_signing_input_hash, + verify_id_alias_credential_jws, AliasTuple, +}; + +/// We use restricted memory in order to ensure the separation between non-managed config memory (first page) +/// and the managed memory for potential other data of the canister. +type Memory = RestrictedMemory; +type ConfigCell = StableCell; + +const MINUTE_NS: u64 = 60 * 1_000_000_000; +const CERTIFICATE_VALIDITY_PERIOD_NS: u64 = 5 * MINUTE_NS; +const PROD_II_CANISTER_ID: &str = "rdmx6-jaaaa-aaaaa-aaadq-cai"; + +thread_local! { + /// Static configuration of the canister set by init() or post_upgrade(). + static CONFIG: RefCell = RefCell::new(ConfigCell::init(config_memory(), IssuerConfig::default()).expect("failed to initialize stable cell")); + static SIGNATURES : RefCell = RefCell::new(SignatureMap::default()); + static EMPLOYEES : RefCell> = RefCell::new(HashSet::new()); + static GRADUATES : RefCell> = RefCell::new(HashSet::new()); +} + +/// Reserve the first stable memory page for the configuration stable cell. +fn config_memory() -> Memory { + RestrictedMemory::new(DefaultMemoryImpl::default(), 0..1) +} + +#[cfg(target_arch = "wasm32")] +use ic_cdk::println; + +#[derive(CandidType, Deserialize)] +struct IssuerConfig { + /// Root of trust for checking canister signatures. + ic_root_key_raw: Vec, + /// List of canister ids that are allowed to provide id alias credentials. + idp_canister_ids: Vec, +} + +impl Storable for IssuerConfig { + fn to_bytes(&self) -> Cow<[u8]> { + Cow::Owned(candid::encode_one(self).expect("failed to encode IssuerConfig")) + } + fn from_bytes(bytes: Cow<[u8]>) -> Self { + candid::decode_one(&bytes).expect("failed to decode IssuerConfig") + } + const BOUND: Bound = Bound::Unbounded; +} + +impl Default for IssuerConfig { + fn default() -> Self { + Self { + ic_root_key_raw: extract_raw_root_pk_from_der(IC_ROOT_PK_DER) + .expect("failed to extract raw root pk from der"), + idp_canister_ids: vec![Principal::from_text(PROD_II_CANISTER_ID).unwrap()], + } + } +} + +impl From for IssuerConfig { + fn from(init: IssuerInit) -> Self { + Self { + ic_root_key_raw: extract_raw_root_pk_from_der(&init.ic_root_key_der) + .expect("failed to extract raw root pk from der"), + idp_canister_ids: init.idp_canister_ids, + } + } +} + +#[derive(CandidType, Deserialize)] +struct IssuerInit { + /// Root of trust for checking canister signatures. + ic_root_key_der: Vec, + /// List of canister ids that are allowed to provide id alias credentials. + idp_canister_ids: Vec, +} + +#[init] +#[candid_method(init)] +fn init(init_arg: Option) { + let Some(init) = init_arg else { + // nothing to do + return; + }; + apply_config(init); +} + +#[update] +#[candid_method] +fn configure(config: IssuerInit) { + apply_config(config); +} + +fn apply_config(init: IssuerInit) { + CONFIG + .with_borrow_mut(|config_cell| config_cell.set(IssuerConfig::from(init))) + .expect("failed to apply issuer config"); +} + +fn authorize_vc_request(alias: &SignedIdAlias) -> Result<(), IssueCredentialError> { + verify_id_alias(&alias)?; + + if caller() != alias.id_dapp { + return Err(IssueCredentialError::UnauthorizedSubject(format!( + "Caller {} does not match id alias dapp principal {}.", + caller(), + alias.id_dapp + ))); + } + Ok(()) +} + +fn verify_id_alias(alias: &SignedIdAlias) -> Result<(), IssueCredentialError> { + let alias_tuple = AliasTuple { + id_alias: alias.id_alias, + id_dapp: alias.id_dapp, + }; + + CONFIG.with_borrow(|config| { + let config = config.get(); + + for idp_canister_id in &config.idp_canister_ids { + if verify_id_alias_credential_jws( + &alias.credential_jws, + &alias_tuple, + idp_canister_id, + &config.ic_root_key_raw, + ) + .is_ok() + { + return Ok(()); + } + } + Err(IssueCredentialError::InvalidIdAlias( + "id alias could not be verified".to_string(), + )) + }) +} + +#[update] +#[candid_method] +async fn prepare_credential(req: PrepareCredentialRequest) -> PrepareCredentialResponse { + if let Err(e) = authorize_vc_request(&req.signed_id_alias) { + return PrepareCredentialResponse::Err(e); + }; + if let Err(err) = verify_credential_spec(&req.credential_spec) { + return PrepareCredentialResponse::Err(IssueCredentialError::UnsupportedCredentialSpec( + err, + )); + } + + let credential = match prepare_credential_payload(&req) { + Ok(credential) => credential, + Err(err) => return PrepareCredentialResponse::Err(err), + }; + let seed = calculate_seed(&req.signed_id_alias.id_alias); + let canister_id = ic_cdk::id(); + let canister_sig_pk = CanisterSigPublicKey::new(canister_id, seed.to_vec()); + let credential_jwt = credential + .serialize_jwt() + .expect("internal: JWT serialization failure"); + let signing_input = + vc_signing_input(&credential_jwt, &canister_sig_pk).expect("failed getting signing_input"); + let msg_hash = vc_signing_input_hash(&signing_input); + + SIGNATURES.with(|sigs| { + let mut sigs = sigs.borrow_mut(); + add_signature(&mut sigs, msg_hash, seed); + }); + update_root_hash(); + PrepareCredentialResponse::Ok(PreparedCredentialData { + prepared_context: Some(ByteBuf::from(credential_jwt.as_bytes())), + }) +} + +fn update_root_hash() { + use ic_certified_map::labeled_hash; + SIGNATURES.with(|sigs| { + let sigs = sigs.borrow(); + let prefixed_root_hash = &labeled_hash(LABEL_SIG, &sigs.root_hash()); + set_certified_data(&prefixed_root_hash[..]); + }) +} + +#[query] +#[candid_method(query)] +fn get_credential(req: GetCredentialRequest) -> GetCredentialResponse { + if let Err(e) = authorize_vc_request(&req.signed_id_alias) { + return GetCredentialResponse::Err(e); + }; + if let Err(err) = verify_credential_spec(&req.credential_spec) { + return GetCredentialResponse::Err(IssueCredentialError::UnsupportedCredentialSpec(err)); + } + let subject_principal = req.signed_id_alias.id_alias; + let seed = calculate_seed(&subject_principal); + let canister_id = ic_cdk::id(); + let canister_sig_pk = CanisterSigPublicKey::new(canister_id, seed.to_vec()); + let prepared_context = match req.prepared_context { + Some(context) => context, + None => return GetCredentialResponse::Err(internal_error("missing prepared_context")), + }; + let credential_jwt = match String::from_utf8(prepared_context.into_vec()) { + Ok(s) => s, + Err(_) => return GetCredentialResponse::Err(internal_error("invalid prepared_context")), + }; + let signing_input = + vc_signing_input(&credential_jwt, &canister_sig_pk).expect("failed getting signing_input"); + let msg_hash = vc_signing_input_hash(&signing_input); + let maybe_sig = SIGNATURES.with(|sigs| { + let sigs = sigs.borrow(); + get_signature(&sigs, seed, msg_hash) + }); + let sig = if let Some(sig) = maybe_sig { + sig + } else { + return GetCredentialResponse::Err(IssueCredentialError::SignatureNotFound(String::from( + "signature not prepared or expired", + ))); + }; + let vc_jws = + vc_jwt_to_jws(&credential_jwt, &canister_sig_pk, &sig).expect("failed constructing JWS"); + GetCredentialResponse::Ok(IssuedCredentialData { vc_jws }) +} + +#[update] +#[candid_method] +async fn vc_consent_message(req: Icrc21VcConsentMessageRequest) -> Icrc21ConsentMessageResponse { + if let Err(err) = verify_credential_spec(&req.credential_spec) { + return Icrc21ConsentMessageResponse::Err(Icrc21Error::NotSupported(Icrc21ErrorInfo { + description: err, + error_code: 0, + })); + } + Icrc21ConsentMessageResponse::Ok(Icrc21ConsentInfo { + consent_message: get_vc_consent_message(&req), + language: "en-US".to_string(), + }) +} + +fn verify_credential_spec(spec: &CredentialSpec) -> Result<(), String> { + match spec.credential_name.as_str() { + "VerifiedEmployee" => verify_single_argument( + spec, + "employerName", + ArgumentValue::String("DFINITY Foundation".to_string()), + ), + "UniversityDegreeCredential" => verify_single_argument( + spec, + "institutionName", + ArgumentValue::String("DFINITY College of Engineering".to_string()), + ), + other => Err(format!("Credential {} is not supported", other)), + } +} + +// Verifies that the credential spec `spec` contains an argument `expected_argument` +// with the value `expected_value`. +fn verify_single_argument( + spec: &CredentialSpec, + expected_argument: &str, + expected_value: ArgumentValue, +) -> Result<(), String> { + fn missing_argument_error( + spec: &CredentialSpec, + expected_argument: &str, + ) -> Result<(), String> { + Err(format!( + "Missing argument '{}' for credential {}", + expected_argument, spec.credential_name + )) + } + + let Some(arguments) = &spec.arguments else { + return missing_argument_error(spec, expected_argument); + }; + let Some(value) = arguments.get(expected_argument) else { + return missing_argument_error(spec, expected_argument); + }; + + if value != &expected_value { + return Err(format!( + "Unsupported value for argument '{}': expected '{}', got '{}'", + expected_argument, expected_value, value + )); + } + + let unexpected_arguments: Vec<&String> = arguments + .keys() + .into_iter() + .filter(|k| k.as_str() != expected_argument) + .collect(); + if !unexpected_arguments.is_empty() { + return Err(format!( + "Unexpected arguments for credential {}: {:?}", + spec.credential_name, unexpected_arguments + )); + } + Ok(()) +} + +fn get_vc_consent_message(req: &Icrc21VcConsentMessageRequest) -> String { + format!( + "Issue credential '{}' with arguments:{}", + req.credential_spec.credential_name, + arguments_as_string(&req.credential_spec.arguments) + ) +} +fn arguments_as_string(maybe_args: &Option>) -> String { + let mut arg_str = String::new(); + let empty_args = HashMap::new(); + let args = maybe_args.as_ref().unwrap_or(&empty_args); + for (key, value) in args { + arg_str.push_str(&format!("\n\t{}: {}", key, value)); + } + arg_str +} + +#[update] +#[candid_method] +fn add_employee(employee_id: Principal) -> String { + EMPLOYEES.with_borrow_mut(|employees| employees.insert(employee_id)); + format!("Added employee {}", employee_id) +} + +#[update] +#[candid_method] +fn add_graduate(graduate_id: Principal) -> String { + GRADUATES.with_borrow_mut(|graduates| graduates.insert(graduate_id)); + format!("Added graduate {}", graduate_id) +} + +fn main() {} + +fn add_signature(sigs: &mut SignatureMap, msg_hash: Hash, seed: Hash) { + let signature_expires_at = time().saturating_add(CERTIFICATE_VALIDITY_PERIOD_NS); + sigs.put(hash_bytes(seed), msg_hash, signature_expires_at); +} + +fn get_signature(sigs: &SignatureMap, seed: Hash, msg_hash: Hash) -> Option> { + let certificate = data_certificate().unwrap_or_else(|| { + trap("data certificate is only available in query calls"); + }); + let witness = sigs.witness(hash_bytes(seed), msg_hash)?; + + let witness_hash = witness.reconstruct(); + let root_hash = sigs.root_hash(); + if witness_hash != root_hash { + trap(&format!( + "internal error: signature map computed an invalid hash tree, witness hash is {}, root hash is {}", + hex::encode(witness_hash), + hex::encode(root_hash) + )); + } + let tree = ic_certified_map::labeled(LABEL_SIG, witness); + #[derive(Serialize)] + struct Sig<'a> { + certificate: ByteBuf, + tree: HashTree<'a>, + } + + let sig = Sig { + certificate: ByteBuf::from(certificate), + tree, + }; + + let mut cbor = serde_cbor::ser::Serializer::new(Vec::new()); + cbor.self_describe().unwrap(); + sig.serialize(&mut cbor).unwrap(); + Some(cbor.into_inner()) +} + +fn calculate_seed(principal: &Principal) -> Hash { + // IMPORTANT: In a real dapp the salt should be set to a random value. + let dummy_salt = [5u8; 32]; + + let mut bytes: Vec = vec![]; + bytes.push(dummy_salt.len() as u8); + bytes.extend_from_slice(&dummy_salt); + + let principal_bytes = principal.as_slice(); + bytes.push(principal_bytes.len() as u8); + bytes.extend(principal_bytes); + hash_bytes(bytes) +} + +fn bachelor_degree_credential(subject_principal: Principal) -> Credential { + let subject: Subject = Subject::from_json_value(json!({ + "id": did_for_principal(subject_principal), + "degree": { + "type": "BachelorDegree", + "name": "Bachelor of Engineering", + "institutionName": "DFINITY College of Engineering", + }, + })) + .unwrap(); + + // Build credential using subject above and issuer. + CredentialBuilder::default() + .id(Url::parse("https://example.edu/credentials/3732").unwrap()) + .issuer(Url::parse("https://example.edu").unwrap()) + .type_("UniversityDegreeCredential") + .subject(subject) + .build() + .unwrap() +} + +fn dfinity_employment_credential(subject_principal: Principal) -> Credential { + let subject: Subject = Subject::from_json_value(json!({ + "id": did_for_principal(subject_principal), + "employee_of": { + "employerId" : "did:web:dfinity.org", + "employerName": "DFINITY Foundation", + }, + })) + .unwrap(); + + // Build credential using subject above and issuer. + CredentialBuilder::default() + .id(Url::parse("https://employment.info/credentials/42").unwrap()) + .issuer(Url::parse("https://employment.info").unwrap()) + .type_("VerifiedEmployee") + .subject(subject) + .build() + .unwrap() +} + +fn prepare_credential_payload( + req: &PrepareCredentialRequest, +) -> Result { + match req.credential_spec.credential_name.as_str() { + "VerifiedEmployee" => { + EMPLOYEES.with_borrow(|employees| verify_authorized_principal(req, employees))?; + Ok(dfinity_employment_credential(req.signed_id_alias.id_alias)) + } + "UniversityDegreeCredential" => { + GRADUATES.with_borrow(|graduates| verify_authorized_principal(req, graduates))?; + Ok(bachelor_degree_credential(req.signed_id_alias.id_alias)) + } + other => Err(IssueCredentialError::UnsupportedCredentialSpec(format!( + "credential {} is not supported", + other + ))), + } +} + +fn verify_authorized_principal( + req: &PrepareCredentialRequest, + authorized_principals: &HashSet, +) -> Result<(), IssueCredentialError> { + if authorized_principals.contains(&req.signed_id_alias.id_dapp) { + Ok(()) + } else { + println!( + "*** principal {} it is not authorized for credential {}", + req.signed_id_alias.id_dapp.to_text(), + req.credential_spec.credential_name + ); + Err(IssueCredentialError::UnauthorizedSubject(format!( + "unauthorized principal {}", + req.signed_id_alias.id_dapp.to_text() + ))) + } +} + +fn internal_error(msg: &str) -> IssueCredentialError { + IssueCredentialError::Internal(String::from(msg)) +} + +fn hash_bytes(value: impl AsRef<[u8]>) -> Hash { + let mut hasher = Sha256::new(); + hasher.update(value.as_ref()); + hasher.finalize().into() +} + +// Order dependent: do not move above any function annotated with #[candid_method]! +candid::export_service!(); + +#[cfg(test)] +mod test { + use crate::__export_service; + use candid::utils::{service_equal, CandidSource}; + use std::path::Path; + + /// Checks candid interface type equality by making sure that the service in the did file is + /// equal to the generated interface. + #[test] + fn check_candid_interface_compatibility() { + let canister_interface = __export_service(); + service_equal( + CandidSource::Text(&canister_interface), + CandidSource::File(Path::new("vc_issuer.did")), + ) + .unwrap_or_else(|e| { + panic!( + "the canister code interface is not equal to the did file: {:?}", + e + ) + }); + } +} diff --git a/demos/vc_issuer/tests/issue_credential.rs b/demos/vc_issuer/tests/issue_credential.rs new file mode 100644 index 0000000000..3acf221fc2 --- /dev/null +++ b/demos/vc_issuer/tests/issue_credential.rs @@ -0,0 +1,677 @@ +//! Tests related to issue_credential canister call. + +use assert_matches::assert_matches; +use candid::{CandidType, Deserialize, Principal}; +use canister_sig_util::{extract_raw_root_pk_from_der, CanisterSigPublicKey}; +use canister_tests::api::internet_identity::vc_mvp as ii_api; +use canister_tests::framework::{ + env, get_wasm_path, principal_1, principal_2, test_principal, II_WASM, +}; +use canister_tests::{flows, match_value}; +use ic_cdk::api::management_canister::provisional::CanisterId; +use ic_test_state_machine_client::{call_candid, call_candid_as}; +use ic_test_state_machine_client::{query_candid_as, CallError, StateMachine}; +use identity_core::common::Value; +use identity_jose::jwt::JwtClaims; +use internet_identity_interface::internet_identity::types::vc_mvp::{ + GetIdAliasRequest, GetIdAliasResponse, PrepareIdAliasRequest, PrepareIdAliasResponse, +}; +use internet_identity_interface::internet_identity::types::FrontendHostname; +use lazy_static::lazy_static; +use std::collections::HashMap; +use std::path::PathBuf; +use vc_util::issuer_api::{ + ArgumentValue, CredentialSpec, GetCredentialRequest, GetCredentialResponse, + Icrc21ConsentMessageResponse, Icrc21ConsentPreferences, Icrc21Error, + Icrc21VcConsentMessageRequest, IssueCredentialError, PrepareCredentialRequest, + PrepareCredentialResponse, SignedIdAlias as SignedIssuerIdAlias, +}; +use vc_util::{ + did_for_principal, verify_credential_jws_with_canister_id, verify_id_alias_credential_jws, + AliasTuple, +}; + +const DUMMY_ROOT_KEY: &str ="308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100adf65638a53056b2222c91bb2457b0274bca95198a5acbdadfe7fd72178f069bdea8d99e9479d8087a2686fc81bf3c4b11fe275570d481f1698f79d468afe0e57acc1e298f8b69798da7a891bbec197093ec5f475909923d48bfed6843dbed1f"; +const DUMMY_II_CANISTER_ID: &str = "rwlgt-iiaaa-aaaaa-aaaaa-cai"; + +/// Dummy alias JWS for testing, valid wrt DUMMY_ROOT_KEY and DUMMY_II_CANISTER_ID. +/// id dapp: nugva-s7c6v-4yszt-koycv-5b623-an7q6-ha2nz-kz6rs-hawgl-nznbe-rqe +/// id alias: vhbib-m4hm6-hpvyc-7prd2-siivo-nbd7r-67o5x-n3awh-qsmqz-wznjf-tqe +const DUMMY_ALIAS_JWS: &str ="eyJqd2siOnsia3R5Ijoib2N0IiwiYWxnIjoiSWNDcyIsImsiOiJNRHd3REFZS0t3WUJCQUdEdUVNQkFnTXNBQW9BQUFBQUFBQUFBQUVCRVNzWHp2bTEzd1BkRTVZSndvLTBCYkdBTHdCN0J2bW1LZUxramFUUTdkQSJ9LCJraWQiOiJkaWQ6aWNwOnJ3bGd0LWlpYWFhLWFhYWFhLWFhYWFhLWNhaSIsImFsZyI6IkljQ3MifQ.eyJleHAiOjE2MjAzMjk1MzAsImlzcyI6Imh0dHBzOi8vaWRlbnRpdHkuaWMwLmFwcC8iLCJuYmYiOjE2MjAzMjg2MzAsImp0aSI6Imh0dHBzOi8vaWRlbnRpdHkuaWMwLmFwcC9jcmVkZW50aWFsLzE2MjAzMjg2MzAwMDAwMDAwMDAiLCJzdWIiOiJkaWQ6aWNwOm51Z3ZhLXM3YzZ2LTR5c3p0LWtveWN2LTViNjIzLWFuN3E2LWhhMm56LWt6NnJzLWhhd2dsLW56bmJlLXJxZSIsInZjIjp7IkBjb250ZXh0IjoiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvdjEiLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiSW50ZXJuZXRJZGVudGl0eUlkQWxpYXMiXSwiY3JlZGVudGlhbFN1YmplY3QiOnsiaGFzX2lkX2FsaWFzIjoiZGlkOmljcDp2aGJpYi1tNGhtNi1ocHZ5Yy03cHJkMi1zaWl2by1uYmQ3ci02N281eC1uM2F3aC1xc21xei13em5qZi10cWUifX19.2dn3omtjZXJ0aWZpY2F0ZVkBsdnZ96JkdHJlZYMBgwGDAYMCSGNhbmlzdGVygwGDAkoAAAAAAAAAAAEBgwGDAYMBgwJOY2VydGlmaWVkX2RhdGGCA1ggnk2d-80NLXpxOs-YszCLd4yvrGBtLEGqe6rp6khNthCCBFgg0sz_P8xdqTDewOhKJUHmWFFrS7FQHnDotBDmmGoFfWCCBFggaAMB9TDaAhXeQPY8DCCUq90vqJJDqpDAVwU-0WdA9OmCBFgghh7VsiTOqTlAiY8hcsbF1pFnG5t1x4kQ7rt2bae_6iGCBFgggcqzMKDpDQKcyRl6xrGy4SIYEtgVJgSLlHGFvHN6zuSCBFggBNxwNVuf0_gTaiM6hbpNNCcEIBfxLHoor0N1mpX-uNeCBFggICEcda6JC5WRFIbzoGGJdJINoas-EWtoCU0lysCe3OGDAYIEWCA1U_ZYHVOz3Sdkb2HIsNoLDDiBuFfG3DxH6miIwRPra4MCRHRpbWWCA0mAuK7U3YmkvhZpc2lnbmF0dXJlWDCY_kVxXw7Wk8HlA0FqOpX-3WMdI0mmxAtY9DJv8xEkfitcTOR0FcE412IftkdH48hkdHJlZYMBggRYIPKxlnFAySvK4ahA_Q0IkEopYPh8H4_IRCFRGb2i23QRgwJDc2lngwJYIFcsa4eb-HMrTnmGWNje_RfErQYi0wNCJvGDrzqazq0OgwGCBFggg7ijRBePgPVau7zffNEvAXThew-FqcBH_cB-fF7722eDAlgg3ikzXLDphmWB8YbAxZDjZfLFd6bDS-sLAPzmVj0nlvSCA0A"; + +lazy_static! { + /** The gzipped Wasm module for the current VC_ISSUER build, i.e. the one we're testing */ + pub static ref VC_ISSUER_WASM: Vec = { + let def_path = PathBuf::from("./").join("vc_issuer.wasm.gz"); + let err = format!(" + Could not find VC Issuer Wasm module for current build. + I will look for it at {:?} (note that I run from {:?}). + ", &def_path, + &std::env::current_dir().map(|x| x.display().to_string()).unwrap_or_else(|_| + "an unknown directory".to_string())); + get_wasm_path("VC_ISSUER_WASM".to_string(), &def_path).expect(&err) + + }; + + pub static ref DUMMY_ISSUER_INIT: IssuerInit = IssuerInit { + ic_root_key_der: hex::decode(DUMMY_ROOT_KEY).unwrap(), + idp_canister_ids: vec![Principal::from_text(DUMMY_II_CANISTER_ID).unwrap()], + }; + + pub static ref DUMMY_SIGNED_ID_ALIAS: SignedIssuerIdAlias = SignedIssuerIdAlias { + id_alias: Principal::from_text("vhbib-m4hm6-hpvyc-7prd2-siivo-nbd7r-67o5x-n3awh-qsmqz-wznjf-tqe").unwrap(), + id_dapp: Principal::from_text("nugva-s7c6v-4yszt-koycv-5b623-an7q6-ha2nz-kz6rs-hawgl-nznbe-rqe").unwrap(), + credential_jws: DUMMY_ALIAS_JWS.to_string(), + }; +} + +pub fn install_canister(env: &StateMachine, wasm: Vec) -> CanisterId { + let canister_id = env.create_canister(None); + let arg = candid::encode_one("()").expect("error encoding II installation arg as candid"); + env.install_canister(canister_id, wasm, arg, None); + canister_id +} + +#[derive(CandidType, Deserialize)] +pub struct IssuerInit { + /// Root of trust for checking canister signatures. + ic_root_key_der: Vec, + /// List of canister ids that are allowed to provide id alias credentials. + idp_canister_ids: Vec, +} + +pub fn install_issuer(env: &StateMachine, init: &IssuerInit) -> CanisterId { + let canister_id = env.create_canister(None); + let arg = candid::encode_one(Some(init)).expect("error encoding II installation arg as candid"); + env.install_canister(canister_id, VC_ISSUER_WASM.clone(), arg, None); + canister_id +} + +mod api { + use super::*; + + pub fn configure( + env: &StateMachine, + canister_id: CanisterId, + config: &IssuerInit, + ) -> Result<(), CallError> { + call_candid(env, canister_id, "configure", (config,)) + } + + pub fn vc_consent_message( + env: &StateMachine, + canister_id: CanisterId, + sender: Principal, + consent_message_request: &Icrc21VcConsentMessageRequest, + ) -> Result, CallError> { + call_candid_as( + env, + canister_id, + sender, + "vc_consent_message", + (consent_message_request,), + ) + .map(|(x,)| x) + } + + pub fn add_employee( + env: &StateMachine, + canister_id: CanisterId, + sender: Principal, + employee_id: Principal, + ) -> Result { + call_candid_as(env, canister_id, sender, "add_employee", (employee_id,)).map(|(x,)| x) + } + + pub fn add_graduate( + env: &StateMachine, + canister_id: CanisterId, + sender: Principal, + employee_id: Principal, + ) -> Result { + call_candid_as(env, canister_id, sender, "add_graduate", (employee_id,)).map(|(x,)| x) + } + + pub fn prepare_credential( + env: &StateMachine, + canister_id: CanisterId, + sender: Principal, + prepare_credential_request: &PrepareCredentialRequest, + ) -> Result { + call_candid_as( + env, + canister_id, + sender, + "prepare_credential", + (prepare_credential_request,), + ) + .map(|(x,)| x) + } + + pub fn get_credential( + env: &StateMachine, + canister_id: CanisterId, + sender: Principal, + get_credential_request: &GetCredentialRequest, + ) -> Result { + query_candid_as( + env, + canister_id, + sender, + "get_credential", + (get_credential_request,), + ) + .map(|(x,)| x) + } +} + +/// Verifies that the consent message can be requested. +#[test] +fn should_return_vc_consent_message() { + let env = env(); + let canister_id = install_canister(&env, VC_ISSUER_WASM.clone()); + + let mut args = HashMap::new(); + args.insert( + "employerName".to_string(), + ArgumentValue::String("DFINITY Foundation".to_string()), + ); + let consent_message_request = Icrc21VcConsentMessageRequest { + credential_spec: CredentialSpec { + credential_name: "VerifiedEmployee".to_string(), + arguments: Some(args), + }, + preferences: Icrc21ConsentPreferences { + language: "en-US".to_string(), + }, + }; + + let response = + api::vc_consent_message(&env, canister_id, principal_1(), &consent_message_request) + .expect("API call failed") + .expect("Got 'None' from vc_consent_message"); + assert_matches!(response, Icrc21ConsentMessageResponse::Ok(_)); + if let Icrc21ConsentMessageResponse::Ok(info) = response { + assert_eq!(info.language, "en-US"); + assert!(info + .consent_message + .contains("Issue credential 'VerifiedEmployee'")); + assert!(info.consent_message.contains("employerName")); + assert!(info.consent_message.contains("DFINITY Foundation")); + } +} + +#[test] +fn should_fail_vc_consent_message_if_not_supported() { + let env = env(); + let canister_id = install_canister(&env, VC_ISSUER_WASM.clone()); + + let consent_message_request = Icrc21VcConsentMessageRequest { + credential_spec: CredentialSpec { + credential_name: "VerifiedAdult".to_string(), + arguments: None, + }, + preferences: Icrc21ConsentPreferences { + language: "en-US".to_string(), + }, + }; + + let response = + api::vc_consent_message(&env, canister_id, principal_1(), &consent_message_request) + .expect("API call failed") + .expect("Got 'None' from vc_consent_message"); + assert_matches!( + response, + Icrc21ConsentMessageResponse::Err(Icrc21Error::NotSupported(_)) + ); +} + +#[test] +fn should_fail_vc_consent_message_if_missing_arguments() { + let env = env(); + let canister_id = install_canister(&env, VC_ISSUER_WASM.clone()); + + let consent_message_request = Icrc21VcConsentMessageRequest { + credential_spec: CredentialSpec { + credential_name: "VerifiedEmployee".to_string(), + arguments: None, + }, + preferences: Icrc21ConsentPreferences { + language: "en-US".to_string(), + }, + }; + + let response = + api::vc_consent_message(&env, canister_id, principal_1(), &consent_message_request) + .expect("API call failed") + .expect("Got 'None' from vc_consent_message"); + assert_matches!( + response, + Icrc21ConsentMessageResponse::Err(Icrc21Error::NotSupported(_)) + ); +} + +#[test] +fn should_fail_vc_consent_message_if_missing_required_argument() { + let env = env(); + let canister_id = install_canister(&env, VC_ISSUER_WASM.clone()); + + let mut args = HashMap::new(); + args.insert("wrongArgument".to_string(), ArgumentValue::Int(42)); + + let consent_message_request = Icrc21VcConsentMessageRequest { + credential_spec: CredentialSpec { + credential_name: "VerifiedEmployee".to_string(), + arguments: None, + }, + preferences: Icrc21ConsentPreferences { + language: "en-US".to_string(), + }, + }; + + let response = + api::vc_consent_message(&env, canister_id, principal_1(), &consent_message_request) + .expect("API call failed") + .expect("Got 'None' from vc_consent_message"); + assert_matches!( + response, + Icrc21ConsentMessageResponse::Err(Icrc21Error::NotSupported(_)) + ); +} + +fn employee_credential_spec() -> CredentialSpec { + let mut args = HashMap::new(); + args.insert( + "employerName".to_string(), + ArgumentValue::String("DFINITY Foundation".to_string()), + ); + CredentialSpec { + credential_name: "VerifiedEmployee".to_string(), + arguments: Some(args), + } +} + +fn degree_credential_spec() -> CredentialSpec { + let mut args = HashMap::new(); + args.insert( + "institutionName".to_string(), + ArgumentValue::String("DFINITY College of Engineering".to_string()), + ); + CredentialSpec { + credential_name: "UniversityDegreeCredential".to_string(), + arguments: Some(args), + } +} + +#[test] +fn should_fail_prepare_credential_for_unauthorized_principal() { + let env = env(); + let issuer_id = install_issuer(&env, &DUMMY_ISSUER_INIT); + let signed_id_alias = DUMMY_SIGNED_ID_ALIAS.clone(); + let response = api::prepare_credential( + &env, + issuer_id, + signed_id_alias.id_dapp, + &PrepareCredentialRequest { + credential_spec: employee_credential_spec(), + signed_id_alias, + }, + ) + .expect("API call failed"); + assert_matches!(response, PrepareCredentialResponse::Err(e) if format!("{:?}", e).contains("unauthorized principal")); +} + +#[test] +fn should_fail_prepare_credential_for_wrong_sender() { + let env = env(); + let issuer_id = install_issuer(&env, &DUMMY_ISSUER_INIT); + let signed_id_alias = DUMMY_SIGNED_ID_ALIAS.clone(); + + let response = api::prepare_credential( + &env, + issuer_id, + principal_1(), // not the same as signed_id_alias.id_dapp + &PrepareCredentialRequest { + credential_spec: employee_credential_spec(), + signed_id_alias, + }, + ) + .expect("API call failed"); + assert_matches!(response, + PrepareCredentialResponse::Err(IssueCredentialError::UnauthorizedSubject(e)) if e.contains("Caller 6epth-hmqup-wz4mv-svl2m-mhcbb-24skq-tbdhq-2txct-2qugv-xuzva-eqe does not match id alias dapp principal nugva-s7c6v-4yszt-koycv-5b623-an7q6-ha2nz-kz6rs-hawgl-nznbe-rqe.")); +} + +#[test] +fn should_fail_get_credential_for_wrong_sender() { + let env = env(); + let issuer_id = install_issuer(&env, &DUMMY_ISSUER_INIT); + let signed_id_alias = DUMMY_SIGNED_ID_ALIAS.clone(); + let authorized_principal = signed_id_alias.id_dapp; + api::add_employee( + &env, + issuer_id, + Principal::anonymous(), + authorized_principal, + ) + .expect("failed to add employee"); + let unauthorized_principal = test_principal(2); + + match_value!( + api::prepare_credential( + &env, + issuer_id, + authorized_principal, + &PrepareCredentialRequest { + credential_spec: employee_credential_spec(), + signed_id_alias: signed_id_alias.clone(), + }, + ), + Ok(PrepareCredentialResponse::Ok(prepare_credential_response)) + ); + let get_credential_response = api::get_credential( + &env, + issuer_id, + unauthorized_principal, + &GetCredentialRequest { + credential_spec: employee_credential_spec(), + signed_id_alias, + prepared_context: prepare_credential_response.prepared_context, + }, + ) + .expect("API call failed"); + assert_matches!(get_credential_response, + GetCredentialResponse::Err(IssueCredentialError::UnauthorizedSubject(e)) if e.contains("Caller sl5og-mycaa-aaaaa-aaaap-4 does not match id alias dapp principal nugva-s7c6v-4yszt-koycv-5b623-an7q6-ha2nz-kz6rs-hawgl-nznbe-rqe.")); +} + +#[test] +fn should_fail_prepare_credential_for_anonymous_caller() { + let env = env(); + let issuer_id = install_issuer(&env, &DUMMY_ISSUER_INIT); + let signed_id_alias = DUMMY_SIGNED_ID_ALIAS.clone(); + let response = api::prepare_credential( + &env, + issuer_id, + Principal::anonymous(), + &PrepareCredentialRequest { + credential_spec: employee_credential_spec(), + signed_id_alias, + }, + ) + .expect("API call failed"); + assert_matches!(response, + PrepareCredentialResponse::Err(IssueCredentialError::UnauthorizedSubject(e)) if e.contains("Caller 2vxsx-fae does not match id alias dapp principal nugva-s7c6v-4yszt-koycv-5b623-an7q6-ha2nz-kz6rs-hawgl-nznbe-rqe.")); +} + +#[test] +fn should_fail_prepare_credential_for_wrong_root_key() { + let env = env(); + let issuer_id = install_issuer( + &env, + &IssuerInit { + ic_root_key_der: canister_sig_util::IC_ROOT_PK_DER.to_vec(), // does not match the DUMMY_ROOT_KEY, which is used in DUMMY_ALIAS_JWS + idp_canister_ids: vec![Principal::from_text(DUMMY_II_CANISTER_ID).unwrap()], + }, + ); + let response = api::prepare_credential( + &env, + issuer_id, + DUMMY_SIGNED_ID_ALIAS.clone().id_dapp, + &PrepareCredentialRequest { + credential_spec: employee_credential_spec(), + signed_id_alias: DUMMY_SIGNED_ID_ALIAS.clone(), + }, + ) + .expect("API call failed"); + assert_matches!( + response, + PrepareCredentialResponse::Err(IssueCredentialError::InvalidIdAlias(_)) + ); +} + +#[test] +fn should_fail_prepare_credential_for_wrong_idp_canister_id() { + let env = env(); + let issuer_id = install_issuer( + &env, + &IssuerInit { + ic_root_key_der: hex::decode(DUMMY_ROOT_KEY).unwrap(), + idp_canister_ids: vec![Principal::from_text("rdmx6-jaaaa-aaaaa-aaadq-cai").unwrap()], // does not match the DUMMY_II_CANISTER_ID, which is used in DUMMY_ALIAS_JWS + }, + ); + let response = api::prepare_credential( + &env, + issuer_id, + DUMMY_SIGNED_ID_ALIAS.clone().id_dapp, + &PrepareCredentialRequest { + credential_spec: employee_credential_spec(), + signed_id_alias: DUMMY_SIGNED_ID_ALIAS.clone(), + }, + ) + .expect("API call failed"); + assert_matches!( + response, + PrepareCredentialResponse::Err(IssueCredentialError::InvalidIdAlias(_)) + ); +} + +#[test] +fn should_prepare_employee_credential_for_authorized_principal() { + let env = env(); + let issuer_id = install_issuer(&env, &DUMMY_ISSUER_INIT); + let signed_id_alias = DUMMY_SIGNED_ID_ALIAS.clone(); + api::add_employee(&env, issuer_id, principal_2(), signed_id_alias.id_dapp) + .expect("API call failed"); + let response = api::prepare_credential( + &env, + issuer_id, + signed_id_alias.id_dapp, + &PrepareCredentialRequest { + credential_spec: employee_credential_spec(), + signed_id_alias, + }, + ) + .expect("API call failed"); + assert_matches!(response, PrepareCredentialResponse::Ok(_)); +} + +#[test] +fn should_prepare_degree_credential_for_authorized_principal() { + let env = env(); + let issuer_id = install_issuer(&env, &DUMMY_ISSUER_INIT); + let signed_id_alias = DUMMY_SIGNED_ID_ALIAS.clone(); + api::add_graduate(&env, issuer_id, principal_2(), signed_id_alias.id_dapp) + .expect("API call failed"); + let response = api::prepare_credential( + &env, + issuer_id, + signed_id_alias.id_dapp, + &PrepareCredentialRequest { + credential_spec: degree_credential_spec(), + signed_id_alias, + }, + ) + .expect("API call failed"); + assert_matches!(response, PrepareCredentialResponse::Ok(_)); +} + +/// Verifies that different credentials are being created including II interactions. +#[test] +fn should_issue_credential_e2e() -> Result<(), CallError> { + let env = env(); + let ii_id = install_canister(&env, II_WASM.clone()); + let issuer_id = install_issuer( + &env, + &IssuerInit { + ic_root_key_der: env.root_key().to_vec(), + idp_canister_ids: vec![ii_id], + }, + ); + let identity_number = flows::register_anchor(&env, ii_id); + let relying_party = FrontendHostname::from("https://some-dapp.com"); + let issuer = FrontendHostname::from("https://some-issuer.com"); + + let prepare_id_alias_req = PrepareIdAliasRequest { + identity_number, + relying_party: relying_party.clone(), + issuer: issuer.clone(), + }; + + let prepare_response = + ii_api::prepare_id_alias(&env, ii_id, principal_1(), prepare_id_alias_req)? + .expect("Got 'None' from prepare_id_alias"); + + let prepared_id_alias = if let PrepareIdAliasResponse::Ok(response) = prepare_response { + response + } else { + panic!("prepare id_alias failed") + }; + let canister_sig_pk = + CanisterSigPublicKey::try_from(prepared_id_alias.canister_sig_pk_der.as_ref()) + .expect("failed parsing canister sig pk"); + + let get_id_alias_req = GetIdAliasRequest { + identity_number, + relying_party, + issuer, + rp_id_alias_jwt: prepared_id_alias.rp_id_alias_jwt, + issuer_id_alias_jwt: prepared_id_alias.issuer_id_alias_jwt, + }; + let id_alias_credentials = + match ii_api::get_id_alias(&env, ii_id, principal_1(), get_id_alias_req)? + .expect("Got 'None' from get_id_alias") + { + GetIdAliasResponse::Ok(credentials) => credentials, + GetIdAliasResponse::NoSuchCredentials(err) => { + panic!("{}", format!("failed to get id_alias credentials: {}", err)) + } + GetIdAliasResponse::AuthenticationFailed(err) => { + panic!("{}", format!("failed authentication: {}", err)) + } + }; + + let root_pk_raw = + extract_raw_root_pk_from_der(&env.root_key()).expect("Failed decoding IC root key."); + verify_id_alias_credential_jws( + &id_alias_credentials + .issuer_id_alias_credential + .credential_jws, + &AliasTuple { + id_alias: id_alias_credentials.issuer_id_alias_credential.id_alias, + id_dapp: id_alias_credentials.issuer_id_alias_credential.id_dapp, + }, + &canister_sig_pk.canister_id, + &root_pk_raw, + ) + .expect("Invalid ID alias"); + + api::add_employee( + &env, + issuer_id, + id_alias_credentials.issuer_id_alias_credential.id_dapp, + id_alias_credentials.issuer_id_alias_credential.id_dapp, + )?; + api::add_graduate( + &env, + issuer_id, + id_alias_credentials.issuer_id_alias_credential.id_dapp, + id_alias_credentials.issuer_id_alias_credential.id_dapp, + )?; + + for credential_spec in vec![employee_credential_spec(), degree_credential_spec()] { + let prepare_credential_response = api::prepare_credential( + &env, + issuer_id, + id_alias_credentials + .issuer_id_alias_credential + .id_dapp + .clone(), + &PrepareCredentialRequest { + credential_spec: credential_spec.clone(), + signed_id_alias: SignedIssuerIdAlias { + id_alias: id_alias_credentials.issuer_id_alias_credential.id_alias, + id_dapp: id_alias_credentials.issuer_id_alias_credential.id_dapp, + credential_jws: id_alias_credentials + .issuer_id_alias_credential + .credential_jws + .clone(), + }, + }, + )?; + let prepared_credential = + if let PrepareCredentialResponse::Ok(data) = prepare_credential_response { + data + } else { + panic!( + "Prepare credential failed: {:?}", + prepare_credential_response + ); + }; + + let get_credential_response = api::get_credential( + &env, + issuer_id, + id_alias_credentials + .issuer_id_alias_credential + .id_dapp + .clone(), + &GetCredentialRequest { + credential_spec: credential_spec.clone(), + signed_id_alias: SignedIssuerIdAlias { + id_alias: id_alias_credentials.issuer_id_alias_credential.id_alias, + id_dapp: id_alias_credentials.issuer_id_alias_credential.id_dapp, + credential_jws: id_alias_credentials + .issuer_id_alias_credential + .credential_jws + .clone(), + }, + prepared_context: prepared_credential.prepared_context, + }, + )?; + match_value!( + get_credential_response, + GetCredentialResponse::Ok(credential_data) + ); + let claims = verify_credential_jws_with_canister_id( + &credential_data.vc_jws, + &issuer_id, + &root_pk_raw, + ) + .expect("credential verification failed"); + validate_vc_claims( + &claims, + &credential_spec, + id_alias_credentials.issuer_id_alias_credential.id_alias, + ); + } + + Ok(()) +} + +/// Validates that the given claims are consistent with the credential spec and the +/// requesting principal. +fn validate_vc_claims( + claims: &JwtClaims, + credential_spec: &CredentialSpec, + subject_principal: Principal, +) { + assert_eq!( + claims.sub(), + Some(did_for_principal(subject_principal)).as_deref() + ); + let vc = claims.vc().expect("missing vc in id_alias JWT claims"); + assert_eq!( + vc.get("type"), + Some(Value::Array(vec![ + Value::String("VerifiableCredential".to_string()), + Value::String(credential_spec.credential_name.clone()) + ])) + .as_ref() + ); +} + +#[test] +fn should_configure() { + let env = env(); + let issuer_id = install_canister(&env, VC_ISSUER_WASM.clone()); + api::configure(&env, issuer_id, &DUMMY_ISSUER_INIT).expect("API call failed"); +} diff --git a/demos/vc_issuer/vc_issuer.did b/demos/vc_issuer/vc_issuer.did new file mode 100644 index 0000000000..fea3d33645 --- /dev/null +++ b/demos/vc_issuer/vc_issuer.did @@ -0,0 +1,107 @@ +/// Candid interface of the example VC issuer canister. +/// The interface contains both the functionality required by the VC-spec +/// (https://github.com/dfinity/internet-identity/blob/main/docs/vc-spec.md) +/// and additional APIs for configuring the canister and using it for testing. + +/// Specification of a requested credential. +type CredentialSpec = record { + credential_name : text; + /// arguments are optional, and specific to the credential_name + arguments : opt vec record { text; ArgumentValue }; +}; +type ArgumentValue = variant { "int" : int32; string : text }; + +/// Messages for ICRC-21 consent message, cf. +/// https://github.com/dfinity/wg-identity-authentication/blob/main/topics/icrc_21_consent_msg.md +type Icrc21ConsentInfo = record { consent_message : text; language : text }; +type Icrc21ConsentMessageResponse = variant { + ok : Icrc21ConsentInfo; + err : Icrc21Error; +}; +type Icrc21ConsentPreferences = record { language : text }; +type Icrc21Error = variant { + generic_error : Icrc21ErrorInfo; + forbidden : Icrc21ErrorInfo; + not_supported : Icrc21ErrorInfo; + malformed_call : Icrc21ErrorInfo; +}; +type Icrc21ErrorInfo = record { description : text; error_code : nat64 }; +type Icrc21VcConsentMessageRequest = record { + preferences : Icrc21ConsentPreferences; + credential_spec : CredentialSpec; +}; + +/// Messages for requesting issuance of a credential. +/// The issuance proceeds in two steps: +/// - `prepare_credential`, and +/// - `get_credential` +/// where the split of work between the two steps depends on the specifics of the issuer, +/// and the second second step returns the actual credential (if any). +/// The two steps can use `prepared_context`-value to transfer information between them. + +/// Messages for `prepare_credential`. +type PrepareCredentialRequest = record { + signed_id_alias : SignedIdAlias; + credential_spec : CredentialSpec; +}; +type PrepareCredentialResponse = variant { + ok : PreparedCredentialData; + err : IssueCredentialError; +}; +type PreparedCredentialData = record { prepared_context : opt vec nat8 }; + +/// Messages for `get_credential`. +type GetCredentialRequest = record { + signed_id_alias : SignedIdAlias; + credential_spec : CredentialSpec; + prepared_context : opt vec nat8; +}; +type GetCredentialResponse = variant { + ok : IssuedCredentialData; + err : IssueCredentialError; +}; + +type SignedIdAlias = record { + credential_jws : text; + id_alias : principal; + id_dapp : principal; +}; +type IssuedCredentialData = record { vc_jws : text }; +type IssueCredentialError = variant { + /// The caller is not known to the issuer. Caller should register first with the issuer before retrying. + unknown_subject : text; + /// The caller is not authorized to obtain the requested credential. Caller requested a credential + /// for a different principal, or the issuer does not have sufficient knowledge about the caller + /// to issue the requested credential. + unauthorized_subject : text; + /// The id_alias credential provided by the identity provider is invalid. + invalid_id_alias : text; + /// The issuer does not issue credentials described in the credential spec. + unsupported_credential_spec : text; + /// Internal errors, indicate malfunctioning of the issuer. + signature_not_found : text; + internal : text; +}; + +/// Configuration specific to this issuer. +type IssuerConfig = record { + /// Root of trust for checking canister signatures. + ic_root_key_der : blob; + /// List of canister ids that are allowed to provide id alias credentials. + idp_canister_ids : vec principal; +}; + +service: (opt IssuerConfig) -> { + /// VC-flow API. + vc_consent_message : (Icrc21VcConsentMessageRequest) -> (Icrc21ConsentMessageResponse); + prepare_credential : (PrepareCredentialRequest) -> (PrepareCredentialResponse); + get_credential : (GetCredentialRequest) -> (GetCredentialResponse) query; + + /// Configure the issuer (e.g. set the root key), used for deployment/testing. + configure: (IssuerConfig) -> (); + + /// API for obtaining information about users, for testing only. + /// In a real-world issuer the data acquisition functionality should be more elaborate and authenticated. + add_employee : (principal) -> (text); + add_graduate : (principal) -> (text); +} diff --git a/docs/vc-spec.md b/docs/vc-spec.md index a8d503b02b..c1cedcfbd7 100644 --- a/docs/vc-spec.md +++ b/docs/vc-spec.md @@ -5,7 +5,7 @@ This section describes the (Candid) interface to be implemented by an issuer of verifiable credentials on the IC. This interface is used by the II-canister during attribute sharing flow (cf. [flow description](https://github.com/dfinity/wg-identity-authentication/blob/d2664795afe9cea40386804bdb1259a47e34540d/topics/attribute-sharing.md)) -An example implementation of the interface is given in [demos/vc_issuer](https://github.com/dfinity/internet-identity/tree/vc-mvp/demos/vc_issuer). +An example implementation of the interface is given in [demos/vc_issuer](../demos/vc_issuer). The Candid interface is as follows, and the subsequent sections describe the services and the corresponding messages in more detail. diff --git a/src/canister_tests/src/framework.rs b/src/canister_tests/src/framework.rs index ce782ab758..ae6a30caa2 100644 --- a/src/canister_tests/src/framework.rs +++ b/src/canister_tests/src/framework.rs @@ -93,7 +93,7 @@ lazy_static! { * The `env_var` environment variable is also read for custom location; if the variable is set * _but_ the Wasm module is not present, we simply panic (i.e. we don't return None) */ -fn get_wasm_path(env_var: String, default_path: &path::PathBuf) -> Option> { +pub fn get_wasm_path(env_var: String, default_path: &path::PathBuf) -> Option> { match env::var_os(env_var.clone()) { None => { if !default_path.exists() { diff --git a/src/vc_util/src/issuer_api.rs b/src/vc_util/src/issuer_api.rs index 5eeaf67365..efb165fe7d 100644 --- a/src/vc_util/src/issuer_api.rs +++ b/src/vc_util/src/issuer_api.rs @@ -39,6 +39,8 @@ pub enum IssueCredentialError { SignatureNotFound(String), #[serde(rename = "internal")] Internal(String), + #[serde(rename = "unsupported_credential_spec")] + UnsupportedCredentialSpec(String), } #[derive(Clone, Debug, CandidType, Deserialize, Eq, PartialEq)]