diff --git a/Cargo.lock b/Cargo.lock index fb38b3930..c034ea5f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -783,9 +783,9 @@ dependencies = [ [[package]] name = "bls12_381_plus" -version = "0.8.15" +version = "0.8.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcdcbc984ce4bbbba587f9415ecfd5ed15c59b33defe276482c517b26a6a6716" +checksum = "68ed5f583bb45888c562e1f117f7f20ce86a640f1163c38fe665ac7a71190861" dependencies = [ "arrayref", "elliptic-curve 0.13.8", @@ -1228,7 +1228,7 @@ dependencies = [ "cocoa-foundation", "core-foundation", "core-graphics", - "foreign-types", + "foreign-types 0.5.0", "libc", "objc", ] @@ -1316,7 +1316,7 @@ checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" [[package]] name = "consumer" version = "0.1.0" -source = "git+https://git@github.com/impierce/did-manager.git?tag=v1.0.0-beta.3#3ad5e3dba7bc76df8d6cb4a4fd2df2238d88710b" +source = "git+https://git@github.com/impierce/did-manager.git?rev=c1cfda0#c1cfda09ae1e5797ba013ead8aa6ace616b75a6d" dependencies = [ "did_iota", "did_jwk", @@ -1365,7 +1365,7 @@ dependencies = [ "bitflags 1.3.2", "core-foundation", "core-graphics-types", - "foreign-types", + "foreign-types 0.5.0", "libc", ] @@ -1893,7 +1893,7 @@ dependencies = [ "serde", "serde_json", "sha2 0.9.9", - "x25519-dalek", + "x25519-dalek 1.1.1", ] [[package]] @@ -1929,9 +1929,9 @@ dependencies = [ [[package]] name = "did_iota" version = "0.1.0" -source = "git+https://git@github.com/impierce/did-manager.git?tag=v1.0.0-beta.3#3ad5e3dba7bc76df8d6cb4a4fd2df2238d88710b" +source = "git+https://git@github.com/impierce/did-manager.git?rev=c1cfda0#c1cfda09ae1e5797ba013ead8aa6ace616b75a6d" dependencies = [ - "bls12_381_plus 0.8.15", + "bls12_381_plus 0.8.17", "identity_iota", "identity_stronghold", "iota-sdk", @@ -1943,7 +1943,7 @@ dependencies = [ [[package]] name = "did_jwk" version = "0.1.0" -source = "git+https://git@github.com/impierce/did-manager.git?tag=v1.0.0-beta.3#3ad5e3dba7bc76df8d6cb4a4fd2df2238d88710b" +source = "git+https://git@github.com/impierce/did-manager.git?rev=c1cfda0#c1cfda09ae1e5797ba013ead8aa6ace616b75a6d" dependencies = [ "did-jwk", "identity_iota", @@ -1960,7 +1960,7 @@ dependencies = [ [[package]] name = "did_key" version = "0.1.0" -source = "git+https://git@github.com/impierce/did-manager.git?tag=v1.0.0-beta.3#3ad5e3dba7bc76df8d6cb4a4fd2df2238d88710b" +source = "git+https://git@github.com/impierce/did-manager.git?rev=c1cfda0#c1cfda09ae1e5797ba013ead8aa6ace616b75a6d" dependencies = [ "did-method-key", "identity_iota", @@ -1978,7 +1978,7 @@ dependencies = [ [[package]] name = "did_manager" version = "0.1.0" -source = "git+https://git@github.com/impierce/did-manager.git?tag=v1.0.0-beta.3#3ad5e3dba7bc76df8d6cb4a4fd2df2238d88710b" +source = "git+https://git@github.com/impierce/did-manager.git?rev=c1cfda0#c1cfda09ae1e5797ba013ead8aa6ace616b75a6d" dependencies = [ "consumer", "producer", @@ -2006,7 +2006,7 @@ dependencies = [ [[package]] name = "did_web" version = "0.1.0" -source = "git+https://git@github.com/impierce/did-manager.git?tag=v1.0.0-beta.3#3ad5e3dba7bc76df8d6cb4a4fd2df2238d88710b" +source = "git+https://git@github.com/impierce/did-manager.git?rev=c1cfda0#c1cfda09ae1e5797ba013ead8aa6ace616b75a6d" dependencies = [ "did-web", "identity_iota", @@ -2025,15 +2025,16 @@ dependencies = [ [[package]] name = "dif-presentation-exchange" version = "0.1.0" -source = "git+https://git@github.com/impierce/openid4vc.git?rev=d095db0#d095db0b943fa208baae298d2e1172e34aa995bc" +source = "git+https://git@github.com/impierce/openid4vc.git?rev=bc4d6d2#bc4d6d2f9ea8cae7ab61da2099af3b95e9616585" dependencies = [ "getset", "jsonpath_lib", - "jsonschema", + "jsonschema 0.17.1", "jsonwebtoken", "serde", "serde_json", "serde_with 3.9.0", + "tracing", "url", ] @@ -2471,6 +2472,17 @@ dependencies = [ "regex", ] +[[package]] +name = "fancy-regex" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "531e46835a22af56d1e3b66f04844bed63158bc094a628bec1d321d9b4c44bf2" +dependencies = [ + "bit-set", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", +] + [[package]] name = "fastrand" version = "1.9.0" @@ -2624,6 +2636,15 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared 0.1.1", +] + [[package]] name = "foreign-types" version = "0.5.0" @@ -2631,7 +2652,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" dependencies = [ "foreign-types-macros", - "foreign-types-shared", + "foreign-types-shared 0.3.1", ] [[package]] @@ -2645,6 +2666,12 @@ dependencies = [ "syn 2.0.71", ] +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "foreign-types-shared" version = "0.3.1" @@ -2670,6 +2697,16 @@ dependencies = [ "num", ] +[[package]] +name = "fraction" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f158e3ff0a1b334408dc9fb811cd99b446986f4d8b741bb08f9df1604085ae7" +dependencies = [ + "lazy_static", + "num", +] + [[package]] name = "funty" version = "2.0.0" @@ -3233,7 +3270,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.2.6", + "indexmap 2.6.0", "slab", "tokio", "tokio-util", @@ -3278,6 +3315,12 @@ dependencies = [ "serde", ] +[[package]] +name = "hashbrown" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" + [[package]] name = "heapless" version = "0.7.17" @@ -3527,7 +3570,7 @@ dependencies = [ "httpdate", "itoa 1.0.11", "pin-project-lite", - "socket2 0.5.7", + "socket2 0.4.10", "tokio", "tower-service", "tracing", @@ -4072,7 +4115,7 @@ dependencies = [ "sha256", "stronghold_engine", "stronghold_ext 0.1.0 (git+https://github.com/tensor-programming/stronghold_ext)", - "strum", + "strum 0.25.0", "tauri", "tempfile", "thiserror", @@ -4088,15 +4131,13 @@ dependencies = [ [[package]] name = "identity_core" version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee35f34cfc61310309a2cec6695e325676c425bfabc0b8fed9c42427d1ee6607" +source = "git+https://github.com/impierce/identity.rs?branch=fix/compile-fixes#d36175ce30d3be6c40da0c39f7d6c95ae424894e" dependencies = [ - "iota-crypto", "js-sys", "multibase 0.9.1", "serde", "serde_json", - "strum", + "strum 0.25.0", "thiserror", "time", "url", @@ -4106,24 +4147,28 @@ dependencies = [ [[package]] name = "identity_credential" version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4d0cf0ed8a8f1280ba518eed2990472d6d097bc430a62a81b3fcd7949054782" +source = "git+https://github.com/impierce/identity.rs?branch=fix/compile-fixes#d36175ce30d3be6c40da0c39f7d6c95ae424894e" dependencies = [ + "anyhow", "async-trait", "flate2", + "futures", "identity_core", "identity_did", "identity_document", "identity_verification", - "indexmap 2.2.6", + "indexmap 2.6.0", "itertools 0.11.0", + "jsonschema 0.19.1", "once_cell", "roaring", + "sd-jwt-payload 0.2.1", + "sd-jwt-payload 0.3.0", "serde", "serde-aux", "serde_json", "serde_repr", - "strum", + "strum 0.25.0", "thiserror", "url", ] @@ -4131,38 +4176,36 @@ dependencies = [ [[package]] name = "identity_did" version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a054fe2898b1d4e29260c128ecd3bb65fbb00846000b17713f2d28cf6b2da7c0" +source = "git+https://github.com/impierce/identity.rs?branch=fix/compile-fixes#d36175ce30d3be6c40da0c39f7d6c95ae424894e" dependencies = [ "did_url_parser", "form_urlencoded", "identity_core", + "identity_jose", "serde", - "strum", + "strum 0.25.0", "thiserror", ] [[package]] name = "identity_document" version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76e59fe2e4b2c4843ef9e9cc37b70e864eff6021d42d982f596ce9949587dd7c" +source = "git+https://github.com/impierce/identity.rs?branch=fix/compile-fixes#d36175ce30d3be6c40da0c39f7d6c95ae424894e" dependencies = [ "did_url_parser", "identity_core", "identity_did", "identity_verification", - "indexmap 2.2.6", + "indexmap 2.6.0", "serde", - "strum", + "strum 0.25.0", "thiserror", ] [[package]] name = "identity_eddsa_verifier" version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c099a4cb2f5f2c99d3edba7fb8b94c39acbbbce5f882a97c3455aac688b64643" +source = "git+https://github.com/impierce/identity.rs?branch=fix/compile-fixes#d36175ce30d3be6c40da0c39f7d6c95ae424894e" dependencies = [ "identity_jose", "iota-crypto", @@ -4171,8 +4214,7 @@ dependencies = [ [[package]] name = "identity_iota" version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6820c32c06bccb53b804aebbc15879f79395632c99e1add4b7e2f1b662611960" +source = "git+https://github.com/impierce/identity.rs?branch=fix/compile-fixes#d36175ce30d3be6c40da0c39f7d6c95ae424894e" dependencies = [ "identity_core", "identity_credential", @@ -4187,8 +4229,7 @@ dependencies = [ [[package]] name = "identity_iota_core" version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bd8d4dec00632808f79bf7d85256f808abae7c8552ef6e102ea7350112900bf" +source = "git+https://github.com/impierce/identity.rs?branch=fix/compile-fixes#d36175ce30d3be6c40da0c39f7d6c95ae424894e" dependencies = [ "async-trait", "futures", @@ -4204,17 +4245,16 @@ dependencies = [ "prefix-hex", "ref-cast", "serde", - "strum", + "strum 0.25.0", "thiserror", ] [[package]] name = "identity_jose" version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a2bf6a6eeeb41729d65bdca82c9cdb3cc52847b8cc277892a60d68d008ba5b3" +source = "git+https://github.com/impierce/identity.rs?branch=fix/compile-fixes#d36175ce30d3be6c40da0c39f7d6c95ae424894e" dependencies = [ - "bls12_381_plus 0.8.15", + "bls12_381_plus 0.8.17", "identity_core", "iota-crypto", "json-proof-token", @@ -4228,26 +4268,25 @@ dependencies = [ [[package]] name = "identity_resolver" version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616265a5de38f03867d3d5ce269e723a8cf6d6d5ee90d5b19a5b9879ed14e821" +source = "git+https://github.com/impierce/identity.rs?branch=fix/compile-fixes#d36175ce30d3be6c40da0c39f7d6c95ae424894e" dependencies = [ + "anyhow", "async-trait", "futures", "identity_core", - "identity_credential", "identity_did", "identity_document", "identity_iota_core", + "iota-sdk", "serde", - "strum", + "strum 0.25.0", "thiserror", ] [[package]] name = "identity_storage" version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee676abc86697f2ca52c86d3d34b1ae8558e62706623b470937be4fb93c169f" +source = "git+https://github.com/impierce/identity.rs?branch=fix/compile-fixes#d36175ce30d3be6c40da0c39f7d6c95ae424894e" dependencies = [ "anyhow", "async-trait", @@ -4267,8 +4306,7 @@ dependencies = [ [[package]] name = "identity_stronghold" version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84cee4d8723ebf1605ca3cd848a21494a7e2e5e44c1610a43bb8ebf3114b5916" +source = "git+https://github.com/impierce/identity.rs?branch=fix/compile-fixes#d36175ce30d3be6c40da0c39f7d6c95ae424894e" dependencies = [ "async-trait", "identity_storage", @@ -4284,7 +4322,7 @@ dependencies = [ [[package]] name = "identity_stronghold_ext" version = "0.1.0" -source = "git+https://git@github.com/impierce/did-manager.git?tag=v1.0.0-beta.3#3ad5e3dba7bc76df8d6cb4a4fd2df2238d88710b" +source = "git+https://git@github.com/impierce/did-manager.git?rev=c1cfda0#c1cfda09ae1e5797ba013ead8aa6ace616b75a6d" dependencies = [ "async-trait", "elliptic-curve 0.13.8", @@ -4303,15 +4341,14 @@ dependencies = [ [[package]] name = "identity_verification" version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "949c048132a35d0337540958bdae866aedebbfaadb588d4604475355fe9646db" +source = "git+https://github.com/impierce/identity.rs?branch=fix/compile-fixes#d36175ce30d3be6c40da0c39f7d6c95ae424894e" dependencies = [ "identity_core", "identity_did", "identity_jose", "serde", "serde_json", - "strum", + "strum 0.25.0", "thiserror", ] @@ -4367,12 +4404,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.6" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown 0.15.0", "serde", ] @@ -4432,9 +4469,9 @@ dependencies = [ [[package]] name = "iota-crypto" -version = "0.23.1" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5db0e2d85e258d6d0db66f4a6bf1e8bdf5b10c3353aa87d98b168778d13fdc1" +checksum = "98a38db844c910d78825e173c083f2ef416b69cb091bba8ac1055763c6db065b" dependencies = [ "aead", "aes", @@ -4444,7 +4481,7 @@ dependencies = [ "blake2", "chacha20poly1305", "cipher", - "curve25519-dalek 3.2.0", + "curve25519-dalek 4.1.3", "digest 0.10.7", "ed25519-zebra", "generic-array", @@ -4461,7 +4498,7 @@ dependencies = [ "sha2 0.10.8", "tiny-keccak", "unicode-normalization", - "x25519-dalek", + "x25519-dalek 2.0.1", "zeroize", ] @@ -4705,6 +4742,24 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" +[[package]] +name = "josekit" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54b85e2125819afc4fd2ae57416207e792c7e12797858e5db2a6c6f24a166829" +dependencies = [ + "anyhow", + "base64 0.22.1", + "flate2", + "once_cell", + "openssl", + "regex", + "serde", + "serde_json", + "thiserror", + "time", +] + [[package]] name = "js-sys" version = "0.3.69" @@ -4876,6 +4931,15 @@ dependencies = [ "thiserror", ] +[[package]] +name = "json-pointer" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fe841b94e719a482213cee19dd04927cf412f26d8dc84c5a446c081e49c2997" +dependencies = [ + "serde_json", +] + [[package]] name = "json-proof-token" version = "0.3.5" @@ -4884,7 +4948,7 @@ checksum = "179551c27c512c948af1edaf4bd7e1d1486d223f8ec4fd41cd760f7645fd4197" dependencies = [ "cargo-license", "data-encoding", - "indexmap 2.2.6", + "indexmap 2.6.0", "json-unflattening", "serde", "serde_json", @@ -4944,8 +5008,8 @@ dependencies = [ "base64 0.21.7", "bytecount", "clap 4.5.9", - "fancy-regex", - "fraction", + "fancy-regex 0.11.0", + "fraction 0.13.1", "getrandom 0.2.15", "iso8601", "itoa 1.0.11", @@ -4963,6 +5027,34 @@ dependencies = [ "uuid", ] +[[package]] +name = "jsonschema" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14a655181740aa66dfcb182daca1bc8109fda5c7c0399c4f30dcb155ab0d32a6" +dependencies = [ + "ahash 0.8.11", + "anyhow", + "base64 0.22.1", + "bytecount", + "fancy-regex 0.13.0", + "fraction 0.15.3", + "getrandom 0.2.15", + "iso8601", + "itoa 1.0.11", + "memchr", + "num-cmp", + "once_cell", + "parking_lot 0.12.3", + "percent-encoding", + "regex", + "serde", + "serde_json", + "time", + "url", + "uuid-simd", +] + [[package]] name = "jsonwebkey" version = "0.3.5" @@ -5942,7 +6034,7 @@ dependencies = [ [[package]] name = "oid4vc" version = "0.1.0" -source = "git+https://git@github.com/impierce/openid4vc.git?rev=d095db0#d095db0b943fa208baae298d2e1172e34aa995bc" +source = "git+https://git@github.com/impierce/openid4vc.git?rev=bc4d6d2#bc4d6d2f9ea8cae7ab61da2099af3b95e9616585" dependencies = [ "dif-presentation-exchange", "oid4vc-core", @@ -5955,7 +6047,7 @@ dependencies = [ [[package]] name = "oid4vc-core" version = "0.1.0" -source = "git+https://git@github.com/impierce/openid4vc.git?rev=d095db0#d095db0b943fa208baae298d2e1172e34aa995bc" +source = "git+https://git@github.com/impierce/openid4vc.git?rev=bc4d6d2#bc4d6d2f9ea8cae7ab61da2099af3b95e9616585" dependencies = [ "anyhow", "async-trait", @@ -5979,7 +6071,7 @@ dependencies = [ [[package]] name = "oid4vc-manager" version = "0.1.0" -source = "git+https://git@github.com/impierce/openid4vc.git?rev=d095db0#d095db0b943fa208baae298d2e1172e34aa995bc" +source = "git+https://git@github.com/impierce/openid4vc.git?rev=bc4d6d2#bc4d6d2f9ea8cae7ab61da2099af3b95e9616585" dependencies = [ "anyhow", "async-trait", @@ -6011,7 +6103,7 @@ dependencies = [ [[package]] name = "oid4vci" version = "0.1.0" -source = "git+https://git@github.com/impierce/openid4vc.git?rev=d095db0#d095db0b943fa208baae298d2e1172e34aa995bc" +source = "git+https://git@github.com/impierce/openid4vc.git?rev=bc4d6d2#bc4d6d2f9ea8cae7ab61da2099af3b95e9616585" dependencies = [ "anyhow", "derivative", @@ -6029,12 +6121,13 @@ dependencies = [ "serde_urlencoded", "serde_with 3.9.0", "tokio", + "tracing", ] [[package]] name = "oid4vp" version = "0.1.0" -source = "git+https://git@github.com/impierce/openid4vc.git?rev=d095db0#d095db0b943fa208baae298d2e1172e34aa995bc" +source = "git+https://git@github.com/impierce/openid4vc.git?rev=bc4d6d2#bc4d6d2f9ea8cae7ab61da2099af3b95e9616585" dependencies = [ "anyhow", "chrono", @@ -6081,12 +6174,50 @@ dependencies = [ "pathdiff", ] +[[package]] +name = "openssl" +version = "0.10.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "foreign-types 0.3.2", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.71", +] + [[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +[[package]] +name = "openssl-sys" +version = "0.9.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "option-ext" version = "0.2.0" @@ -6109,6 +6240,12 @@ version = "6.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" +[[package]] +name = "outref" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4030760ffd992bef45b0ae3f10ce1aba99e33464c90d14dd7c039884963ddc7a" + [[package]] name = "overload" version = "0.1.1" @@ -6599,7 +6736,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016" dependencies = [ "base64 0.22.1", - "indexmap 2.2.6", + "indexmap 2.6.0", "quick-xml", "serde", "time", @@ -6803,7 +6940,7 @@ dependencies = [ [[package]] name = "producer" version = "0.1.0" -source = "git+https://git@github.com/impierce/did-manager.git?tag=v1.0.0-beta.3#3ad5e3dba7bc76df8d6cb4a4fd2df2238d88710b" +source = "git+https://git@github.com/impierce/did-manager.git?rev=c1cfda0#c1cfda09ae1e5797ba013ead8aa6ace616b75a6d" dependencies = [ "did_iota", "did_jwk", @@ -7690,6 +7827,45 @@ dependencies = [ "untrusted", ] +[[package]] +name = "sd-jwt-payload" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f96560f8ef0ef51808661b53f49e640cf854d64339d204c33fec3528d9451da7" +dependencies = [ + "iota-crypto", + "itertools 0.12.1", + "json-pointer", + "multibase 0.9.1", + "rand 0.8.5", + "serde", + "serde_json", + "serde_with 3.9.0", + "strum 0.26.3", + "thiserror", +] + +[[package]] +name = "sd-jwt-payload" +version = "0.3.0" +source = "git+https://github.com/iotaledger/sd-jwt-payload.git?rev=0300fc5#0300fc5bb2bd6c595127f58a023e0cbb33a7d423" +dependencies = [ + "anyhow", + "async-trait", + "indexmap 2.6.0", + "iota-crypto", + "itertools 0.12.1", + "josekit", + "json-pointer", + "multibase 0.9.1", + "rand 0.8.5", + "serde", + "serde_json", + "serde_with 3.9.0", + "strum 0.26.3", + "thiserror", +] + [[package]] name = "seahash" version = "4.1.0" @@ -7846,7 +8022,7 @@ version = "1.0.120" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.6.0", "itoa 1.0.11", "ryu", "serde", @@ -7931,7 +8107,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.2.6", + "indexmap 2.6.0", "serde", "serde_derive", "serde_json", @@ -8100,7 +8276,7 @@ dependencies = [ [[package]] name = "shared" version = "0.1.0" -source = "git+https://git@github.com/impierce/did-manager.git?tag=v1.0.0-beta.3#3ad5e3dba7bc76df8d6cb4a4fd2df2238d88710b" +source = "git+https://git@github.com/impierce/did-manager.git?rev=c1cfda0#c1cfda09ae1e5797ba013ead8aa6ace616b75a6d" dependencies = [ "identity_iota", "identity_storage", @@ -8192,7 +8368,7 @@ dependencies = [ [[package]] name = "siopv2" version = "0.1.0" -source = "git+https://git@github.com/impierce/openid4vc.git?rev=d095db0#d095db0b943fa208baae298d2e1172e34aa995bc" +source = "git+https://git@github.com/impierce/openid4vc.git?rev=bc4d6d2#bc4d6d2f9ea8cae7ab61da2099af3b95e9616585" dependencies = [ "anyhow", "async-trait", @@ -8276,7 +8452,7 @@ dependencies = [ "bytemuck", "cfg_aliases 0.2.1", "core-graphics", - "foreign-types", + "foreign-types 0.5.0", "js-sys", "log", "objc2", @@ -8750,7 +8926,16 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" dependencies = [ - "strum_macros", + "strum_macros 0.25.3", +] + +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros 0.26.4", ] [[package]] @@ -8766,6 +8951,19 @@ dependencies = [ "syn 2.0.71", ] +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.71", +] + [[package]] name = "subtle" version = "2.6.1" @@ -9502,7 +9700,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.6.0", "serde", "serde_spanned", "toml_datetime", @@ -9515,7 +9713,7 @@ version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.6.0", "serde", "serde_spanned", "toml_datetime", @@ -9985,6 +10183,17 @@ dependencies = [ "serde", ] +[[package]] +name = "uuid-simd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b082222b4f6619906941c17eb2297fff4c2fb96cb60164170522942a200bd8" +dependencies = [ + "outref", + "uuid", + "vsimd", +] + [[package]] name = "valuable" version = "0.1.0" @@ -10015,6 +10224,12 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "vsimd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" + [[package]] name = "vswhom" version = "0.1.0" @@ -10812,6 +11027,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "x25519-dalek" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" +dependencies = [ + "curve25519-dalek 4.1.3", + "rand_core 0.6.4", + "zeroize", +] + [[package]] name = "xattr" version = "1.3.1" @@ -10953,7 +11179,7 @@ dependencies = [ "crossbeam-utils", "displaydoc", "flate2", - "indexmap 2.2.6", + "indexmap 2.6.0", "memchr", "thiserror", "zopfli", @@ -10965,7 +11191,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c734c171ed591a19dc1127351eb1b4d91864d3e53b2b6e9992bffcb7febf364a" dependencies = [ - "bls12_381_plus 0.8.15", + "bls12_381_plus 0.8.17", "cargo-license", "digest 0.10.7", "dotenv", diff --git a/Cargo.toml b/Cargo.toml index b8338e929..53b816a35 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,10 +26,12 @@ tauri-utils = { version = "=2.0.0-beta.19", features = [ "resources" ] } tauri-winres = "=0.1" agent_shared = { git = "https://git@github.com/impierce/ssi-agent.git", rev = "1823810" } -did_manager = { git = "https://git@github.com/impierce/did-manager.git", tag = "v1.0.0-beta.3" } +# did_manager = { git = "https://git@github.com/impierce/did-manager.git", tag = "v1.0.0-beta.3" } +did_manager = { git = "https://git@github.com/impierce/did-manager.git", rev = "c1cfda0" } jsonwebtoken = "9.3" log = "^0.4" -oid4vc = { git = "https://git@github.com/impierce/openid4vc.git", rev = "d095db0" } +oid4vc = { git = "https://git@github.com/impierce/openid4vc.git", rev = "bc4d6d2" } +# oid4vc = { path = "../openid4vc" } rand = "0.8" serde_json = "1.0" serial_test = "2.0" diff --git a/identity-wallet/Cargo.toml b/identity-wallet/Cargo.toml index ff87d90b7..cda10d15b 100644 --- a/identity-wallet/Cargo.toml +++ b/identity-wallet/Cargo.toml @@ -17,16 +17,17 @@ downcast-rs = "1.2" dyn-clone = "1.0" futures = "0.3" icu = "1.4.0" -identity_credential = { version = "1.3", default-features = false, features = [ +identity_credential = { git = "https://github.com/impierce/identity.rs", branch = "fix/compile-fixes", default-features = false, features = [ "credential", "domain-linkage", "presentation", "validator", + "sd-jwt-vc" ] } -identity_core = { version = "1.3" } -identity_eddsa_verifier = { version = "1.3" } -identity_iota = { version = "1.3" } -identity_jose = { version = "1.3" } +identity_core = { git = "https://github.com/impierce/identity.rs", branch = "fix/compile-fixes" } +identity_eddsa_verifier = { git = "https://github.com/impierce/identity.rs", branch = "fix/compile-fixes" } +identity_iota = { git = "https://github.com/impierce/identity.rs", branch = "fix/compile-fixes" } +identity_jose = { git = "https://github.com/impierce/identity.rs", branch = "fix/compile-fixes" } iota_stronghold = { version = "2.1" } itertools = "0.10.5" jsonwebtoken.workspace = true diff --git a/identity-wallet/src/state/credentials/mod.rs b/identity-wallet/src/state/credentials/mod.rs index 0808a641b..fd581befb 100644 --- a/identity-wallet/src/state/credentials/mod.rs +++ b/identity-wallet/src/state/credentials/mod.rs @@ -1,10 +1,15 @@ pub mod actions; pub mod reducers; +use std::str::FromStr; + use super::{core_utils::helpers::get_unverified_jwt_claims, FeatTrait}; use crate::{error::AppError, state::core_utils::DateUtils}; use derivative::Derivative; +use identity_credential::{sd_jwt_v2::Sha256Hasher, sd_jwt_vc::SdJwtVc}; +use log::info; +use oid4vc::oid4vci::credential_format_profiles::CredentialFormats; use serde::{Deserialize, Serialize}; use serde_json::json; use ts_rs::TS; @@ -16,6 +21,8 @@ use uuid::Uuid; #[ts(export, export_to = "bindings/credentials/DisplayCredential.ts")] pub struct DisplayCredential { pub id: String, + #[ts(type = "string")] + pub format: CredentialFormats, pub issuer_name: String, #[ts(type = "any")] pub data: serde_json::Value, @@ -54,48 +61,89 @@ impl TryFrom for VerifiableCredentialRecord { fn try_from(verifiable_credential: serde_json::Value) -> Result { let display_credential = { - let credential_display = get_unverified_jwt_claims(&verifiable_credential)?["vc"].clone(); - - // Derive the hash from the credential display. - let hash = { - let type_key = "type"; - let type_value = credential_display[type_key].clone(); + // FIX THIS + if let Ok(sd_jwt_vc) = SdJwtVc::from_str(verifiable_credential.as_str().unwrap()) { + info!("sd_jwt_vc: {:#?}", sd_jwt_vc); - let credential_subject_key = "credentialSubject"; - let mut credential_subject_value = credential_display[credential_subject_key].clone(); + let issuance_date = sd_jwt_vc.claims().iat.map(|iat| iat.to_rfc3339()).unwrap_or_default(); + let credential_subject = sd_jwt_vc.clone().into_disclosed_object(&Sha256Hasher::new()).unwrap(); - // TODO(ngdil): Remove this hard-coded logic. - // Remove the `Passport Number` and `Staff Number` from the credential subject if they exists. - credential_subject_value["Passport Number"].take(); - credential_subject_value["Staff Number"].take(); - credential_subject_value["achievement"]["id"].take(); - - sha256::digest( + let hash = sha256::digest( json!( { - "type": type_value, - "credentialSubject": credential_subject_value, + "type": ["VerifiableCredential"], + "credentialSubject": credential_subject } ) .to_string(), - ) - }; - - let issuance_date = credential_display["issuanceDate"] - .as_str() - .map(ToString::to_string) - .unwrap_or_default(); - - DisplayCredential { - id: Uuid::from_slice(&hash.as_bytes()[..16]).unwrap().to_string(), - data: credential_display, - metadata: CredentialMetadata { - is_favorite: false, - date_added: DateUtils::new_date_string(), - date_issued: issuance_date.to_string(), - }, - // The other fields will be filled in at a later stage. - ..Default::default() + ); + + DisplayCredential { + id: Uuid::from_slice(&hash.as_bytes()[..16]).unwrap().to_string(), + format: CredentialFormats::VcSdJwt(()), + data: json!({ + "type": ["VerifiableCredential"], + "issuer": sd_jwt_vc.claims().iss, + "credentialSubject": credential_subject + + }), + metadata: CredentialMetadata { + is_favorite: false, + date_added: DateUtils::new_date_string(), + date_issued: issuance_date.to_string(), + }, + // The other fields will be filled in at a later stage. + ..Default::default() + } + } else { + let credential_display = get_unverified_jwt_claims(&verifiable_credential)?["vc"].clone(); + + info!( + "Credential Display: {:#?}", + serde_json::to_string_pretty(&credential_display).unwrap() + ); + + // Derive the hash from the credential display. + let hash = { + let type_value = credential_display["type"].clone(); + + let credential_subject_key = "credentialSubject"; + let mut credential_subject_value = credential_display[credential_subject_key].clone(); + + // TODO(ngdil): Remove this hard-coded logic. + // Remove the `Passport Number` and `Staff Number` from the credential subject if they exists. + credential_subject_value["Passport Number"].take(); + credential_subject_value["Staff Number"].take(); + credential_subject_value["achievement"]["id"].take(); + + sha256::digest( + json!( + { + "type": type_value, + "credentialSubject": credential_subject_value, + } + ) + .to_string(), + ) + }; + + let issuance_date = credential_display["issuanceDate"] + .as_str() + .map(ToString::to_string) + .unwrap_or_default(); + + DisplayCredential { + id: Uuid::from_slice(&hash.as_bytes()[..16]).unwrap().to_string(), + format: CredentialFormats::JwtVcJson(()), + data: credential_display, + metadata: CredentialMetadata { + is_favorite: false, + date_added: DateUtils::new_date_string(), + date_issued: issuance_date.to_string(), + }, + // The other fields will be filled in at a later stage. + ..Default::default() + } } }; diff --git a/identity-wallet/src/state/credentials/reducers/handle_oid4vp_authorization_request.rs b/identity-wallet/src/state/credentials/reducers/handle_oid4vp_authorization_request.rs index cee931fae..257794f4c 100644 --- a/identity-wallet/src/state/credentials/reducers/handle_oid4vp_authorization_request.rs +++ b/identity-wallet/src/state/credentials/reducers/handle_oid4vp_authorization_request.rs @@ -12,16 +12,19 @@ use crate::{ user_prompt::CurrentUserPrompt, AppState, }, + subject::SubjectWrapper, }; -use identity_credential::{credential::Jwt, presentation::Presentation}; -use identity_iota::did::CoreDID; +use identity_credential::{ + credential::Jwt, + presentation::Presentation, + sd_jwt_v2::{KeyBindingJwt, Sha256Hasher}, + sd_jwt_vc::{SdJwtVc, SdJwtVcPresentationBuilder}, +}; +use identity_iota::{core::Timestamp, did::CoreDID}; use jsonwebtoken::Algorithm; use log::info; -use oid4vc::oid4vc_manager::managers::presentation::create_presentation_submission; -use oid4vc::oid4vp::authorization_request::ClientMetadataParameters; -use oid4vc::oid4vp::oid4vp; -use oid4vc::oid4vp::oid4vp::OID4VP; +use oid4vc::oid4vp::{authorization_request::ClientMetadataParameters, oid4vp::PresentationInputType}; use oid4vc::{ oid4vc_core::{ authorization_request::{AuthorizationRequest, Object}, @@ -29,6 +32,12 @@ use oid4vc::{ }, oid4vp::{ClaimFormatDesignation, ClaimFormatProperty}, }; +use oid4vc::{ + oid4vc_manager::managers::presentation::create_presentation_submission, + oid4vci::credential_format_profiles::CredentialFormats, +}; +use oid4vc::{oid4vc_manager::managers::presentation::create_sd_jwt_presentation_submission, oid4vp::oid4vp}; +use oid4vc::{oid4vc_manager::managers::presentation::merge_submissions, oid4vp::oid4vp::OID4VP}; // Sends the authorization response including the verifiable credentials. pub async fn handle_oid4vp_authorization_request(state: AppState, action: Action) -> Result { @@ -46,6 +55,12 @@ pub async fn handle_oid4vp_authorization_request(state: AppState, action: Action .as_ref() .ok_or(MissingManagerError("identity"))? .provider_manager; + let subject = state_guard + .identity_manager + .as_ref() + .ok_or(MissingManagerError("identity"))? + .subject + .clone(); let oid4vp_authorization_request = match serde_json::from_value(serde_json::json!(state.core_utils.active_connection_request)).unwrap() { @@ -55,12 +70,14 @@ pub async fn handle_oid4vp_authorization_request(state: AppState, action: Action let mut history_credentials = Vec::new(); - let verifiable_credentials: Vec = stronghold_manager + let verifiable_credentials: Vec<(CredentialFormats, serde_json::Value)> = stronghold_manager .values() .map_err(StrongholdValuesError)? .unwrap() .iter() .filter_map(|verifiable_credential_record| { + info!("verifiable_credential_record: {:#?}", verifiable_credential_record); + let share_credential = credential_uuids .contains(&verifiable_credential_record.display_credential.id.parse().unwrap()) .then_some(verifiable_credential_record.verifiable_credential.clone()); @@ -69,53 +86,169 @@ pub async fn handle_oid4vp_authorization_request(state: AppState, action: Action history_credentials.push(HistoryCredential::from_credential(verifiable_credential_record)); } - share_credential + share_credential.map(|share_credential| { + ( + verifiable_credential_record.display_credential.format.clone(), + share_credential, + ) + }) }) .collect(); - let presentation_submission = create_presentation_submission( - &oid4vp_authorization_request.body.extension.presentation_definition, - &verifiable_credentials - .iter() - .map(get_unverified_jwt_claims) - .collect::, _>>()?, - ) - .map_err(PresentationSubmissionError)?; + let subject_syntax_type = state + .profile_settings + .preferred_did_methods + .first() + .unwrap() + .to_string(); - info!("get the subject did"); + let subject_wrapper = SubjectWrapper { + subject, + subject_syntax_type, + }; - let identity_manager = state_guard - .identity_manager - .as_ref() - .ok_or(MissingManagerError("identity"))?; + let sd_jwt_vcs: Vec = verifiable_credentials + .iter() + .filter_map(|(format, vc)| { + if format == &CredentialFormats::VcSdJwt(()) { + Some(vc.clone()) + } else { + None + } + }) + .collect(); - let OID4VPClientMetadata { - client_name, - logo_uri, - connection_url, - client_id, - algorithm, - } = get_oid4vp_client_name_and_logo_uri(&oid4vp_authorization_request); + let now = Timestamp::now_utc(); + + let mut verifiable_presentation_input = vec![]; + let mut presentation_submissions = vec![]; + + info!( + "Authorization Request: {}", + serde_json::to_string_pretty(&oid4vp_authorization_request).unwrap() + ); + + let nonce = oid4vp_authorization_request.body.extension.nonce.clone(); + let aud = oid4vp_authorization_request.body.client_id.clone(); + + let OID4VPClientMetadata { algorithm, .. } = get_oid4vp_client_name_and_logo_uri(&oid4vp_authorization_request); + + for sd_jwt_vc in sd_jwt_vcs { + let sd_jwt_vc = sd_jwt_vc + .as_str() + .and_then(|sd_jwt_vc| SdJwtVc::parse(sd_jwt_vc).ok()) + .ok_or(AppError::Error("Failed to parse SD-JWT VC".to_string()))?; + + let alg = sd_jwt_vc + .header() + .get("alg") + .and_then(|alg| alg.as_str()) + .map(ToString::to_string) + .unwrap_or(serde_json::json!(algorithm).as_str().unwrap().to_string()); + let kb_jwt = KeyBindingJwt::builder() + .iat(now.to_unix()) + .aud(aud.clone()) + .nonce(nonce.clone()) + .finish(&sd_jwt_vc, &Sha256Hasher::new(), &alg, &subject_wrapper) + .await + .map_err(|e| AppError::Error(format!("Failed to create KeyBindingJwt for SD-JWT VC: {:?}", e)))?; + + let (sd_jwt_vc, _) = SdJwtVcPresentationBuilder::new(sd_jwt_vc, &Sha256Hasher::new()) + .map_err(|e| { + AppError::Error(format!( + "Failed to create SD-JWT VC Presentation Builder for SD-JWT VC: {:?}", + e + )) + })? + .attach_key_binding_jwt(kb_jwt) + .finish() + .map_err(|e| AppError::Error(format!("Failed to attach KeyBindingJwt to SD-JWT VC: {:?}", e)))?; + + let presentation_submission = create_sd_jwt_presentation_submission( + &oid4vp_authorization_request.body.extension.presentation_definition, + &[serde_json::json!(sd_jwt_vc + .clone() + .into_disclosed_object(&Sha256Hasher::new()) + // FIX THIS + .unwrap())], + ) + .map_err(|e| { + AppError::Error(format!( + "Failed to create Presentation Submission for SD-JWT VC: {:?}", + e + )) + })?; + + verifiable_presentation_input.push(PresentationInputType::Signed(sd_jwt_vc.to_string())); + presentation_submissions.push(presentation_submission); + } - let subject_did = identity_manager - .subject - .identifier(state.profile_settings.preferred_did_methods.first().unwrap(), algorithm) - .await - .expect("No default DID method"); - - let mut presentation_builder = - Presentation::builder(subject_did.parse().map_err(|_| DidParseError)?, Default::default()); - for verifiable_credential in verifiable_credentials { - presentation_builder = presentation_builder.credential(Jwt::from( - verifiable_credential - .as_str() - .ok_or(InvalidCredentialFormatError)? - .to_string(), + let verifiable_credentials: Vec = verifiable_credentials + .iter() + .filter_map(|(format, vc)| { + if format == &CredentialFormats::JwtVcJson(()) { + Some(vc.clone()) + } else { + None + } + }) + .collect(); + + info!("verifiable_credentials: {:#?}", verifiable_credentials); + + if !verifiable_credentials.is_empty() { + let presentation_submission = create_presentation_submission( + &oid4vp_authorization_request.body.extension.presentation_definition, + &verifiable_credentials + .iter() + .map(get_unverified_jwt_claims) + .collect::, _>>()?, + ) + .map_err(PresentationSubmissionError)?; + + presentation_submissions.push(presentation_submission); + + info!("get the subject did"); + + let identity_manager = state_guard + .identity_manager + .as_ref() + .ok_or(MissingManagerError("identity"))?; + + let OID4VPClientMetadata { algorithm, .. } = + get_oid4vp_client_name_and_logo_uri(&oid4vp_authorization_request); + + let subject_did = identity_manager + .subject + .identifier(state.profile_settings.preferred_did_methods.first().unwrap(), algorithm) + .await + .expect("No default DID method"); + + let mut presentation_builder = + Presentation::builder(subject_did.parse().map_err(|_| DidParseError)?, Default::default()); + for verifiable_credential in verifiable_credentials { + presentation_builder = presentation_builder.credential(Jwt::from( + verifiable_credential + .as_str() + .ok_or(InvalidCredentialFormatError)? + .to_string(), + )); + } + + verifiable_presentation_input.push(PresentationInputType::Unsigned( + presentation_builder.build().map_err(PresentationBuilderError)?, )); } - let verifiable_presentation: Presentation = - presentation_builder.build().map_err(PresentationBuilderError)?; + let presentation_submission = if presentation_submissions.len() > 1 { + merge_submissions(presentation_submissions) + } else { + presentation_submissions.pop().ok_or(AppError::Error( + "Failed to create a Presentation Submission".to_string(), + ))? + }; + + info!("Verifiable Presentation Input: {:#?}", verifiable_presentation_input); info!("get the provider_manager"); @@ -124,7 +257,7 @@ pub async fn handle_oid4vp_authorization_request(state: AppState, action: Action .generate_response( &oid4vp_authorization_request, oid4vp::AuthorizationResponseInput { - verifiable_presentation, + verifiable_presentation_input, presentation_submission, }, ) @@ -138,10 +271,18 @@ pub async fn handle_oid4vp_authorization_request(state: AppState, action: Action } info!("response successfully sent"); + let OID4VPClientMetadata { + client_name, + logo_uri, + connection_url, + client_id, + algorithm: _algorithm, + } = get_oid4vp_client_name_and_logo_uri(&oid4vp_authorization_request); + let did = CoreDID::parse(client_id).ok(); - let previously_connected = state.connections.contains(connection_url.as_str(), &client_name); let mut connections = state.connections; + let previously_connected = connections.contains(connection_url.as_str(), &client_name); let connection = connections.update_or_insert(&connection_url, &client_name, did); let file_name = match logo_uri { @@ -225,7 +366,7 @@ pub fn get_oid4vp_client_name_and_logo_uri( .and_then(|claim_format_property| match claim_format_property { ClaimFormatProperty::Alg(alg) => alg.first().cloned(), // TODO: implement `ProofType`. - ClaimFormatProperty::ProofType(_) => None, + ClaimFormatProperty::ProofType(_) | _ => None, }) .unwrap_or(Algorithm::EdDSA); diff --git a/identity-wallet/src/state/qr_code/reducers/read_authorization_request.rs b/identity-wallet/src/state/qr_code/reducers/read_authorization_request.rs index ecaa4fac1..8eec8d86f 100644 --- a/identity-wallet/src/state/qr_code/reducers/read_authorization_request.rs +++ b/identity-wallet/src/state/qr_code/reducers/read_authorization_request.rs @@ -4,7 +4,7 @@ use crate::{ state::{ actions::{listen, Action}, connections::reducers::handle_siopv2_authorization_request::get_siopv2_client_name_and_logo_uri, - core_utils::{ConnectionRequest, CoreUtils}, + core_utils::{helpers::get_unverified_jwt_claims, ConnectionRequest, CoreUtils}, credentials::reducers::handle_oid4vp_authorization_request::{ get_oid4vp_client_name_and_logo_uri, OID4VPClientMetadata, }, @@ -18,10 +18,14 @@ use crate::{ }, }; +use identity_credential::{sd_jwt_v2::Sha256Hasher, sd_jwt_vc::SdJwtVc}; use log::{debug, info}; -use oid4vc::oid4vc_core::authorization_request::{AuthorizationRequest, Object}; use oid4vc::oid4vp::{evaluate_input, oid4vp::OID4VP}; use oid4vc::siopv2::siopv2::SIOPv2; +use oid4vc::{ + oid4vc_core::authorization_request::{AuthorizationRequest, Object}, + oid4vci::credential_format_profiles::CredentialFormats, +}; // Reads the request url from the payload and validates it. pub async fn read_authorization_request(state: AppState, action: Action) -> Result { @@ -85,7 +89,8 @@ pub async fn read_authorization_request(state: AppState, action: Action) -> Resu let did = siopv2_authorization_request.body.client_id.as_str(); - let domain_validation = Box::new(validate_domain_linkage(url, did).await); + let domain_validation: Box = + Box::new(validate_domain_linkage(url, did).await); let temp: Vec = state .trust_lists @@ -150,13 +155,30 @@ pub async fn read_authorization_request(state: AppState, action: Action) -> Resu verifiable_credentials .iter() .find_map(|verifiable_credential_record| { - evaluate_input( - input_descriptor, - &serde_json::json!({ - "vc": verifiable_credential_record.display_credential.data - }), - ) - .then_some(verifiable_credential_record.display_credential.id.clone()) + if verifiable_credential_record.display_credential.format == CredentialFormats::VcSdJwt(()) + { + let unconceiled_credential = serde_json::json!(verifiable_credential_record + .verifiable_credential + .as_str() + // FIX THIS + .unwrap() + .parse::() + // FIX THIS + .unwrap() + .into_disclosed_object(&Sha256Hasher::new()) + // FIX THIS + .unwrap()); + + evaluate_input(input_descriptor, &unconceiled_credential) + .then_some(verifiable_credential_record.display_credential.id.clone()) + } else { + evaluate_input( + input_descriptor, + &get_unverified_jwt_claims(&verifiable_credential_record.verifiable_credential) + .unwrap(), + ) + .then_some(verifiable_credential_record.display_credential.id.clone()) + } }) .ok_or(NoMatchingCredentialError) }) diff --git a/identity-wallet/src/state/search/reducers/search_query.rs b/identity-wallet/src/state/search/reducers/search_query.rs index a10c9c1a3..7d89331ab 100644 --- a/identity-wallet/src/state/search/reducers/search_query.rs +++ b/identity-wallet/src/state/search/reducers/search_query.rs @@ -58,6 +58,8 @@ fn contains_search_term(string: Option<&str>, search_term: &str) -> bool { #[cfg(test)] mod tests { + use oid4vc::oid4vci::credential_format_profiles::CredentialFormats; + use super::*; use crate::state::credentials::CredentialMetadata; use crate::state::credentials::DisplayCredential; @@ -108,6 +110,7 @@ mod tests { credentials: vec![ DisplayCredential { id: "1".to_string(), + format: CredentialFormats::JwtVcJson(()), issuer_name: "Example Organization".to_string(), data: serde_json::json!({"last_name": "Ferris"}), metadata: CredentialMetadata { @@ -120,6 +123,7 @@ mod tests { }, DisplayCredential { id: "2".to_string(), + format: CredentialFormats::JwtVcJson(()), issuer_name: "Example Organization".to_string(), data: serde_json::json!({"last_name": "John"}), metadata: CredentialMetadata { @@ -132,6 +136,7 @@ mod tests { }, DisplayCredential { id: "3".to_string(), + format: CredentialFormats::JwtVcJson(()), issuer_name: "John Organization".to_string(), data: serde_json::json!({"last_name": "Ferris"}), metadata: CredentialMetadata { diff --git a/identity-wallet/src/subject.rs b/identity-wallet/src/subject.rs index fcb59c59c..efb68b28e 100644 --- a/identity-wallet/src/subject.rs +++ b/identity-wallet/src/subject.rs @@ -1,15 +1,17 @@ -use crate::stronghold::StrongholdManager; +use crate::{error::AppError, stronghold::StrongholdManager}; use async_trait::async_trait; use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine as _}; use did_manager::{DidMethod, Resolver, SecretManager}; +use identity_credential::sd_jwt_v2::JwsSigner; use identity_iota::{ did::DID, document::DIDUrlQuery, verification::{jwk::JwkParams, jws::JwsAlgorithm}, }; use jsonwebtoken::Algorithm; -use oid4vc::oid4vc_core::{authentication::sign::ExternalSign, Sign, Verify}; +use log::info; +use oid4vc::oid4vc_core::{self, authentication::sign::ExternalSign, JsonObject, Sign, Verify}; use std::sync::Arc; use tokio::sync::Mutex; @@ -131,6 +133,47 @@ pub async fn subject(stronghold_manager: Arc, password: Strin }) } +pub struct SubjectWrapper { + pub subject: Arc, + pub subject_syntax_type: String, +} + +#[async_trait] +impl JwsSigner for SubjectWrapper { + // FIX THIS + type Error = AppError; + + async fn sign(&self, header: &JsonObject, payload: &JsonObject) -> Result, Self::Error> { + let encoded_header = URL_SAFE_NO_PAD + .encode(serde_json::to_vec(header).map_err(|_| AppError::Error("Failed to encode header".to_string()))?); + let encoded_payload = URL_SAFE_NO_PAD + .encode(serde_json::to_vec(payload).map_err(|_| AppError::Error("Failed to encode payload".to_string()))?); + + info!("header {}", serde_json::to_string_pretty(&header).unwrap()); + info!("payload {}", serde_json::to_string_pretty(&payload).unwrap()); + + let message = format!("{}.{}", encoded_header, encoded_payload); + + let algorithm = header["alg"] + .as_str() + .and_then(|s| s.parse().ok()) + .ok_or(AppError::Error("Unsupported algorithm".to_string()))?; + + let proof_value = Sign::sign(&*self.subject, &message, &self.subject_syntax_type, algorithm) + .await + .map_err(|e| { + AppError::Error(format!( + "Failed to sign message with algorithm {:?}: {:?}", + algorithm, e + )) + })?; + + let signature = URL_SAFE_NO_PAD.encode(proof_value.as_slice()); + let message = [message, signature].join("."); + Ok(message.as_bytes().to_vec()) + } +} + trait IntoJwsAlgorithm { fn into_jws_algorithm(self) -> JwsAlgorithm; } diff --git a/unime/src/routes/credentials/[id]/DefaultRenderer.svelte b/unime/src/routes/credentials/[id]/DefaultRenderer.svelte index c4ddb8479..b98bf741f 100644 --- a/unime/src/routes/credentials/[id]/DefaultRenderer.svelte +++ b/unime/src/routes/credentials/[id]/DefaultRenderer.svelte @@ -8,7 +8,23 @@ // If you add a field, add a comment why that field should be hidden. // // `enrichment`: custom metadata field related for NGDIL demo. - const hideFields: string[] = ['enrichment', 'id', 'type']; + const hideFields: string[] = [ + 'enrichment', + 'id', + 'type', + + // TODO: to be removed once the backend properly propagates the to be displayed fields. + // SD-JWT claims + 'iss', + 'nbf', + 'exp', + 'status', + 'iat', + 'sub', + '_sd_alg', + 'cnf', + // 'vct', + ]; function isDataUrl(value: unknown): boolean { return typeof value === 'string' && value.startsWith('data:image/');