From 2ac1c694e01ff438f55e2056ec8432f1802645f6 Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Sun, 16 Nov 2025 03:09:37 +0100 Subject: [PATCH] Initial commit --- apps/desktop/desktop_native/Cargo.lock | 1435 ++++++++++++++++- apps/desktop/desktop_native/Cargo.toml | 1 + .../desktop_native/fido2_client/Cargo.toml | 22 + .../fido2_client/src/ctap_hid_fido2.rs | 104 ++ .../desktop_native/fido2_client/src/lib.rs | 69 + .../fido2_client/src/unimplemented.rs | 7 + apps/desktop/desktop_native/napi/Cargo.toml | 1 + apps/desktop/desktop_native/napi/index.d.ts | 31 + apps/desktop/desktop_native/napi/src/lib.rs | 107 ++ apps/desktop/src/app/app-routing.module.ts | 23 + .../src/app/services/services.module.ts | 16 + apps/desktop/src/auth/preload.ts | 5 + .../desktop-webauthn-login.serivce.ts | 86 + .../main-navigator-credentials.serivce.ts | 29 + apps/desktop/src/main.ts | 2 + .../electron-platform-utils.service.ts | 2 +- .../login-via-webauthn.component.ts | 1 + .../src/services/jslib-services.module.ts | 25 +- .../login/default-login-component.service.ts | 2 +- ...bauthn-login-assertion-response.request.ts | 15 +- .../webauthn-login/webauthn-login.service.ts | 6 +- 21 files changed, 1924 insertions(+), 65 deletions(-) create mode 100644 apps/desktop/desktop_native/fido2_client/Cargo.toml create mode 100644 apps/desktop/desktop_native/fido2_client/src/ctap_hid_fido2.rs create mode 100644 apps/desktop/desktop_native/fido2_client/src/lib.rs create mode 100644 apps/desktop/desktop_native/fido2_client/src/unimplemented.rs create mode 100644 apps/desktop/src/auth/services/desktop-webauthn-login.serivce.ts create mode 100644 apps/desktop/src/auth/services/main-navigator-credentials.serivce.ts diff --git a/apps/desktop/desktop_native/Cargo.lock b/apps/desktop/desktop_native/Cargo.lock index 4da82144305..8105b840244 100644 --- a/apps/desktop/desktop_native/Cargo.lock +++ b/apps/desktop/desktop_native/Cargo.lock @@ -193,6 +193,45 @@ dependencies = [ "nom", ] +[[package]] +name = "asn1-rs" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5493c3bedbacf7fd7382c6346bbd66687d12bbaad3a89a2d2c303ee6cf20b048" +dependencies = [ + "asn1-rs-derive", + "asn1-rs-impl", + "displaydoc", + "nom", + "num-traits", + "rusticata-macros", + "thiserror 1.0.69", + "time", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "asn1-rs-impl" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "async-broadcast" version = "0.7.2" @@ -309,6 +348,28 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "async-stream" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "async-task" version = "4.7.1" @@ -371,6 +432,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + [[package]] name = "base64" version = "0.22.1" @@ -383,6 +450,17 @@ version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3" +[[package]] +name = "base64urlsafedata" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "215ee31f8a88f588c349ce2d20108b2ed96089b96b9c2b03775dc35dd72938e8" +dependencies = [ + "base64 0.21.7", + "pastey", + "serde", +] + [[package]] name = "basic-toml" version = "0.1.10" @@ -412,6 +490,35 @@ dependencies = [ "serde", ] +[[package]] +name = "bindgen" +version = "0.65.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfdf7b466f9a4903edc73f95d6d2bcd5baf8ae620638762244d3f60143643cc5" +dependencies = [ + "bitflags 1.3.2", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", + "which", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "bitflags" version = "2.9.0" @@ -446,7 +553,7 @@ version = "0.0.0" dependencies = [ "aes-gcm", "anyhow", - "base64", + "base64 0.22.1", "chacha20poly1305", "chromium_importer", "clap", @@ -459,6 +566,12 @@ dependencies = [ "windows 0.61.1", ] +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + [[package]] name = "block-buffer" version = "0.10.4" @@ -500,6 +613,69 @@ dependencies = [ "cipher", ] +[[package]] +name = "bluez-async" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ce7d4413c940e8e3cb6afc122d3f4a07096aca259d286781128683fc9f39d9b" +dependencies = [ + "async-trait", + "bitflags 2.9.0", + "bluez-generated", + "dbus", + "dbus-tokio", + "futures", + "itertools", + "log", + "serde", + "serde-xml-rs", + "thiserror 1.0.69", + "tokio", + "uuid", +] + +[[package]] +name = "bluez-generated" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d1c659dbc82f0b8ca75606c91a371e763589b7f6acf36858eeed0c705afe367" +dependencies = [ + "dbus", +] + +[[package]] +name = "btleplug" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba345f9db94939c72959b2008abe1ffcdbcaa235243fd92ad12436532ff199cf" +dependencies = [ + "async-trait", + "bitflags 2.9.0", + "bluez-async", + "cocoa", + "dashmap", + "dbus", + "futures", + "jni", + "jni-utils", + "libc", + "log", + "objc", + "once_cell", + "static_assertions", + "thiserror 1.0.69", + "tokio", + "tokio-stream", + "uuid", + "windows 0.52.0", +] + +[[package]] +name = "bumpalo" +version = "3.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" + [[package]] name = "byteorder" version = "1.5.0" @@ -562,6 +738,21 @@ dependencies = [ "shlex", ] +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -606,15 +797,15 @@ dependencies = [ "aes-gcm", "anyhow", "async-trait", - "base64", + "base64 0.22.1", "cbc", - "dirs", + "dirs 6.0.0", "hex", "oo7", "pbkdf2", "rand 0.9.1", "rusqlite", - "security-framework", + "security-framework 3.5.0", "serde", "serde_json", "sha1", @@ -635,6 +826,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + [[package]] name = "clap" version = "4.5.40" @@ -684,6 +886,36 @@ dependencies = [ "error-code", ] +[[package]] +name = "cocoa" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6140449f97a6e97f9511815c5632d84c8aacf8ac271ad77c559218161a1373c" +dependencies = [ + "bitflags 1.3.2", + "block", + "cocoa-foundation", + "core-foundation 0.9.4", + "core-graphics", + "foreign-types 0.5.0", + "libc", + "objc", +] + +[[package]] +name = "cocoa-foundation" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7" +dependencies = [ + "bitflags 1.3.2", + "block", + "core-foundation 0.9.4", + "core-graphics-types", + "libc", + "objc", +] + [[package]] name = "codespan-reporting" version = "0.12.0" @@ -692,7 +924,7 @@ checksum = "fe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81" dependencies = [ "serde", "termcolor", - "unicode-width", + "unicode-width 0.2.0", ] [[package]] @@ -701,6 +933,16 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "concurrent-queue" version = "2.5.0" @@ -725,6 +967,16 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation" version = "0.10.1" @@ -741,6 +993,30 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "core-graphics" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" +dependencies = [ + "bitflags 1.3.2", + "core-foundation 0.9.4", + "core-graphics-types", + "foreign-types 0.5.0", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +dependencies = [ + "bitflags 1.3.2", + "core-foundation 0.9.4", + "libc", +] + [[package]] name = "cpufeatures" version = "0.2.17" @@ -756,6 +1032,12 @@ version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + [[package]] name = "crypto-bigint" version = "0.5.5" @@ -779,6 +1061,29 @@ dependencies = [ "typenum", ] +[[package]] +name = "ctap-hid-fido2" +version = "3.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6473a333d82796d5b23529fde19386de33820ad19d368402f8e9de780e1723" +dependencies = [ + "aes", + "anyhow", + "base64 0.22.1", + "byteorder", + "cbc", + "hex", + "hidapi", + "num", + "pad", + "ring", + "serde", + "serde_cbor", + "strum", + "strum_macros", + "x509-parser", +] + [[package]] name = "ctor" version = "0.2.9" @@ -900,6 +1205,49 @@ dependencies = [ "syn", ] +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "data-encoding" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" + +[[package]] +name = "dbus" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "190b6255e8ab55a7b568df5a883e9497edc3e4821c06396612048b430e5ad1e9" +dependencies = [ + "futures-channel", + "futures-util", + "libc", + "libdbus-sys", + "windows-sys 0.59.0", +] + +[[package]] +name = "dbus-tokio" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "007688d459bc677131c063a3a77fb899526e17b7980f390b69644bdbc41fad13" +dependencies = [ + "dbus", + "libc", + "tokio", +] + [[package]] name = "der" version = "0.7.10" @@ -911,6 +1259,29 @@ dependencies = [ "zeroize", ] +[[package]] +name = "der-parser" +version = "9.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cd0a5c643689626bec213c4d8bd4d96acc8ffdb4ad4bb6bc16abf27d5f4b553" +dependencies = [ + "asn1-rs", + "displaydoc", + "nom", + "num-bigint", + "num-traits", + "rusticata-macros", +] + +[[package]] +name = "deranged" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" +dependencies = [ + "powerfmt", +] + [[package]] name = "desktop_core" version = "0.0.0" @@ -919,15 +1290,15 @@ dependencies = [ "anyhow", "arboard", "ashpd", - "base64", + "base64 0.22.1", "bitwarden-russh", "byteorder", "bytes", "cbc", "chacha20poly1305", - "core-foundation", + "core-foundation 0.10.1", "desktop_objc", - "dirs", + "dirs 6.0.0", "ed25519", "futures", "homedir", @@ -944,7 +1315,7 @@ dependencies = [ "russh-cryptovec", "scopeguard", "secmem-proc", - "security-framework", + "security-framework 3.5.0", "security-framework-sys", "serde", "serde_json", @@ -972,9 +1343,10 @@ version = "0.0.0" dependencies = [ "anyhow", "autotype", - "base64", + "base64 0.22.1", "chromium_importer", "desktop_core", + "fido2_client", "hex", "napi", "napi-build", @@ -996,7 +1368,7 @@ version = "0.0.0" dependencies = [ "anyhow", "cc", - "core-foundation", + "core-foundation 0.10.1", "glob", "thiserror 2.0.12", "tokio", @@ -1029,13 +1401,34 @@ dependencies = [ "subtle", ] +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys 0.4.1", +] + [[package]] name = "dirs" version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" dependencies = [ - "dirs-sys", + "dirs-sys 0.5.0", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users 0.4.6", + "windows-sys 0.48.0", ] [[package]] @@ -1046,7 +1439,7 @@ checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" dependencies = [ "libc", "option-ext", - "redox_users", + "redox_users 0.5.0", "windows-sys 0.61.2", ] @@ -1056,7 +1449,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" dependencies = [ - "bitflags", + "bitflags 2.9.0", "objc2", ] @@ -1143,6 +1536,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + [[package]] name = "elliptic-curve" version = "0.13.8" @@ -1288,6 +1687,50 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" +[[package]] +name = "fido-hid-rs" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a8766c4600034812553d02c28dde631d51cad03c3ad1372ef7824c9627aabc8" +dependencies = [ + "async-trait", + "bindgen", + "bitflags 1.3.2", + "core-foundation 0.9.4", + "futures", + "lazy_static", + "libc", + "mach2", + "nix 0.26.4", + "num-derive", + "num-traits", + "thiserror 1.0.69", + "tokio", + "tokio-stream", + "tracing", + "udev", + "windows 0.41.0", +] + +[[package]] +name = "fido2_client" +version = "0.0.0" +dependencies = [ + "base64 0.22.1", + "ctap-hid-fido2", + "futures-util", + "hex", + "home", + "pinentry", + "secrecy", + "serde", + "serde_json", + "sha2", + "tokio", + "webauthn-authenticator-rs", + "webauthn-rs-proto", +] + [[package]] name = "fixedbitset" version = "0.4.2" @@ -1306,6 +1749,48 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared 0.3.1", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -1520,6 +2005,28 @@ dependencies = [ "subtle", ] +[[package]] +name = "half" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" + +[[package]] +name = "half" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" +dependencies = [ + "cfg-if", + "crunchy", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + [[package]] name = "hashbrown" version = "0.15.3" @@ -1535,7 +2042,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" dependencies = [ - "hashbrown", + "hashbrown 0.15.3", ] [[package]] @@ -1556,6 +2063,18 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hidapi" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "798154e4b6570af74899d71155fb0072d5b17e6aa12f39c8ef22c60fb8ec99e7" +dependencies = [ + "cc", + "libc", + "pkg-config", + "winapi", +] + [[package]] name = "hkdf" version = "0.12.4" @@ -1574,6 +2093,16 @@ dependencies = [ "digest", ] +[[package]] +name = "home" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c07c315e106bd6f83f026a20ddaeef2706782e490db1dcdd37caad38a0e895b3" +dependencies = [ + "scopeguard", + "winapi", +] + [[package]] name = "homedir" version = "0.3.4" @@ -1586,6 +2115,23 @@ dependencies = [ "windows 0.57.0", ] +[[package]] +name = "http" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + [[package]] name = "icu_collections" version = "2.0.0" @@ -1700,7 +2246,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.15.3", ] [[package]] @@ -1734,12 +2280,66 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +[[package]] +name = "jni" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6df18c2e3db7e453d3c6ac5b3e9d5182664d28788126d39b91f2d1e22b017ec" +dependencies = [ + "cesu8", + "combine", + "jni-sys", + "log", + "thiserror 1.0.69", + "walkdir", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jni-utils" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "259e9f2c3ead61de911f147000660511f07ab00adeed1d84f5ac4d0386e7a6c4" +dependencies = [ + "dashmap", + "futures", + "jni", + "log", + "once_cell", + "static_assertions", + "uuid", +] + +[[package]] +name = "js-sys" +version = "0.3.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + [[package]] name = "keytar" version = "0.1.6" @@ -1770,12 +2370,27 @@ dependencies = [ "spin", ] +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + [[package]] name = "libc" version = "0.2.172" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" +[[package]] +name = "libdbus-sys" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cbe856efeb50e4681f010e9aaa2bf0a644e10139e54cde10fc83a307c23bd9f" +dependencies = [ + "pkg-config", +] + [[package]] name = "libloading" version = "0.8.7" @@ -1798,7 +2413,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags", + "bitflags 2.9.0", "libc", ] @@ -1813,6 +2428,16 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "libudev-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c8469b4a23b962c1396b9b451dda50ef5b283e8dd309d69033475fa9b334324" +dependencies = [ + "libc", + "pkg-config", +] + [[package]] name = "link-cplusplus" version = "1.0.10" @@ -1828,7 +2453,7 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "761e49ec5fd8a5a463f9b84e877c373d888935b71c6be78f3767fe2ae6bed18e" dependencies = [ - "bitflags", + "bitflags 2.9.0", "libc", ] @@ -1866,6 +2491,15 @@ version = "0.4.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" +[[package]] +name = "mach2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d640282b302c0bb0a2a8e0233ead9035e3bed871f0b7e81fe4a1ec829765db44" +dependencies = [ + "libc", +] + [[package]] name = "macos_provider" version = "0.0.0" @@ -1882,6 +2516,15 @@ dependencies = [ "uniffi", ] +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + [[package]] name = "matchers" version = "0.2.0" @@ -1907,6 +2550,15 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + [[package]] name = "memoffset" version = "0.9.1" @@ -2001,7 +2653,7 @@ version = "2.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55740c4ae1d8696773c78fdafd5d0e5fe9bc9f1b071c7ba493ba5c413a9184f3" dependencies = [ - "bitflags", + "bitflags 2.9.0", "ctor 0.2.9", "napi-derive", "napi-sys", @@ -2053,13 +2705,43 @@ dependencies = [ "libloading", ] +[[package]] +name = "native-tls" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework 2.11.1", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset 0.7.1", + "pin-utils", +] + [[package]] name = "nix" version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags", + "bitflags 2.9.0", "cfg-if", "cfg_aliases", "libc", @@ -2071,11 +2753,11 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ - "bitflags", + "bitflags 2.9.0", "cfg-if", "cfg_aliases", "libc", - "memoffset", + "memoffset 0.9.1", ] [[package]] @@ -2157,6 +2839,23 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "num-integer" version = "0.1.46" @@ -2198,6 +2897,15 @@ dependencies = [ "libm", ] +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + [[package]] name = "objc2" version = "0.6.1" @@ -2213,7 +2921,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6f29f568bec459b0ddff777cec4fe3fd8666d82d5a40ebd0ff7e66134f89bcc" dependencies = [ - "bitflags", + "bitflags 2.9.0", "objc2", "objc2-core-graphics", "objc2-foundation", @@ -2225,7 +2933,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" dependencies = [ - "bitflags", + "bitflags 2.9.0", "dispatch2", "objc2", ] @@ -2236,7 +2944,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "989c6c68c13021b5c2d6b71456ebb0f9dc78d752e86a98da7c716f4f9470f5a4" dependencies = [ - "bitflags", + "bitflags 2.9.0", "dispatch2", "objc2", "objc2-core-foundation", @@ -2255,7 +2963,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c" dependencies = [ - "bitflags", + "bitflags 2.9.0", "objc2", "objc2-core-foundation", ] @@ -2276,7 +2984,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7282e9ac92529fa3457ce90ebb15f4ecbc383e8338060960760fa2cf75420c3c" dependencies = [ - "bitflags", + "bitflags 2.9.0", "objc2", "objc2-core-foundation", ] @@ -2290,6 +2998,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "oid-registry" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d8034d9489cdaf79228eb9f6a3b8d7bb32ba00d6645ebd48eef4077ceb5bd9" +dependencies = [ + "asn1-rs", +] + [[package]] name = "once_cell" version = "1.21.3" @@ -2333,6 +3050,50 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +[[package]] +name = "openssl" +version = "0.10.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" +dependencies = [ + "bitflags 2.9.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", +] + +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + +[[package]] +name = "openssl-sys" +version = "0.9.111" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "option-ext" version = "0.2.0" @@ -2397,6 +3158,15 @@ dependencies = [ "sha2", ] +[[package]] +name = "pad" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ad9b889f1b12e0b9ee24db044b5129150d5eada288edc800f789928dc8c0e3" +dependencies = [ + "unicode-width 0.1.14", +] + [[package]] name = "parking" version = "2.2.1" @@ -2432,6 +3202,12 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +[[package]] +name = "pastey" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35fb2e5f958ec131621fdd531e9fc186ed768cbe395337403ae56c17a74c68ec" + [[package]] name = "pbkdf2" version = "0.12.2" @@ -2442,6 +3218,12 @@ dependencies = [ "hmac", ] +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + [[package]] name = "pem-rfc7468" version = "0.7.0" @@ -2499,6 +3281,20 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pinentry" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72268b7db3a2075ea65d4b93b755d086e99196e327837e690db6559b393a8d69" +dependencies = [ + "log", + "nom", + "percent-encoding", + "secrecy", + "which", + "zeroize", +] + [[package]] name = "piper" version = "0.2.4" @@ -2607,6 +3403,12 @@ dependencies = [ "zerovec", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" version = "0.2.21" @@ -2642,6 +3444,16 @@ dependencies = [ "termtree", ] +[[package]] +name = "prettyplease" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6837b9e10d61f45f987d50808f83d1ee3d206c66acf650c3e4ae2e1f6ddedf55" +dependencies = [ + "proc-macro2", + "syn", +] + [[package]] name = "primeorder" version = "0.13.6" @@ -2774,7 +3586,18 @@ version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af" dependencies = [ - "bitflags", + "bitflags 2.9.0", +] + +[[package]] +name = "redox_users" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +dependencies = [ + "getrandom 0.2.16", + "libredox", + "thiserror 1.0.69", ] [[package]] @@ -2827,6 +3650,20 @@ dependencies = [ "subtle", ] +[[package]] +name = "ring" +version = "0.17.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e75ec5e92c4d8aede845126adc388046234541629e76029599ed35a003c7ed24" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.16", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + [[package]] name = "rsa" version = "0.9.6" @@ -2854,7 +3691,7 @@ version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "165ca6e57b20e1351573e3729b958bc62f0e48025386970b6e4d29e7a7e71f3f" dependencies = [ - "bitflags", + "bitflags 2.9.0", "fallible-iterator", "fallible-streaming-iterator", "hashlink", @@ -2878,6 +3715,12 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustc_version" version = "0.4.1" @@ -2887,13 +3730,22 @@ dependencies = [ "semver", ] +[[package]] +name = "rusticata-macros" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" +dependencies = [ + "nom", +] + [[package]] name = "rustix" version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags", + "bitflags 2.9.0", "errno", "libc", "linux-raw-sys 0.4.15", @@ -2906,7 +3758,7 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" dependencies = [ - "bitflags", + "bitflags 2.9.0", "errno", "libc", "linux-raw-sys 0.9.4", @@ -2944,6 +3796,15 @@ dependencies = [ "cipher", ] +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "scc" version = "2.4.0" @@ -2953,6 +3814,15 @@ dependencies = [ "sdd", ] +[[package]] +name = "schannel" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "scopeguard" version = "1.2.0" @@ -3031,14 +3901,36 @@ dependencies = [ "windows 0.61.1", ] +[[package]] +name = "secrecy" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" +dependencies = [ + "zeroize", +] + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.9.0", + "core-foundation 0.9.4", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + [[package]] name = "security-framework" version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc198e42d9b7510827939c9a15f5062a0c913f3371d765977e586d2fe6c16f4a" dependencies = [ - "bitflags", - "core-foundation", + "bitflags 2.9.0", + "core-foundation 0.10.1", "core-foundation-sys", "libc", "security-framework-sys", @@ -3072,6 +3964,47 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-xml-rs" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb3aa78ecda1ebc9ec9847d5d3aba7d618823446a049ba2491940506da6e2782" +dependencies = [ + "log", + "serde", + "thiserror 1.0.69", + "xml-rs", +] + +[[package]] +name = "serde_bytes" +version = "0.11.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8437fd221bde2d4ca316d61b90e337e9e702b3820b87d63caa9ba6c02bd06d96" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_cbor" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +dependencies = [ + "half 1.8.3", + "serde", +] + +[[package]] +name = "serde_cbor_2" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aec2709de9078e077090abd848e967abab63c9fb3fdb5d4799ad359d8d482c" +dependencies = [ + "half 2.6.0", + "serde", +] + [[package]] name = "serde_derive" version = "1.0.209" @@ -3315,6 +4248,25 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn", +] + [[package]] name = "subtle" version = "2.6.1" @@ -3443,6 +4395,37 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "time" +version = "0.3.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" + +[[package]] +name = "time-macros" +version = "0.2.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tinystr" version = "0.8.1" @@ -3453,6 +4436,21 @@ dependencies = [ "zerovec", ] +[[package]] +name = "tinyvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tokio" version = "1.45.0" @@ -3483,6 +4481,16 @@ dependencies = [ "syn", ] +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + [[package]] name = "tokio-stream" version = "0.1.15" @@ -3492,6 +4500,21 @@ dependencies = [ "futures-core", "pin-project-lite", "tokio", + "tokio-util", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edc5f74e248dc973e0dbb7b74c7e0d6fcc301c694ff50049504004ef4d0cdcd9" +dependencies = [ + "futures-util", + "log", + "native-tls", + "tokio", + "tokio-native-tls", + "tungstenite", ] [[package]] @@ -3658,19 +4681,49 @@ dependencies = [ "petgraph", ] +[[package]] +name = "tungstenite" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "native-tls", + "rand 0.8.5", + "sha1", + "thiserror 1.0.69", + "utf-8", +] + [[package]] name = "typenum" version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +[[package]] +name = "udev" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebdbbd670373442a12fe9ef7aeb53aec4147a5a27a00bbc3ab639f08f48191a" +dependencies = [ + "libc", + "libudev-sys", + "pkg-config", +] + [[package]] name = "uds_windows" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" dependencies = [ - "memoffset", + "memoffset 0.9.1", "tempfile", "winapi", ] @@ -3687,12 +4740,27 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +[[package]] +name = "unicode-normalization" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8" +dependencies = [ + "tinyvec", +] + [[package]] name = "unicode-segmentation" version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + [[package]] name = "unicode-width" version = "0.2.0" @@ -3839,6 +4907,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.5.4" @@ -3851,6 +4925,12 @@ dependencies = [ "serde", ] +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + [[package]] name = "utf8_iter" version = "1.0.4" @@ -3863,6 +4943,18 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "uuid" +version = "1.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" +dependencies = [ + "getrandom 0.3.3", + "js-sys", + "serde", + "wasm-bindgen", +] + [[package]] name = "valuable" version = "0.1.1" @@ -3881,7 +4973,7 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2ebfe12e38930c3b851aea35e93fab1a6c29279cad7e8e273f29a21678fee8c0" dependencies = [ - "core-foundation", + "core-foundation 0.10.1", "sha1", "sha2", "windows-sys 0.61.2", @@ -3913,6 +5005,16 @@ dependencies = [ "libc", ] +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -3928,6 +5030,51 @@ dependencies = [ "wit-bindgen-rt", ] +[[package]] +name = "wasm-bindgen" +version = "0.2.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76" +dependencies = [ + "unicode-ident", +] + [[package]] name = "wayland-backend" version = "0.3.10" @@ -3947,7 +5094,7 @@ version = "0.31.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978fa7c67b0847dbd6a9f350ca2569174974cd4082737054dbb7fbb79d7d9a61" dependencies = [ - "bitflags", + "bitflags 2.9.0", "rustix 0.38.44", "wayland-backend", "wayland-scanner", @@ -3959,7 +5106,7 @@ version = "0.32.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "779075454e1e9a521794fed15886323ea0feda3f8b0fc1390f5398141310422a" dependencies = [ - "bitflags", + "bitflags 2.9.0", "wayland-backend", "wayland-client", "wayland-scanner", @@ -3971,7 +5118,7 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1cb6cdc73399c0e06504c437fe3cf886f25568dd5454473d565085b36d6a8bbf" dependencies = [ - "bitflags", + "bitflags 2.9.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -3998,6 +5145,96 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "webauthn-attestation-ca" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f77a2892ec44032e6c48dad9aad1b05fada09c346ada11d8d32db119b4b4f205" +dependencies = [ + "base64urlsafedata", + "openssl", + "openssl-sys", + "serde", + "tracing", + "uuid", +] + +[[package]] +name = "webauthn-authenticator-rs" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45f8fe3811c8d6c6830d263452670a608fd4dcdfc481349bd4d1e6a46d6c7a0f" +dependencies = [ + "async-stream", + "async-trait", + "base64 0.21.7", + "base64urlsafedata", + "bitflags 1.3.2", + "btleplug", + "fido-hid-rs", + "futures", + "hex", + "nom", + "num-derive", + "num-traits", + "openssl", + "openssl-sys", + "serde", + "serde_bytes", + "serde_cbor_2", + "serde_json", + "thiserror 1.0.69", + "tokio", + "tokio-stream", + "tokio-tungstenite", + "tracing", + "unicode-normalization", + "url", + "uuid", + "webauthn-rs-core", + "webauthn-rs-proto", +] + +[[package]] +name = "webauthn-rs-core" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f1d80f3146382529fe70a3ab5d0feb2413a015204ed7843f9377cd39357fc4" +dependencies = [ + "base64 0.21.7", + "base64urlsafedata", + "der-parser", + "hex", + "nom", + "openssl", + "openssl-sys", + "rand 0.8.5", + "rand_chacha 0.3.1", + "serde", + "serde_cbor_2", + "serde_json", + "thiserror 1.0.69", + "tracing", + "url", + "uuid", + "webauthn-attestation-ca", + "webauthn-rs-proto", + "x509-parser", +] + +[[package]] +name = "webauthn-rs-proto" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e786894f89facb9aaf1c5f6559670236723c98382e045521c76f3d5ca5047bd" +dependencies = [ + "base64 0.21.7", + "base64urlsafedata", + "serde", + "serde_json", + "url", +] + [[package]] name = "weedle2" version = "5.0.0" @@ -4007,6 +5244,18 @@ dependencies = [ "nom", ] +[[package]] +name = "which" +version = "4.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ad25fe5717e59ada8ea33511bbbf7420b11031730a24c65e82428766c307006" +dependencies = [ + "dirs 5.0.1", + "either", + "once_cell", + "rustix 0.38.44", +] + [[package]] name = "widestring" version = "1.2.0" @@ -4044,6 +5293,31 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3ed69de2c1f8d0524a8a3417a80a85dd316a071745fbfdf5eb028b310058ab" +dependencies = [ + "windows_aarch64_gnullvm 0.41.0", + "windows_aarch64_msvc 0.41.0", + "windows_i686_gnu 0.41.0", + "windows_i686_msvc 0.41.0", + "windows_x86_64_gnu 0.41.0", + "windows_x86_64_gnullvm 0.41.0", + "windows_x86_64_msvc 0.41.0", +] + +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core 0.52.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows" version = "0.57.0" @@ -4076,6 +5350,15 @@ dependencies = [ "windows-core 0.61.0", ] +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-core" version = "0.57.0" @@ -4242,6 +5525,15 @@ dependencies = [ "windows-targets 0.42.2", ] +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + [[package]] name = "windows-sys" version = "0.52.0" @@ -4341,6 +5633,12 @@ dependencies = [ "windows_x86_64_msvc 0.53.0", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "163d2761774f2278ecb4e6719e80b2b5e92e5a2be73a7bcd3ef624dd5e3091fd" + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -4365,6 +5663,12 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" +[[package]] +name = "windows_aarch64_msvc" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef005ff2bceb00d3b84166a359cc19084f9459754fd3fe5a504dee3dddcd0a0c" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -4389,6 +5693,12 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" +[[package]] +name = "windows_i686_gnu" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b4df2d51e32f03f8b4b228e487828c03bcb36d97b216fc5463bcea5bb1440b" + [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -4425,6 +5735,12 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" +[[package]] +name = "windows_i686_msvc" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "568a966834571f2f3267f07dd72b4d8507381f25e53d056808483b2637385ef7" + [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -4458,6 +5774,12 @@ dependencies = [ "windows-core 0.61.0", ] +[[package]] +name = "windows_x86_64_gnu" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc395dac1adf444e276d096d933ae7961361c8cda3245cffef7a9b3a70a8f994" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -4482,6 +5804,12 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90e8ec22b715d5b436e1d59c8adad6c744dc20cd984710121d5836b4e8dbb5e0" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -4506,6 +5834,12 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" +[[package]] +name = "windows_x86_64_msvc" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9761f0216b669019df1512f6e25e5ee779bf61c5cdc43c7293858e7efd7926" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -4555,7 +5889,7 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ - "bitflags", + "bitflags 2.9.0", ] [[package]] @@ -4600,6 +5934,29 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d" +[[package]] +name = "x509-parser" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcbc162f30700d6f3f82a24bf7cc62ffe7caea42c0b2cba8bf7f3ae50cf51f69" +dependencies = [ + "asn1-rs", + "data-encoding", + "der-parser", + "lazy_static", + "nom", + "oid-registry", + "rusticata-macros", + "thiserror 1.0.69", + "time", +] + +[[package]] +name = "xml-rs" +version = "0.8.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ae8337f8a065cfc972643663ea4279e04e7256de865aa66fe25cec5fb912d3f" + [[package]] name = "yoke" version = "0.8.0" diff --git a/apps/desktop/desktop_native/Cargo.toml b/apps/desktop/desktop_native/Cargo.toml index ccf7c1f3796..008eaa3d12c 100644 --- a/apps/desktop/desktop_native/Cargo.toml +++ b/apps/desktop/desktop_native/Cargo.toml @@ -5,6 +5,7 @@ members = [ "bitwarden_chromium_import_helper", "chromium_importer", "core", + "fido2_client", "macos_provider", "napi", "process_isolation", diff --git a/apps/desktop/desktop_native/fido2_client/Cargo.toml b/apps/desktop/desktop_native/fido2_client/Cargo.toml new file mode 100644 index 00000000000..fdf2c0e2799 --- /dev/null +++ b/apps/desktop/desktop_native/fido2_client/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "fido2_client" +edition = { workspace = true } +license = { workspace = true } +version = { workspace = true } +publish = { workspace = true } + +[dependencies] +base64.workspace = true +ctap-hid-fido2 = "3.5.1" +pinentry = "0.5.0" +home = "=0.5.0" +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +secrecy = "0.8.0" +hex.workspace = true +webauthn-authenticator-rs = { version = "0.5.3", features = ["ctap2", "cable", "usb"] } +tokio.workspace = true +futures-util = "0.3.31" +webauthn-rs-proto = "0.5.3" +sha2.workspace = true + diff --git a/apps/desktop/desktop_native/fido2_client/src/ctap_hid_fido2.rs b/apps/desktop/desktop_native/fido2_client/src/ctap_hid_fido2.rs new file mode 100644 index 00000000000..c409535b8a1 --- /dev/null +++ b/apps/desktop/desktop_native/fido2_client/src/ctap_hid_fido2.rs @@ -0,0 +1,104 @@ +use base64::{prelude::BASE64_URL_SAFE_NO_PAD, Engine}; +use ctap_hid_fido2::{ + fidokey::{AssertionExtension, GetAssertionArgsBuilder}, + Cfg, FidoKeyHidFactory, +}; +use pinentry::PassphraseInput; +use secrecy::ExposeSecret; + +use crate::{ + prf_to_hmac, AssertionOptions, AuthenticatorAssertionResponse, Fido2ClientError, + PublicKeyCredential, +}; + +fn get_pin() -> Option { + if let Some(mut input) = PassphraseInput::with_default_binary() { + input + .with_description("Enter your FIDO2 Authenticator PIN:") + .with_prompt("PIN:") + .interact() + .ok() + .map(|p| p.expose_secret().to_owned()) + } else { + None + } +} + +pub fn available() -> bool { + true +} + +pub fn get(options: AssertionOptions) -> Result { + let device = FidoKeyHidFactory::create(&Cfg::init()).map_err(|_| Fido2ClientError::NoDevice)?; + + let client_data_json = format!( + r#"{{"type":"webauthn.get","challenge":"{}","origin":"https://{}","crossOrigin": true}}"#, + BASE64_URL_SAFE_NO_PAD.encode(&options.challenge), + options.rpid + ); + + let mut get_assertion_args = + GetAssertionArgsBuilder::new(options.rpid.as_str(), client_data_json.as_bytes()) + .extensions(&[AssertionExtension::HmacSecret(Some(prf_to_hmac( + &options.prf_eval_first, + )))]); + + let mut pin: Option = None; + if options.user_verification == crate::UserVerification::Required + || options.user_verification == crate::UserVerification::Preferred + { + pin = Some(get_pin().ok_or(Fido2ClientError::WrongPin)?); + get_assertion_args = get_assertion_args.pin(pin.as_ref().unwrap()); + } + + let assertions = device + .get_assertion_with_args(&get_assertion_args.build()) + .map_err(|_e| Fido2ClientError::AssertionError)?; + let assertion = assertions.get(0).ok_or(Fido2ClientError::AssertionError)?; + + let prf_extension = assertion + .extensions + .iter() + .find_map(|ext| { + if let AssertionExtension::HmacSecret(results) = ext { + Some(*results) + } else { + None + } + }) + .flatten(); + + Ok(PublicKeyCredential { + authenticator_attachment: "cross-platform".to_string(), + id: BASE64_URL_SAFE_NO_PAD.encode(&assertion.credential_id), + raw_id: assertion.credential_id.clone(), + response: AuthenticatorAssertionResponse { + authenticator_data: assertion.auth_data.clone(), + client_data_json: client_data_json.as_bytes().to_vec(), + signature: assertion.signature.clone(), + user_handle: assertion.user.id.clone(), + }, + r#type: "public-key".to_string(), + prf: prf_extension, + }) +} + +#[cfg(test)] +mod tests { + use crate::{ctap_hid_fido2::get, AssertionOptions}; + + #[test] + #[ignore] + fn assertion() { + get(AssertionOptions { + challenge: vec![], + timeout: 0, + rpid: "example.com".to_string(), + user_verification: crate::UserVerification::Required, + allow_credentials: vec![], + prf_eval_first: [0u8; 32], + prf_eval_second: None, + }) + .unwrap(); + } +} diff --git a/apps/desktop/desktop_native/fido2_client/src/lib.rs b/apps/desktop/desktop_native/fido2_client/src/lib.rs new file mode 100644 index 00000000000..e489d5672b1 --- /dev/null +++ b/apps/desktop/desktop_native/fido2_client/src/lib.rs @@ -0,0 +1,69 @@ +#[cfg(all(target_os = "linux", target_env = "gnu"))] +mod ctap_hid_fido2; +#[cfg(all(target_os = "linux", target_env = "gnu"))] +use ctap_hid_fido2::*; + +#[cfg(not(all(target_os = "linux", target_env = "gnu")))] +mod unimplemented; +#[cfg(not(all(target_os = "linux", target_env = "gnu")))] +use unimplemented::*; + +fn prf_to_hmac(prf_salt: &[u8]) -> [u8; 32] { + use sha2::Digest; + sha2::Sha256::digest(&[b"WebAuthn PRF".as_slice(), &[0], prf_salt].concat()).into() +} + +#[derive(Debug, PartialEq)] +pub enum UserVerification { + Discouraged, + Preferred, + Required, +} + +#[derive(Debug)] +pub struct AssertionOptions { + pub challenge: Vec, + pub timeout: u64, + pub rpid: String, + pub user_verification: UserVerification, + pub allow_credentials: Vec>, + pub prf_eval_first: [u8; 32], + pub prf_eval_second: Option<[u8; 32]>, +} + +pub struct AuthenticatorAssertionResponse { + pub authenticator_data: Vec, + pub client_data_json: Vec, + pub signature: Vec, + pub user_handle: Vec, +} + +pub struct PublicKeyCredential { + pub authenticator_attachment: String, + pub id: String, + pub raw_id: Vec, + pub response: AuthenticatorAssertionResponse, + pub r#type: String, + pub prf: Option<[u8; 32]>, +} + +#[derive(Debug)] +pub enum Fido2ClientError { + WrongPin, + NoCredentials, + NoDevice, + InvalidInput, + AssertionError, +} + +pub mod fido2_client { + pub fn get( + assertion_options: super::AssertionOptions, + ) -> Result { + super::get(assertion_options) + } + + pub fn available() -> bool { + super::available() + } +} diff --git a/apps/desktop/desktop_native/fido2_client/src/unimplemented.rs b/apps/desktop/desktop_native/fido2_client/src/unimplemented.rs new file mode 100644 index 00000000000..6812a1a0c2a --- /dev/null +++ b/apps/desktop/desktop_native/fido2_client/src/unimplemented.rs @@ -0,0 +1,7 @@ +pub fn get(options: AssertionOptions) -> Result { + todo!("Fido2Client is unimplemented on this platform"); +} + +pub fn available() -> bool { + false +} diff --git a/apps/desktop/desktop_native/napi/Cargo.toml b/apps/desktop/desktop_native/napi/Cargo.toml index 4198baa4b5a..21e976dfd20 100644 --- a/apps/desktop/desktop_native/napi/Cargo.toml +++ b/apps/desktop/desktop_native/napi/Cargo.toml @@ -19,6 +19,7 @@ autotype = { path = "../autotype" } base64 = { workspace = true } chromium_importer = { path = "../chromium_importer" } desktop_core = { path = "../core" } +fido2_client = { path = "../fido2_client" } hex = { workspace = true } napi = { workspace = true, features = ["async"] } napi-derive = { workspace = true } diff --git a/apps/desktop/desktop_native/napi/index.d.ts b/apps/desktop/desktop_native/napi/index.d.ts index 0a8beb8c427..daec1147298 100644 --- a/apps/desktop/desktop_native/napi/index.d.ts +++ b/apps/desktop/desktop_native/napi/index.d.ts @@ -3,6 +3,33 @@ /* auto-generated by NAPI-RS */ +export const enum UserVerification { + Preferred = 'Preferred', + Required = 'Required', + Discouraged = 'Discouraged' +} +export interface CredentialAssertionOptions { + challenge: Uint8Array + timeout: number + rpid: string + userVerification: UserVerification + allowCredentials: Array> + prfEvalFirst: Uint8Array +} +export interface AuthenticatorAssertionResponse { + authenticatorData: Uint8Array + clientDataJson: Uint8Array + signature: Uint8Array + userHandle: Uint8Array +} +export interface PublicKeyCredential { + authenticatorAttachment: string + id: string + rawId: Uint8Array + response: AuthenticatorAssertionResponse + type: string + prf?: Uint8Array +} export declare namespace passwords { /** The error message returned when a password is not found during retrieval or deletion. */ export const PASSWORD_NOT_FOUND: string @@ -254,3 +281,7 @@ export declare namespace autotype { export function getForegroundWindowTitle(): string export function typeInput(input: Array, keyboardShortcut: Array): void } +export declare namespace navigator_credentials { + export function get(assertionOptions: CredentialAssertionOptions): PublicKeyCredential + export function available(): boolean +} diff --git a/apps/desktop/desktop_native/napi/src/lib.rs b/apps/desktop/desktop_native/napi/src/lib.rs index 39e57bd0bb5..6943d553c82 100644 --- a/apps/desktop/desktop_native/napi/src/lib.rs +++ b/apps/desktop/desktop_native/napi/src/lib.rs @@ -1,3 +1,6 @@ +use napi::bindgen_prelude::{Buffer, Uint8Array}; +use tokio_util::bytes::Buf; + #[macro_use] extern crate napi_derive; @@ -1199,3 +1202,107 @@ pub mod autotype { }) } } + +#[napi(string_enum)] +pub enum UserVerification { + Preferred, + Required, + Discouraged, +} + +impl Into for UserVerification { + fn into(self) -> fido2_client::UserVerification { + match self { + UserVerification::Preferred => fido2_client::UserVerification::Preferred, + UserVerification::Required => fido2_client::UserVerification::Required, + UserVerification::Discouraged => fido2_client::UserVerification::Discouraged, + } + } +} + +#[napi(object)] +pub struct CredentialAssertionOptions { + pub challenge: Uint8Array, + pub timeout: i64, + pub rpid: String, + pub user_verification: UserVerification, + pub allow_credentials: Vec>, + pub prf_eval_first: Uint8Array, +} + +impl Into for CredentialAssertionOptions { + fn into(self) -> fido2_client::AssertionOptions { + fido2_client::AssertionOptions { + challenge: self.challenge.to_vec(), + timeout: self.timeout as u64, + rpid: self.rpid, + user_verification: self.user_verification.into(), + allow_credentials: self.allow_credentials, + prf_eval_first: self.prf_eval_first.to_vec().try_into().unwrap_or([0u8; 32]), + prf_eval_second: None, + } + } +} + +#[napi(object)] +pub struct AuthenticatorAssertionResponse { + pub authenticator_data: Uint8Array, + pub client_data_json: Uint8Array, + pub signature: Uint8Array, + pub user_handle: Uint8Array, +} + +impl From for AuthenticatorAssertionResponse { + fn from(response: fido2_client::AuthenticatorAssertionResponse) -> Self { + AuthenticatorAssertionResponse { + authenticator_data: Uint8Array::from(response.authenticator_data), + client_data_json: Uint8Array::from(response.client_data_json), + signature: Uint8Array::from(response.signature), + user_handle: Uint8Array::from(response.user_handle), + } + } +} + +#[napi(object)] +pub struct PublicKeyCredential { + pub authenticator_attachment: String, + pub id: String, + pub raw_id: Uint8Array, + pub response: AuthenticatorAssertionResponse, + pub r#type: String, + pub prf: Option, +} + +impl Into for fido2_client::PublicKeyCredential { + fn into(self) -> PublicKeyCredential { + PublicKeyCredential { + authenticator_attachment: self.authenticator_attachment, + id: self.id, + raw_id: Uint8Array::from(self.raw_id), + response: self.response.into(), + r#type: self.r#type, + prf: self.prf.map(|p| Uint8Array::from(p)), + } + } +} + +#[napi] +pub mod navigator_credentials { + use crate::CredentialAssertionOptions; + + #[napi] + pub fn get( + assertion_options: CredentialAssertionOptions, + ) -> napi::Result { + let options: fido2_client::AssertionOptions = assertion_options.into(); + let resp = fido2_client::fido2_client::get(options).map_err(|e| { + napi::Error::from_reason(format!("FIDO2 Authentication failed: {:?}", e)) + })?; + Ok(resp.into()) + } + + #[napi] + pub fn available() -> bool { + fido2_client::fido2_client::available() + } +} diff --git a/apps/desktop/src/app/app-routing.module.ts b/apps/desktop/src/app/app-routing.module.ts index b6e86ba19ff..2deaa02dc46 100644 --- a/apps/desktop/src/app/app-routing.module.ts +++ b/apps/desktop/src/app/app-routing.module.ts @@ -12,6 +12,7 @@ import { tdeDecryptionRequiredGuard, unauthGuardFn, } from "@bitwarden/angular/auth/guards"; +import { LoginViaWebAuthnComponent } from "@bitwarden/angular/auth/login-via-webauthn/login-via-webauthn.component"; import { ChangePasswordComponent } from "@bitwarden/angular/auth/password-management/change-password"; import { SetInitialPasswordComponent } from "@bitwarden/angular/auth/password-management/set-initial-password/set-initial-password.component"; import { @@ -23,6 +24,7 @@ import { VaultIcon, LockIcon, DomainIcon, + TwoFactorAuthSecurityKeyIcon, } from "@bitwarden/assets/svg"; import { LoginComponent, @@ -123,6 +125,27 @@ const routes: Routes = [ path: "", component: AnonLayoutWrapperComponent, children: [ + { + path: AuthRoute.LoginWithPasskey, + canActivate: [unauthGuardFn()], + data: { + pageIcon: TwoFactorAuthSecurityKeyIcon, + pageTitle: { + key: "logInWithPasskey", + }, + pageSubtitle: { + key: "readingPasskeyLoadingInfo", + }, + } satisfies RouteDataProperties & AnonLayoutWrapperData, + children: [ + { path: "", component: LoginViaWebAuthnComponent }, + { + path: "", + component: EnvironmentSelectorComponent, + outlet: "environment-selector", + }, + ], + }, { path: AuthRoute.SignUp, canActivate: [unauthGuardFn()], diff --git a/apps/desktop/src/app/services/services.module.ts b/apps/desktop/src/app/services/services.module.ts index 03d6eb5c908..7ef33a2e1e8 100644 --- a/apps/desktop/src/app/services/services.module.ts +++ b/apps/desktop/src/app/services/services.module.ts @@ -33,6 +33,7 @@ import { import { InternalUserDecryptionOptionsServiceAbstraction, LoginEmailService, + LoginStrategyServiceAbstraction, SsoUrlService, } from "@bitwarden/auth/common"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; @@ -51,6 +52,9 @@ import { } from "@bitwarden/common/auth/abstractions/auth.service"; import { MasterPasswordApiService } from "@bitwarden/common/auth/abstractions/master-password-api.service.abstraction"; import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction"; +import { WebAuthnLoginApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/webauthn/webauthn-login-api.service.abstraction"; +import { WebAuthnLoginPrfKeyServiceAbstraction } from "@bitwarden/common/auth/abstractions/webauthn/webauthn-login-prf-key.service.abstraction"; +import { WebAuthnLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/webauthn/webauthn-login.service.abstraction"; import { AutofillSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/autofill-settings.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions"; import { ClientType } from "@bitwarden/common/enums"; @@ -119,6 +123,7 @@ import { DefaultSshImportPromptService, SshImportPromptService } from "@bitwarde import { DesktopLoginApprovalDialogComponentService } from "../../auth/login/desktop-login-approval-dialog-component.service"; import { DesktopLoginComponentService } from "../../auth/login/desktop-login-component.service"; import { DesktopTwoFactorAuthDuoComponentService } from "../../auth/services/desktop-two-factor-auth-duo-component.service"; +import { DesktopWebAuthnLoginService } from "../../auth/services/desktop-webauthn-login.serivce"; import { DesktopAutofillSettingsService } from "../../autofill/services/desktop-autofill-settings.service"; import { DesktopAutofillService } from "../../autofill/services/desktop-autofill.service"; import { DesktopAutotypeDefaultSettingPolicy } from "../../autofill/services/desktop-autotype-policy.service"; @@ -310,6 +315,17 @@ const safeProviders: SafeProvider[] = [ useClass: WebCryptoFunctionService, deps: [WINDOW], }), + safeProvider({ + provide: WebAuthnLoginServiceAbstraction, + useClass: DesktopWebAuthnLoginService, + deps: [ + WebAuthnLoginApiServiceAbstraction, + LoginStrategyServiceAbstraction, + WebAuthnLoginPrfKeyServiceAbstraction, + WINDOW, + LogService, + ], + }), safeProvider({ provide: KeyServiceAbstraction, useClass: ElectronKeyService, diff --git a/apps/desktop/src/auth/preload.ts b/apps/desktop/src/auth/preload.ts index 7c213934659..9889048f9cf 100644 --- a/apps/desktop/src/auth/preload.ts +++ b/apps/desktop/src/auth/preload.ts @@ -1,5 +1,7 @@ import { ipcRenderer } from "electron"; +import { PublicKeyCredential } from "@bitwarden/desktop-napi"; + export default { loginRequest: (alertTitle: string, alertBody: string, buttonText: string): Promise => ipcRenderer.invoke("loginRequest", { @@ -7,4 +9,7 @@ export default { alertBody, buttonText, }), + navigatorCredentialsGet: ( + options: CredentialRequestOptions, + ): Promise => ipcRenderer.invoke("navigatorCredentialsGet", options), }; diff --git a/apps/desktop/src/auth/services/desktop-webauthn-login.serivce.ts b/apps/desktop/src/auth/services/desktop-webauthn-login.serivce.ts new file mode 100644 index 00000000000..49d9f6d1b8e --- /dev/null +++ b/apps/desktop/src/auth/services/desktop-webauthn-login.serivce.ts @@ -0,0 +1,86 @@ +import { LoginStrategyServiceAbstraction, WebAuthnLoginCredentials } from "@bitwarden/auth/common"; +import { WebAuthnLoginApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/webauthn/webauthn-login-api.service.abstraction"; +import { WebAuthnLoginPrfKeyServiceAbstraction } from "@bitwarden/common/auth/abstractions/webauthn/webauthn-login-prf-key.service.abstraction"; +import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result"; +import { WebAuthnLoginCredentialAssertionOptionsView } from "@bitwarden/common/auth/models/view/webauthn-login/webauthn-login-credential-assertion-options.view"; +import { WebAuthnLoginCredentialAssertionView } from "@bitwarden/common/auth/models/view/webauthn-login/webauthn-login-credential-assertion.view"; +import { WebAuthnLoginAssertionResponseRequest } from "@bitwarden/common/auth/services/webauthn-login/request/webauthn-login-assertion-response.request"; +import { WebAuthnLoginService } from "@bitwarden/common/auth/services/webauthn-login/webauthn-login.service"; +import { PrfKey } from "@bitwarden/common/types/key"; +import { LogService } from "@bitwarden/logging"; + +export class DesktopWebAuthnLoginService extends WebAuthnLoginService { + constructor( + webAuthnLoginApiService: WebAuthnLoginApiServiceAbstraction, + loginStrategyService: LoginStrategyServiceAbstraction, + webAuthnLoginPrfKeyService: WebAuthnLoginPrfKeyServiceAbstraction, + window: Window, + logService?: LogService, + ) { + super( + webAuthnLoginApiService, + loginStrategyService, + webAuthnLoginPrfKeyService, + window, + logService, + ); + } + + async assertCredential( + credentialAssertionOptions: WebAuthnLoginCredentialAssertionOptionsView, + ): Promise { + const nativeOptions: CredentialRequestOptions = { + publicKey: credentialAssertionOptions.options, + }; + // TODO: Remove `any` when typescript typings add support for PRF + nativeOptions.publicKey.extensions = { + prf: { eval: { first: await this.webAuthnLoginPrfKeyService.getLoginWithPrfSalt() } }, + } as any; + + try { + const response = await ipc.auth.navigatorCredentialsGet(nativeOptions); + this.logService.info("navigator.credentials.get response received", response); + // if (!(response instanceof PublicKeyCredential)) { + // return undefined; + // } + // TODO: Remove `any` when typescript typings add support for PRF + const prfResult = (response as any).prf as Uint8Array | undefined; + let symmetricPrfKey: PrfKey | undefined; + if (prfResult != undefined) { + // Ensure we pass a plain ArrayBuffer (not a SharedArrayBuffer) by copying the bytes. + symmetricPrfKey = await this.webAuthnLoginPrfKeyService.createSymmetricKeyFromPrf( + prfResult.slice().buffer, + ); + } + + const deviceResponse = new WebAuthnLoginAssertionResponseRequest( + response as any as PublicKeyCredential, + ); + + // Verify that we aren't going to send PRF information to the server in any case. + // Note: this will only happen if a dev has done something wrong. + if ("prf" in deviceResponse.extensions) { + throw new Error("PRF information is not allowed to be sent to the server."); + } + + return new WebAuthnLoginCredentialAssertionView( + credentialAssertionOptions.token, + deviceResponse, + symmetricPrfKey, + ); + } catch (error) { + this.logService?.error(error); + return undefined; + } + } + + async logIn(assertion: WebAuthnLoginCredentialAssertionView): Promise { + const credential = new WebAuthnLoginCredentials( + assertion.token, + assertion.deviceResponse, + assertion.prfKey, + ); + const result = await this.loginStrategyService.logIn(credential); + return result; + } +} diff --git a/apps/desktop/src/auth/services/main-navigator-credentials.serivce.ts b/apps/desktop/src/auth/services/main-navigator-credentials.serivce.ts new file mode 100644 index 00000000000..a86c6ad350a --- /dev/null +++ b/apps/desktop/src/auth/services/main-navigator-credentials.serivce.ts @@ -0,0 +1,29 @@ +import { ipcMain } from "electron"; + +import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; +import { Utils } from "@bitwarden/common/platform/misc/utils"; +import { navigator_credentials, UserVerification } from "@bitwarden/desktop-napi"; + +export class MainNavigatorCredentialsService { + constructor(private logService: LogService) { + ipcMain.handle("navigatorCredentialsGet", async (event: any, message: any) => { + this.logService.info("Handling navigatorCredentials.get request from renderer", message); + const challenge = Utils.fromB64ToArray(message.publicKey.response.challenge); + this.logService.info("navigatorCredentials.get challenge", challenge); + this.logService.info( + "navigatorCredentials.get prfEvalFirst", + message.publicKey.extensions.prf.eval.first, + ); + const result = navigator_credentials.get({ + challenge: Uint8Array.from(challenge), + timeout: message.publicKey.timeout, + rpid: message.publicKey.rpId, + userVerification: UserVerification.Required, + allowCredentials: [], + prfEvalFirst: Uint8Array.from(message.publicKey.extensions.prf.eval.first), + }); + this.logService.info("navigatorCredentials.get result", result); + return result; + }); + } +} diff --git a/apps/desktop/src/main.ts b/apps/desktop/src/main.ts index fbb83a1bf56..6dce97e8a0c 100644 --- a/apps/desktop/src/main.ts +++ b/apps/desktop/src/main.ts @@ -34,6 +34,7 @@ import { import { SerializedMemoryStorageService, StorageServiceProvider } from "@bitwarden/storage-core"; import { ChromiumImporterService } from "./app/tools/import/chromium-importer.service"; +import { MainNavigatorCredentialsService } from "./auth/services/main-navigator-credentials.serivce"; import { MainDesktopAutotypeService } from "./autofill/main/main-desktop-autotype.service"; import { MainSshAgentService } from "./autofill/main/main-ssh-agent.service"; import { DesktopAutofillSettingsService } from "./autofill/services/desktop-autofill-settings.service"; @@ -284,6 +285,7 @@ export class Main { app.getPath("exe"), app.getAppPath(), ); + new MainNavigatorCredentialsService(this.logService); this.desktopAutofillSettingsService = new DesktopAutofillSettingsService(stateProvider); diff --git a/apps/desktop/src/platform/services/electron-platform-utils.service.ts b/apps/desktop/src/platform/services/electron-platform-utils.service.ts index de63c6b28aa..884a1835492 100644 --- a/apps/desktop/src/platform/services/electron-platform-utils.service.ts +++ b/apps/desktop/src/platform/services/electron-platform-utils.service.ts @@ -113,7 +113,7 @@ export class ElectronPlatformUtilsService implements PlatformUtilsService { } isDev(): boolean { - return ipc.platform.isDev; + return true; } isSelfHost(): boolean { diff --git a/libs/angular/src/auth/login-via-webauthn/login-via-webauthn.component.ts b/libs/angular/src/auth/login-via-webauthn/login-via-webauthn.component.ts index fa2a01fe8e1..effca732861 100644 --- a/libs/angular/src/auth/login-via-webauthn/login-via-webauthn.component.ts +++ b/libs/angular/src/auth/login-via-webauthn/login-via-webauthn.component.ts @@ -98,6 +98,7 @@ export class LoginViaWebAuthnComponent implements OnInit { let assertion: WebAuthnLoginCredentialAssertionView; try { const options = await this.webAuthnLoginService.getCredentialAssertionOptions(); + this.logService.info("Starting WebAuthn assertion with options:", options); assertion = await this.webAuthnLoginService.assertCredential(options); } catch (error) { this.validationService.showError(error); diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index 9dbc6679963..0d1e9eb653c 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -107,7 +107,6 @@ import { UserVerificationApiServiceAbstraction } from "@bitwarden/common/auth/ab import { UserVerificationService as UserVerificationServiceAbstraction } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { WebAuthnLoginApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/webauthn/webauthn-login-api.service.abstraction"; import { WebAuthnLoginPrfKeyServiceAbstraction } from "@bitwarden/common/auth/abstractions/webauthn/webauthn-login-prf-key.service.abstraction"; -import { WebAuthnLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/webauthn/webauthn-login.service.abstraction"; import { SendTokenService, DefaultSendTokenService } from "@bitwarden/common/auth/send-access"; import { AccountApiServiceImplementation } from "@bitwarden/common/auth/services/account-api.service"; import { AccountServiceImplementation } from "@bitwarden/common/auth/services/account.service"; @@ -130,8 +129,6 @@ import { UserVerificationApiService } from "@bitwarden/common/auth/services/user import { UserVerificationService } from "@bitwarden/common/auth/services/user-verification/user-verification.service"; import { WebAuthnLoginApiService } from "@bitwarden/common/auth/services/webauthn-login/webauthn-login-api.service"; import { WebAuthnLoginPrfKeyService } from "@bitwarden/common/auth/services/webauthn-login/webauthn-login-prf-key.service"; -import { WebAuthnLoginService } from "@bitwarden/common/auth/services/webauthn-login/webauthn-login.service"; -import { TwoFactorApiService, DefaultTwoFactorApiService } from "@bitwarden/common/auth/two-factor"; import { AutofillSettingsService, AutofillSettingsServiceAbstraction, @@ -1339,17 +1336,17 @@ const safeProviders: SafeProvider[] = [ useClass: WebAuthnLoginApiService, deps: [ApiServiceAbstraction, EnvironmentService], }), - safeProvider({ - provide: WebAuthnLoginServiceAbstraction, - useClass: WebAuthnLoginService, - deps: [ - WebAuthnLoginApiServiceAbstraction, - LoginStrategyServiceAbstraction, - WebAuthnLoginPrfKeyServiceAbstraction, - WINDOW, - LogService, - ], - }), + // safeProvider({ + // provide: WebAuthnLoginServiceAbstraction, + // useClass: WebAuthnLoginService, + // deps: [ + // WebAuthnLoginApiServiceAbstraction, + // LoginStrategyServiceAbstraction, + // WebAuthnLoginPrfKeyServiceAbstraction, + // WINDOW, + // LogService, + // ], + // }), safeProvider({ provide: StorageServiceProvider, useClass: StorageServiceProvider, diff --git a/libs/auth/src/angular/login/default-login-component.service.ts b/libs/auth/src/angular/login/default-login-component.service.ts index 7f98040d9c2..1f145dc06fd 100644 --- a/libs/auth/src/angular/login/default-login-component.service.ts +++ b/libs/auth/src/angular/login/default-login-component.service.ts @@ -24,7 +24,7 @@ export class DefaultLoginComponentService implements LoginComponentService { } isLoginWithPasskeySupported(): boolean { - return this.clientType === ClientType.Web; + return true; } /** diff --git a/libs/common/src/auth/services/webauthn-login/request/webauthn-login-assertion-response.request.ts b/libs/common/src/auth/services/webauthn-login/request/webauthn-login-assertion-response.request.ts index 746a0962e86..8f8097d2cb7 100644 --- a/libs/common/src/auth/services/webauthn-login/request/webauthn-login-assertion-response.request.ts +++ b/libs/common/src/auth/services/webauthn-login/request/webauthn-login-assertion-response.request.ts @@ -20,15 +20,16 @@ export class WebAuthnLoginAssertionResponseRequest extends WebAuthnLoginResponse constructor(credential: PublicKeyCredential) { super(credential); - if (!(credential.response instanceof AuthenticatorAssertionResponse)) { - throw new Error("Invalid authenticator response"); - } + // if (!(credential.response instanceof AuthenticatorAssertionResponse)) { + // throw new Error("Invalid authenticator response"); + // } + const resp = credential.response as AuthenticatorAssertionResponse; this.response = { - authenticatorData: Utils.fromBufferToUrlB64(credential.response.authenticatorData), - signature: Utils.fromBufferToUrlB64(credential.response.signature), - clientDataJSON: Utils.fromBufferToUrlB64(credential.response.clientDataJSON), - userHandle: Utils.fromBufferToUrlB64(credential.response.userHandle), + authenticatorData: Utils.fromBufferToUrlB64(resp.authenticatorData), + signature: Utils.fromBufferToUrlB64(resp.signature), + clientDataJSON: Utils.fromBufferToUrlB64((resp as any).clientDataJson), + userHandle: Utils.fromBufferToUrlB64(resp.userHandle), }; } diff --git a/libs/common/src/auth/services/webauthn-login/webauthn-login.service.ts b/libs/common/src/auth/services/webauthn-login/webauthn-login.service.ts index 2d42329d27a..e407453e2f4 100644 --- a/libs/common/src/auth/services/webauthn-login/webauthn-login.service.ts +++ b/libs/common/src/auth/services/webauthn-login/webauthn-login.service.ts @@ -20,10 +20,10 @@ export class WebAuthnLoginService implements WebAuthnLoginServiceAbstraction { constructor( private webAuthnLoginApiService: WebAuthnLoginApiServiceAbstraction, - private loginStrategyService: LoginStrategyServiceAbstraction, - private webAuthnLoginPrfKeyService: WebAuthnLoginPrfKeyServiceAbstraction, + protected loginStrategyService: LoginStrategyServiceAbstraction, + protected webAuthnLoginPrfKeyService: WebAuthnLoginPrfKeyServiceAbstraction, private window: Window, - private logService?: LogService, + protected logService?: LogService, ) { this.navigatorCredentials = this.window.navigator.credentials; }