Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
81330e5d52 | ||
|
|
31774ef316 | ||
|
|
1c6c7a4eae | ||
|
|
078e565ac1 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -2,7 +2,6 @@ fuzz/artifacts
|
||||
fuzz/corpus
|
||||
fuzz/coverage
|
||||
target/
|
||||
Cargo.lock
|
||||
|
||||
# Local installation of elf2tab.
|
||||
/elf2tab/
|
||||
|
||||
789
Cargo.lock
generated
Normal file
789
Cargo.lock
generated
Normal file
@@ -0,0 +1,789 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arbitrary"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db55d72333851e17d572bec876e390cd3b11eb1ef53ae821dd9f3b653d2b4569"
|
||||
dependencies = [
|
||||
"derive_arbitrary",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "cloudabi"
|
||||
version = "0.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"byteorder",
|
||||
"hex",
|
||||
"regex",
|
||||
"ring",
|
||||
"rng256",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"subtle",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctap2"
|
||||
version = "1.0.0"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
"arrayref",
|
||||
"byteorder",
|
||||
"crypto",
|
||||
"ed25519-compact",
|
||||
"embedded-time",
|
||||
"enum-iterator",
|
||||
"lang_items",
|
||||
"libtock_core",
|
||||
"libtock_drivers",
|
||||
"openssl",
|
||||
"persistent_store",
|
||||
"rand 0.8.5",
|
||||
"rng256",
|
||||
"sk-cbor",
|
||||
"subtle",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_arbitrary"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1a012b5e473dc912f0db0546a1c9c6a194ce8494feb66fa0237160926f9e0e6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ed25519-compact"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bee9df587982575886a8682edcee11877894349a805f25629c27f63abe3e9ae8"
|
||||
|
||||
[[package]]
|
||||
name = "embedded-time"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7a4b4d10ac48d08bfe3db7688c402baadb244721f30a77ce360bd24c3dffe58"
|
||||
dependencies = [
|
||||
"num",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "enum-iterator"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c79a6321a1197d7730510c7e3f6cb80432dfefecb32426de8cea0aa19b4bb8d7"
|
||||
dependencies = [
|
||||
"enum-iterator-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "enum-iterator-derive"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e94aa31f7c0dc764f57896dc615ddd76fc13b0d5dca7eb6cc5e018a5a09ec06"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
||||
dependencies = [
|
||||
"foreign-types-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types-shared"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-cprng"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lang_items"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libtock_core",
|
||||
"libtock_drivers",
|
||||
"linked_list_allocator",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.133"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966"
|
||||
|
||||
[[package]]
|
||||
name = "libtock_codegen"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libtock_core"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libtock_codegen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libtock_drivers"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libtock_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linked_list_allocator"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "822add9edb1860698b79522510da17bef885171f75aa395cff099d770c609c24"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "num"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b7a8e9be5e039e2ff869df49155f1c06bd01ade2117ec783e56ab0932b67a8f"
|
||||
dependencies = [
|
||||
"num-complex",
|
||||
"num-integer",
|
||||
"num-iter",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-complex"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "747d632c0c558b87dbabbe6a82f3b4ae03720d0646ac5b7b4dae89394be5f2c5"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-iter"
|
||||
version = "0.1.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "618febf65336490dfcf20b73f885f5651a0c89c64c2d4a8c3662585a70bf5bd0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"openssl-macros",
|
||||
"openssl-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-macros"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.75"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5f9bd0c2710541a3cda73d6f9ac4f1b240de4ae261065d309dbe73d9dceb42f"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "persistent_store"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
|
||||
dependencies = [
|
||||
"autocfg 0.1.8",
|
||||
"libc",
|
||||
"rand_chacha 0.1.1",
|
||||
"rand_core 0.4.2",
|
||||
"rand_hc",
|
||||
"rand_isaac",
|
||||
"rand_jitter",
|
||||
"rand_os",
|
||||
"rand_pcg",
|
||||
"rand_xorshift",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha 0.3.1",
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
|
||||
dependencies = [
|
||||
"autocfg 0.1.8",
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||
dependencies = [
|
||||
"rand_core 0.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_isaac"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_jitter"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_core 0.4.2",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_os"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
|
||||
dependencies = [
|
||||
"cloudabi",
|
||||
"fuchsia-cprng",
|
||||
"libc",
|
||||
"rand_core 0.4.2",
|
||||
"rdrand",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_pcg"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
|
||||
dependencies = [
|
||||
"autocfg 0.1.8",
|
||||
"rand_core 0.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_xorshift"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rdrand"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.16.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"spin",
|
||||
"untrusted",
|
||||
"web-sys",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rng256"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"libtock_drivers",
|
||||
"rand 0.6.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.145"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.145"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e466864e431129c7e0d3476b92f20458e5879919a0596c6472738d9fa2d342f8"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sk-cbor"
|
||||
version = "0.1.2"
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52205623b1b0f064a4e71182c3b18ae902267282930c6d5462c91b859668426e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd"
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
@@ -20,8 +20,6 @@ persistent_store = { path = "libraries/persistent_store" }
|
||||
byteorder = { version = "1", default-features = false }
|
||||
arrayref = "0.3.6"
|
||||
subtle = { version = "2.2", default-features = false, features = ["nightly"] }
|
||||
# This import explicitly locks the version.
|
||||
serde_json = { version = "=1.0.69", default-features = false, features = ["alloc"] }
|
||||
embedded-time = "0.12.1"
|
||||
arbitrary = { version = "0.4.7", features = ["derive"], optional = true }
|
||||
rand = { version = "0.8.4", optional = true }
|
||||
|
||||
282
bootloader/Cargo.lock
generated
Normal file
282
bootloader/Cargo.lock
generated
Normal file
@@ -0,0 +1,282 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aligned"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a785a543aea40f5e4e2e93bb2655d31bc21bb391fff65697150973e383f16bb"
|
||||
dependencies = [
|
||||
"as-slice",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "as-slice"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45403b49e3954a4b8428a0ac21a4b7afadccf92bfd96273f1a58cd4812496ae0"
|
||||
dependencies = [
|
||||
"generic-array 0.12.4",
|
||||
"generic-array 0.13.3",
|
||||
"generic-array 0.14.6",
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bare-metal"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3"
|
||||
dependencies = [
|
||||
"rustc_version",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitfield"
|
||||
version = "0.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719"
|
||||
|
||||
[[package]]
|
||||
name = "bootloader"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"cortex-m 0.6.7",
|
||||
"cortex-m-rt",
|
||||
"cortex-m-rt-macros",
|
||||
"panic-abort",
|
||||
"rtt-target",
|
||||
"tock-registers",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "cortex-m"
|
||||
version = "0.6.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9075300b07c6a56263b9b582c214d0ff037b00d45ec9fde1cc711490c56f1bb9"
|
||||
dependencies = [
|
||||
"aligned",
|
||||
"bare-metal",
|
||||
"bitfield",
|
||||
"cortex-m 0.7.6",
|
||||
"volatile-register",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cortex-m"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70858629a458fdfd39f9675c4dc309411f2a3f83bede76988d81bf1a0ecee9e0"
|
||||
dependencies = [
|
||||
"bare-metal",
|
||||
"bitfield",
|
||||
"embedded-hal",
|
||||
"volatile-register",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cortex-m-rt"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c433da385b720d5bb9f52362fa2782420798e68d40d67bfe4b0d992aba5dfe7"
|
||||
dependencies = [
|
||||
"cortex-m-rt-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cortex-m-rt-macros"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0f6f3e36f203cfedbc78b357fb28730aa2c6dc1ab060ee5c2405e843988d3c7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "embedded-hal"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff"
|
||||
dependencies = [
|
||||
"nb 0.1.3",
|
||||
"void",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.12.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.13.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f797e67af32588215eaaab8327027ee8e71b9dd0b2b26996aedf20c030fce309"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nb"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f"
|
||||
dependencies = [
|
||||
"nb 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nb"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae"
|
||||
|
||||
[[package]]
|
||||
name = "panic-abort"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e20e6499bbbc412f280b04a42346b356c6fa0753d5fd22b7bd752ff34c778ee"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rtt-target"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "065d6058bb1204f51a562a67209e1817cf714759d5cf845aa45c75fa7b0b9d9b"
|
||||
dependencies = [
|
||||
"cortex-m 0.7.6",
|
||||
"ufmt-write",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||
dependencies = [
|
||||
"semver-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52205623b1b0f064a4e71182c3b18ae902267282930c6d5462c91b859668426e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tock-registers"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f521a79accce68c417c9c77ce22108056b626126da1932f7e2e9b5bbffee0cea"
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
|
||||
|
||||
[[package]]
|
||||
name = "ufmt-write"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e87a2ed6b42ec5e28cc3b94c09982969e9227600b2e3dcbc1db927a84c06bd69"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd"
|
||||
|
||||
[[package]]
|
||||
name = "vcell"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "void"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||
|
||||
[[package]]
|
||||
name = "volatile-register"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ee8f19f9d74293faf70901bc20ad067dc1ad390d2cbf1e3f75f721ffee908b6"
|
||||
dependencies = [
|
||||
"vcell",
|
||||
]
|
||||
794
fuzz/Cargo.lock
generated
Normal file
794
fuzz/Cargo.lock
generated
Normal file
@@ -0,0 +1,794 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arbitrary"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db55d72333851e17d572bec876e390cd3b11eb1ef53ae821dd9f3b653d2b4569"
|
||||
dependencies = [
|
||||
"derive_arbitrary",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "cloudabi"
|
||||
version = "0.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"byteorder",
|
||||
"hex",
|
||||
"regex",
|
||||
"ring",
|
||||
"rng256",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"subtle",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctap2"
|
||||
version = "1.0.0"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
"arrayref",
|
||||
"byteorder",
|
||||
"crypto",
|
||||
"embedded-time",
|
||||
"lang_items",
|
||||
"libtock_core",
|
||||
"libtock_drivers",
|
||||
"openssl",
|
||||
"persistent_store",
|
||||
"rand 0.8.5",
|
||||
"rng256",
|
||||
"sk-cbor",
|
||||
"subtle",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctap2-fuzz"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"fuzz_helper",
|
||||
"libfuzzer-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_arbitrary"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1a012b5e473dc912f0db0546a1c9c6a194ce8494feb66fa0237160926f9e0e6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "embedded-time"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7a4b4d10ac48d08bfe3db7688c402baadb244721f30a77ce360bd24c3dffe58"
|
||||
dependencies = [
|
||||
"num",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
||||
dependencies = [
|
||||
"foreign-types-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types-shared"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-cprng"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||
|
||||
[[package]]
|
||||
name = "fuzz_helper"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
"arrayref",
|
||||
"crypto",
|
||||
"ctap2",
|
||||
"embedded-time",
|
||||
"lang_items",
|
||||
"libtock_drivers",
|
||||
"rng256",
|
||||
"sk-cbor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lang_items"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libtock_core",
|
||||
"libtock_drivers",
|
||||
"linked_list_allocator",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.133"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966"
|
||||
|
||||
[[package]]
|
||||
name = "libfuzzer-sys"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcf184a4b6b274f82a5df6b357da6055d3e82272327bba281c28bbba6f1664ef"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libtock_codegen"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libtock_core"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libtock_codegen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libtock_drivers"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libtock_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linked_list_allocator"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "822add9edb1860698b79522510da17bef885171f75aa395cff099d770c609c24"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "num"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b7a8e9be5e039e2ff869df49155f1c06bd01ade2117ec783e56ab0932b67a8f"
|
||||
dependencies = [
|
||||
"num-complex",
|
||||
"num-integer",
|
||||
"num-iter",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-complex"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "747d632c0c558b87dbabbe6a82f3b4ae03720d0646ac5b7b4dae89394be5f2c5"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-iter"
|
||||
version = "0.1.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "618febf65336490dfcf20b73f885f5651a0c89c64c2d4a8c3662585a70bf5bd0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"openssl-macros",
|
||||
"openssl-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-macros"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.75"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5f9bd0c2710541a3cda73d6f9ac4f1b240de4ae261065d309dbe73d9dceb42f"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "persistent_store"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
|
||||
dependencies = [
|
||||
"autocfg 0.1.8",
|
||||
"libc",
|
||||
"rand_chacha 0.1.1",
|
||||
"rand_core 0.4.2",
|
||||
"rand_hc",
|
||||
"rand_isaac",
|
||||
"rand_jitter",
|
||||
"rand_os",
|
||||
"rand_pcg",
|
||||
"rand_xorshift",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha 0.3.1",
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
|
||||
dependencies = [
|
||||
"autocfg 0.1.8",
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||
dependencies = [
|
||||
"rand_core 0.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_isaac"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_jitter"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_core 0.4.2",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_os"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
|
||||
dependencies = [
|
||||
"cloudabi",
|
||||
"fuchsia-cprng",
|
||||
"libc",
|
||||
"rand_core 0.4.2",
|
||||
"rdrand",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_pcg"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
|
||||
dependencies = [
|
||||
"autocfg 0.1.8",
|
||||
"rand_core 0.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_xorshift"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rdrand"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.16.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"spin",
|
||||
"untrusted",
|
||||
"web-sys",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rng256"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"libtock_drivers",
|
||||
"rand 0.6.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.144"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.144"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e466864e431129c7e0d3476b92f20458e5879919a0596c6472738d9fa2d342f8"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sk-cbor"
|
||||
version = "0.1.2"
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52205623b1b0f064a4e71182c3b18ae902267282930c6d5462c91b859668426e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd"
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
@@ -11,8 +11,6 @@ cargo-fuzz = true
|
||||
[dependencies]
|
||||
libfuzzer-sys = { version = "0.3" }
|
||||
fuzz_helper = { path = "fuzz_helper" }
|
||||
# This import explicitly locks the version.
|
||||
serde_json = { version = "=1.0.69" }
|
||||
|
||||
# Prevent this from interfering with workspaces
|
||||
[workspace]
|
||||
|
||||
7
libraries/cbor/Cargo.lock
generated
Normal file
7
libraries/cbor/Cargo.lock
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "sk-cbor"
|
||||
version = "0.1.2"
|
||||
37
libraries/cbor/fuzz/Cargo.lock
generated
Normal file
37
libraries/cbor/fuzz/Cargo.lock
generated
Normal file
@@ -0,0 +1,37 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "arbitrary"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db55d72333851e17d572bec876e390cd3b11eb1ef53ae821dd9f3b653d2b4569"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
|
||||
|
||||
[[package]]
|
||||
name = "libfuzzer-sys"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcf184a4b6b274f82a5df6b357da6055d3e82272327bba281c28bbba6f1664ef"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sk-cbor"
|
||||
version = "0.1.2"
|
||||
|
||||
[[package]]
|
||||
name = "sk-cbor-fuzz"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"libfuzzer-sys",
|
||||
"sk-cbor",
|
||||
]
|
||||
503
libraries/crypto/Cargo.lock
generated
Normal file
503
libraries/crypto/Cargo.lock
generated
Normal file
@@ -0,0 +1,503 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "cloudabi"
|
||||
version = "0.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"byteorder",
|
||||
"hex",
|
||||
"regex",
|
||||
"ring",
|
||||
"rng256",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"subtle",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-cprng"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.133"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966"
|
||||
|
||||
[[package]]
|
||||
name = "libtock_codegen"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libtock_core"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libtock_codegen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libtock_drivers"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libtock_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
|
||||
dependencies = [
|
||||
"autocfg 0.1.8",
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core 0.4.2",
|
||||
"rand_hc",
|
||||
"rand_isaac",
|
||||
"rand_jitter",
|
||||
"rand_os",
|
||||
"rand_pcg",
|
||||
"rand_xorshift",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
|
||||
dependencies = [
|
||||
"autocfg 0.1.8",
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||
dependencies = [
|
||||
"rand_core 0.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_isaac"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_jitter"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_core 0.4.2",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_os"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
|
||||
dependencies = [
|
||||
"cloudabi",
|
||||
"fuchsia-cprng",
|
||||
"libc",
|
||||
"rand_core 0.4.2",
|
||||
"rdrand",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_pcg"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
|
||||
dependencies = [
|
||||
"autocfg 0.1.8",
|
||||
"rand_core 0.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_xorshift"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rdrand"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.16.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"spin",
|
||||
"untrusted",
|
||||
"web-sys",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rng256"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"libtock_drivers",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.144"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.144"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e466864e431129c7e0d3476b92f20458e5879919a0596c6472738d9fa2d342f8"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52205623b1b0f064a4e71182c3b18ae902267282930c6d5462c91b859668426e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd"
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.80"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.80"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.80"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.80"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.80"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
100
libraries/persistent_store/Cargo.lock
generated
Normal file
100
libraries/persistent_store/Cargo.lock
generated
Normal file
@@ -0,0 +1,100 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
|
||||
dependencies = [
|
||||
"instant",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.133"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966"
|
||||
|
||||
[[package]]
|
||||
name = "persistent_store"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "remove_dir_all"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"fastrand",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"remove_dir_all",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
1
libraries/persistent_store/fuzz/.gitignore
vendored
1
libraries/persistent_store/fuzz/.gitignore
vendored
@@ -1,4 +1,3 @@
|
||||
/Cargo.lock
|
||||
/artifacts/
|
||||
/corpus/
|
||||
/target/
|
||||
|
||||
126
libraries/persistent_store/fuzz/Cargo.lock
generated
Normal file
126
libraries/persistent_store/fuzz/Cargo.lock
generated
Normal file
@@ -0,0 +1,126 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "arbitrary"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db55d72333851e17d572bec876e390cd3b11eb1ef53ae821dd9f3b653d2b4569"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
|
||||
|
||||
[[package]]
|
||||
name = "fuzz-store"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"libfuzzer-sys",
|
||||
"persistent_store",
|
||||
"rand_core",
|
||||
"rand_pcg",
|
||||
"strum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libfuzzer-sys"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcf184a4b6b274f82a5df6b357da6055d3e82272327bba281c28bbba6f1664ef"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "persistent_store"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
||||
|
||||
[[package]]
|
||||
name = "rand_pcg"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.19.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b89a286a7e3b5720b9a477b23253bc50debac207c8d21505f8e70b36792f11b5"
|
||||
dependencies = [
|
||||
"strum_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
version = "0.19.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e61bb0be289045cb80bfce000512e32d09f8337e54c186725da381377ad1f8d5"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52205623b1b0f064a4e71182c3b18ae902267282930c6d5462c91b859668426e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a"
|
||||
242
libraries/persistent_store/src/concat.rs
Normal file
242
libraries/persistent_store/src/concat.rs
Normal file
@@ -0,0 +1,242 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Support for concatenated entries.
|
||||
//!
|
||||
//! This module permits to store multiple indexed values under the same key by concatenation. Such
|
||||
//! values must be at most 255 bytes and there can't be more than 255 such values under the same
|
||||
//! key (they are indexed with a `u8`).
|
||||
//!
|
||||
//! The rationale for using those particular constraints is that we want the number of bits to store
|
||||
//! the index and the number of bits to store the length to fit in an integer number of bytes
|
||||
//! (because the values are an integer number of bytes). Using only one byte is too restrictive
|
||||
//! (e.g. 8 values of at most 31 bytes or 16 values of at most 15 bytes). Using 2 bytes is plenty of
|
||||
//! space, so using one byte for each field makes parsing simpler and faster.
|
||||
//!
|
||||
//! The format is thus `(index:u8 length:u8 payload:[u8; length])*`. The concatenation is not
|
||||
//! particularly sorted.
|
||||
|
||||
use crate::{Storage, Store, StoreError, StoreResult};
|
||||
use alloc::vec::Vec;
|
||||
use core::cmp::Ordering;
|
||||
use core::ops::Range;
|
||||
|
||||
/// Reads a value from a concatenated entry.
|
||||
pub fn read(store: &Store<impl Storage>, key: usize, index: u8) -> StoreResult<Option<Vec<u8>>> {
|
||||
let values = match store.find(key)? {
|
||||
None => return Ok(None),
|
||||
Some(x) => x,
|
||||
};
|
||||
Ok(find(&values, index)?.map(|range| values[range].to_vec()))
|
||||
}
|
||||
|
||||
/// Writes a value to a concatenated entry.
|
||||
pub fn write(
|
||||
store: &mut Store<impl Storage>,
|
||||
key: usize,
|
||||
index: u8,
|
||||
value: &[u8],
|
||||
) -> StoreResult<()> {
|
||||
if value.len() > 255 {
|
||||
return Err(StoreError::InvalidArgument);
|
||||
}
|
||||
let mut values = store.find(key)?.unwrap_or(vec![]);
|
||||
match find(&values, index)? {
|
||||
None => {
|
||||
values.push(index);
|
||||
values.push(value.len() as u8);
|
||||
values.extend_from_slice(value);
|
||||
}
|
||||
Some(mut range) => {
|
||||
values[range.start - 1] = value.len() as u8;
|
||||
match range.len().cmp(&value.len()) {
|
||||
Ordering::Less => {
|
||||
let diff = value.len() - range.len();
|
||||
values.resize(values.len() + diff, 0);
|
||||
values[range.end..].rotate_right(diff);
|
||||
range.end += diff;
|
||||
}
|
||||
Ordering::Equal => (),
|
||||
Ordering::Greater => {
|
||||
let diff = range.len() - value.len();
|
||||
range.end -= diff;
|
||||
values[range.end..].rotate_left(diff);
|
||||
values.truncate(values.len() - diff);
|
||||
}
|
||||
}
|
||||
values[range].copy_from_slice(value);
|
||||
}
|
||||
}
|
||||
store.insert(key, &values)
|
||||
}
|
||||
|
||||
/// Deletes the value from a concatenated entry.
|
||||
pub fn delete(store: &mut Store<impl Storage>, key: usize, index: u8) -> StoreResult<()> {
|
||||
let mut values = match store.find(key)? {
|
||||
None => return Ok(()),
|
||||
Some(x) => x,
|
||||
};
|
||||
let mut range = match find(&values, index)? {
|
||||
None => return Ok(()),
|
||||
Some(x) => x,
|
||||
};
|
||||
range.start -= 2;
|
||||
values[range.start..].rotate_left(range.len());
|
||||
values.truncate(values.len() - range.len());
|
||||
store.insert(key, &values)
|
||||
}
|
||||
|
||||
fn find(values: &[u8], index: u8) -> StoreResult<Option<Range<usize>>> {
|
||||
let mut pos = 0;
|
||||
while pos < values.len() {
|
||||
if pos == values.len() - 1 {
|
||||
return Err(StoreError::InvalidStorage);
|
||||
}
|
||||
let len = values[pos + 1] as usize;
|
||||
if len > values.len() - 2 || pos > values.len() - 2 - len {
|
||||
return Err(StoreError::InvalidStorage);
|
||||
}
|
||||
if index == values[pos] {
|
||||
return Ok(Some(pos + 2..pos + 2 + len));
|
||||
}
|
||||
pos += 2 + len;
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::test::MINIMAL;
|
||||
|
||||
#[test]
|
||||
fn read_empty_entry() {
|
||||
let store = MINIMAL.new_store();
|
||||
assert_eq!(read(&store, 0, 0), Ok(None));
|
||||
assert_eq!(read(&store, 0, 1), Ok(None));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_missing_value() {
|
||||
let mut store = MINIMAL.new_store();
|
||||
let value = b"\x00\x03foo\x02\x05hello".to_vec();
|
||||
store.insert(0, &value).unwrap();
|
||||
assert_eq!(read(&store, 0, 1), Ok(None));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_existing_value() {
|
||||
let mut store = MINIMAL.new_store();
|
||||
let value = b"\x00\x03foo\x02\x05hello".to_vec();
|
||||
store.insert(0, &value).unwrap();
|
||||
assert_eq!(read(&store, 0, 0), Ok(Some(b"foo".to_vec())));
|
||||
assert_eq!(read(&store, 0, 2), Ok(Some(b"hello".to_vec())));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_invalid_entry_too_long() {
|
||||
let mut store = MINIMAL.new_store();
|
||||
let value = b"\x00\x03foo\x02\x08hello".to_vec();
|
||||
store.insert(0, &value).unwrap();
|
||||
assert_eq!(read(&store, 0, 1), Err(StoreError::InvalidStorage));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_invalid_entry_too_short() {
|
||||
let mut store = MINIMAL.new_store();
|
||||
let value = b"\x00\x03foo\x02".to_vec();
|
||||
store.insert(0, &value).unwrap();
|
||||
assert_eq!(read(&store, 0, 1), Err(StoreError::InvalidStorage));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn write_empty_entry() {
|
||||
let mut store = MINIMAL.new_store();
|
||||
assert_eq!(write(&mut store, 0, 0, b"foo"), Ok(()));
|
||||
assert_eq!(store.find(0), Ok(Some(b"\x00\x03foo".to_vec())));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn write_missing_value() {
|
||||
let mut store = MINIMAL.new_store();
|
||||
let value = b"\x00\x03foo".to_vec();
|
||||
store.insert(0, &value).unwrap();
|
||||
assert_eq!(write(&mut store, 0, 1, b"bar"), Ok(()));
|
||||
assert_eq!(store.find(0), Ok(Some(b"\x00\x03foo\x01\x03bar".to_vec())));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn write_existing_value_same_size() {
|
||||
let mut store = MINIMAL.new_store();
|
||||
let value = b"\x00\x03foo\x02\x05hello".to_vec();
|
||||
store.insert(0, &value).unwrap();
|
||||
assert_eq!(write(&mut store, 0, 0, b"bar"), Ok(()));
|
||||
assert_eq!(
|
||||
store.find(0),
|
||||
Ok(Some(b"\x00\x03bar\x02\x05hello".to_vec()))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn write_existing_value_longer() {
|
||||
let mut store = MINIMAL.new_store();
|
||||
let value = b"\x00\x03foo\x02\x05hello".to_vec();
|
||||
store.insert(0, &value).unwrap();
|
||||
assert_eq!(write(&mut store, 0, 0, b"barrage"), Ok(()));
|
||||
assert_eq!(
|
||||
store.find(0),
|
||||
Ok(Some(b"\x00\x07barrage\x02\x05hello".to_vec()))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn write_existing_value_shorter() {
|
||||
let mut store = MINIMAL.new_store();
|
||||
let value = b"\x00\x08football\x02\x05hello".to_vec();
|
||||
store.insert(0, &value).unwrap();
|
||||
assert_eq!(write(&mut store, 0, 0, b"bar"), Ok(()));
|
||||
assert_eq!(
|
||||
store.find(0),
|
||||
Ok(Some(b"\x00\x03bar\x02\x05hello".to_vec()))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn delete_empty_entry() {
|
||||
let mut store = MINIMAL.new_store();
|
||||
assert_eq!(delete(&mut store, 0, 0), Ok(()));
|
||||
assert_eq!(delete(&mut store, 0, 1), Ok(()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn delete_missing_value() {
|
||||
let mut store = MINIMAL.new_store();
|
||||
let value = b"\x00\x03foo\x02\x05hello".to_vec();
|
||||
store.insert(0, &value).unwrap();
|
||||
assert_eq!(delete(&mut store, 0, 1), Ok(()));
|
||||
assert_eq!(
|
||||
store.find(0),
|
||||
Ok(Some(b"\x00\x03foo\x02\x05hello".to_vec()))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn delete_existing_value() {
|
||||
let mut store = MINIMAL.new_store();
|
||||
let value = b"\x00\x03foo\x02\x05hello".to_vec();
|
||||
store.insert(0, &value).unwrap();
|
||||
assert_eq!(delete(&mut store, 0, 0), Ok(()));
|
||||
assert_eq!(store.find(0), Ok(Some(b"\x02\x05hello".to_vec())));
|
||||
}
|
||||
}
|
||||
@@ -363,6 +363,7 @@ extern crate alloc;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
mod buffer;
|
||||
pub mod concat;
|
||||
#[cfg(feature = "std")]
|
||||
mod driver;
|
||||
#[cfg(feature = "std")]
|
||||
|
||||
255
libraries/rng256/Cargo.lock
generated
Normal file
255
libraries/rng256/Cargo.lock
generated
Normal file
@@ -0,0 +1,255 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "cloudabi"
|
||||
version = "0.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-cprng"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.133"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966"
|
||||
|
||||
[[package]]
|
||||
name = "libtock_codegen"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libtock_core"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libtock_codegen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libtock_drivers"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libtock_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
|
||||
dependencies = [
|
||||
"autocfg 0.1.8",
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core 0.4.2",
|
||||
"rand_hc",
|
||||
"rand_isaac",
|
||||
"rand_jitter",
|
||||
"rand_os",
|
||||
"rand_pcg",
|
||||
"rand_xorshift",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
|
||||
dependencies = [
|
||||
"autocfg 0.1.8",
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||
dependencies = [
|
||||
"rand_core 0.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_isaac"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_jitter"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_core 0.4.2",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_os"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
|
||||
dependencies = [
|
||||
"cloudabi",
|
||||
"fuchsia-cprng",
|
||||
"libc",
|
||||
"rand_core 0.4.2",
|
||||
"rdrand",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_pcg"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
|
||||
dependencies = [
|
||||
"autocfg 0.1.8",
|
||||
"rand_core 0.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_xorshift"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rdrand"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rng256"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"libtock_drivers",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52205623b1b0f064a4e71182c3b18ae902267282930c6d5462c91b859668426e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
@@ -241,6 +241,21 @@ pub trait Customization {
|
||||
/// With P=20 and K=150, we have I=2M which is enough for 500 increments per day
|
||||
/// for 10 years.
|
||||
fn max_supported_resident_keys(&self) -> usize;
|
||||
|
||||
/// Sets the slot count of the multi-PIN feature.
|
||||
///
|
||||
/// # Invariant
|
||||
///
|
||||
/// - The slot count may not:
|
||||
/// - make the storage entries that concatenate data of each slots
|
||||
/// become larger than the storage page size,
|
||||
/// - go over u8, as we only reserve 1 byte for the array index for
|
||||
/// concatenated entries, or
|
||||
/// - exceed the number of keys we reserve for the storage entries
|
||||
/// that use unique keys for each slot.
|
||||
///
|
||||
/// The upper bound of this is currently 8.
|
||||
fn slot_count(&self) -> usize;
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -260,6 +275,7 @@ pub struct CustomizationImpl {
|
||||
pub max_large_blob_array_size: usize,
|
||||
pub max_rp_ids_length: usize,
|
||||
pub max_supported_resident_keys: usize,
|
||||
pub slot_count: usize,
|
||||
}
|
||||
|
||||
pub const DEFAULT_CUSTOMIZATION: CustomizationImpl = CustomizationImpl {
|
||||
@@ -278,6 +294,7 @@ pub const DEFAULT_CUSTOMIZATION: CustomizationImpl = CustomizationImpl {
|
||||
max_large_blob_array_size: 2048,
|
||||
max_rp_ids_length: 8,
|
||||
max_supported_resident_keys: 150,
|
||||
slot_count: 8,
|
||||
};
|
||||
|
||||
impl Customization for CustomizationImpl {
|
||||
@@ -351,6 +368,10 @@ impl Customization for CustomizationImpl {
|
||||
fn max_supported_resident_keys(&self) -> usize {
|
||||
self.max_supported_resident_keys
|
||||
}
|
||||
|
||||
fn slot_count(&self) -> usize {
|
||||
self.slot_count
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
@@ -423,6 +444,11 @@ pub fn is_valid(customization: &impl Customization) -> bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Slot count should be at most 8.
|
||||
if customization.slot_count() > 8 {
|
||||
return false;
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
|
||||
@@ -21,12 +21,13 @@ use super::pin_protocol::{verify_pin_uv_auth_token, PinProtocol, SharedSecret};
|
||||
use super::response::{AuthenticatorClientPinResponse, ResponseData};
|
||||
use super::status_code::Ctap2StatusCode;
|
||||
use super::token_state::PinUvAuthTokenState;
|
||||
use crate::api::customization::Customization;
|
||||
use crate::ctap::storage;
|
||||
use crate::env::Env;
|
||||
use alloc::boxed::Box;
|
||||
use alloc::str;
|
||||
use alloc::string::String;
|
||||
use alloc::vec::Vec;
|
||||
use alloc::{str, vec};
|
||||
use crypto::hmac::hmac_256;
|
||||
use crypto::sha256::Sha256;
|
||||
use crypto::Hash256;
|
||||
@@ -78,6 +79,7 @@ fn decrypt_pin(
|
||||
/// truncated for persistent storage.
|
||||
fn check_and_store_new_pin(
|
||||
env: &mut impl Env,
|
||||
slot_id: usize,
|
||||
shared_secret: &dyn SharedSecret,
|
||||
new_pin_enc: Vec<u8>,
|
||||
) -> Result<(), Ctap2StatusCode> {
|
||||
@@ -90,7 +92,7 @@ fn check_and_store_new_pin(
|
||||
let mut pin_hash = [0u8; PIN_AUTH_LENGTH];
|
||||
pin_hash.copy_from_slice(&Sha256::hash(&pin[..])[..PIN_AUTH_LENGTH]);
|
||||
// The PIN length is always < PIN_PADDED_LENGTH < 256.
|
||||
storage::set_pin(env, &pin_hash, pin_length as u8)?;
|
||||
storage::set_pin(env, slot_id, &pin_hash, pin_length as u8)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -108,16 +110,16 @@ pub enum PinPermission {
|
||||
pub struct ClientPin {
|
||||
pin_protocol_v1: PinProtocol,
|
||||
pin_protocol_v2: PinProtocol,
|
||||
consecutive_pin_mismatches: u8,
|
||||
consecutive_pin_mismatches: Vec<u8>,
|
||||
pin_uv_auth_token_state: PinUvAuthTokenState,
|
||||
}
|
||||
|
||||
impl ClientPin {
|
||||
pub fn new(rng: &mut impl Rng256) -> ClientPin {
|
||||
pub fn new(env: &mut impl Env) -> ClientPin {
|
||||
ClientPin {
|
||||
pin_protocol_v1: PinProtocol::new(rng),
|
||||
pin_protocol_v2: PinProtocol::new(rng),
|
||||
consecutive_pin_mismatches: 0,
|
||||
pin_protocol_v1: PinProtocol::new(env.rng()),
|
||||
pin_protocol_v2: PinProtocol::new(env.rng()),
|
||||
consecutive_pin_mismatches: vec![0; env.customization().slot_count()],
|
||||
pin_uv_auth_token_state: PinUvAuthTokenState::new(),
|
||||
}
|
||||
}
|
||||
@@ -159,16 +161,21 @@ impl ClientPin {
|
||||
fn verify_pin_hash_enc(
|
||||
&mut self,
|
||||
env: &mut impl Env,
|
||||
slot_id: usize,
|
||||
pin_uv_auth_protocol: PinUvAuthProtocol,
|
||||
shared_secret: &dyn SharedSecret,
|
||||
pin_hash_enc: Vec<u8>,
|
||||
) -> Result<(), Ctap2StatusCode> {
|
||||
match storage::pin_hash(env)? {
|
||||
// To prevent out of bounds access in code below.
|
||||
if slot_id >= self.consecutive_pin_mismatches.len() {
|
||||
return Err(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR);
|
||||
}
|
||||
match storage::pin_hash(env, slot_id)? {
|
||||
Some(pin_hash) => {
|
||||
if self.consecutive_pin_mismatches >= 3 {
|
||||
if self.consecutive_pin_mismatches[slot_id] >= 3 {
|
||||
return Err(Ctap2StatusCode::CTAP2_ERR_PIN_AUTH_BLOCKED);
|
||||
}
|
||||
storage::decr_pin_retries(env)?;
|
||||
storage::decr_pin_retries(env, slot_id)?;
|
||||
let pin_hash_dec = shared_secret
|
||||
.decrypt(&pin_hash_enc)
|
||||
.map_err(|_| Ctap2StatusCode::CTAP2_ERR_PIN_INVALID)?;
|
||||
@@ -176,11 +183,11 @@ impl ClientPin {
|
||||
if !bool::from(pin_hash.ct_eq(&pin_hash_dec)) {
|
||||
self.get_mut_pin_protocol(pin_uv_auth_protocol)
|
||||
.regenerate(env.rng());
|
||||
if storage::pin_retries(env)? == 0 {
|
||||
if storage::pin_retries(env, slot_id)? == 0 {
|
||||
return Err(Ctap2StatusCode::CTAP2_ERR_PIN_BLOCKED);
|
||||
}
|
||||
self.consecutive_pin_mismatches += 1;
|
||||
if self.consecutive_pin_mismatches >= 3 {
|
||||
self.consecutive_pin_mismatches[slot_id] += 1;
|
||||
if self.consecutive_pin_mismatches[slot_id] >= 3 {
|
||||
return Err(Ctap2StatusCode::CTAP2_ERR_PIN_AUTH_BLOCKED);
|
||||
}
|
||||
return Err(Ctap2StatusCode::CTAP2_ERR_PIN_INVALID);
|
||||
@@ -189,20 +196,26 @@ impl ClientPin {
|
||||
// This status code is not explicitly mentioned in the specification.
|
||||
None => return Err(Ctap2StatusCode::CTAP2_ERR_PUAT_REQUIRED),
|
||||
}
|
||||
storage::reset_pin_retries(env)?;
|
||||
self.consecutive_pin_mismatches = 0;
|
||||
storage::reset_pin_retries(env, slot_id)?;
|
||||
self.consecutive_pin_mismatches[slot_id] = 0;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn process_get_pin_retries(
|
||||
&self,
|
||||
env: &mut impl Env,
|
||||
_client_pin_params: AuthenticatorClientPinParameters,
|
||||
) -> Result<AuthenticatorClientPinResponse, Ctap2StatusCode> {
|
||||
// TODO: Parse slot_id from params if multi-PIN feature is enabled.
|
||||
let slot_id = 0;
|
||||
if slot_id >= self.consecutive_pin_mismatches.len() {
|
||||
return Err(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR);
|
||||
}
|
||||
Ok(AuthenticatorClientPinResponse {
|
||||
key_agreement: None,
|
||||
pin_uv_auth_token: None,
|
||||
retries: Some(storage::pin_retries(env)? as u64),
|
||||
power_cycle_state: Some(self.consecutive_pin_mismatches >= 3),
|
||||
retries: Some(storage::pin_retries(env, slot_id)? as u64),
|
||||
power_cycle_state: Some(self.consecutive_pin_mismatches[slot_id] >= 3),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -234,18 +247,20 @@ impl ClientPin {
|
||||
new_pin_enc,
|
||||
..
|
||||
} = client_pin_params;
|
||||
// TODO: Parse slot_id from params if multi-PIN feature is enabled.
|
||||
let slot_id = 0;
|
||||
let key_agreement = ok_or_missing(key_agreement)?;
|
||||
let pin_uv_auth_param = ok_or_missing(pin_uv_auth_param)?;
|
||||
let new_pin_enc = ok_or_missing(new_pin_enc)?;
|
||||
|
||||
if storage::pin_hash(env)?.is_some() {
|
||||
if storage::pin_hash(env, slot_id)?.is_some() {
|
||||
return Err(Ctap2StatusCode::CTAP2_ERR_PIN_AUTH_INVALID);
|
||||
}
|
||||
let shared_secret = self.get_shared_secret(pin_uv_auth_protocol, key_agreement)?;
|
||||
shared_secret.verify(&new_pin_enc, &pin_uv_auth_param)?;
|
||||
|
||||
check_and_store_new_pin(env, shared_secret.as_ref(), new_pin_enc)?;
|
||||
storage::reset_pin_retries(env)?;
|
||||
check_and_store_new_pin(env, slot_id, shared_secret.as_ref(), new_pin_enc)?;
|
||||
storage::reset_pin_retries(env, slot_id)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -262,12 +277,14 @@ impl ClientPin {
|
||||
pin_hash_enc,
|
||||
..
|
||||
} = client_pin_params;
|
||||
// TODO: Parse slot_id from params if multi-PIN feature is enabled.
|
||||
let slot_id = 0;
|
||||
let key_agreement = ok_or_missing(key_agreement)?;
|
||||
let pin_uv_auth_param = ok_or_missing(pin_uv_auth_param)?;
|
||||
let new_pin_enc = ok_or_missing(new_pin_enc)?;
|
||||
let pin_hash_enc = ok_or_missing(pin_hash_enc)?;
|
||||
|
||||
if storage::pin_retries(env)? == 0 {
|
||||
if storage::pin_retries(env, slot_id)? == 0 {
|
||||
return Err(Ctap2StatusCode::CTAP2_ERR_PIN_BLOCKED);
|
||||
}
|
||||
let shared_secret = self.get_shared_secret(pin_uv_auth_protocol, key_agreement)?;
|
||||
@@ -276,12 +293,13 @@ impl ClientPin {
|
||||
shared_secret.verify(&auth_param_data, &pin_uv_auth_param)?;
|
||||
self.verify_pin_hash_enc(
|
||||
env,
|
||||
slot_id,
|
||||
pin_uv_auth_protocol,
|
||||
shared_secret.as_ref(),
|
||||
pin_hash_enc,
|
||||
)?;
|
||||
|
||||
check_and_store_new_pin(env, shared_secret.as_ref(), new_pin_enc)?;
|
||||
check_and_store_new_pin(env, slot_id, shared_secret.as_ref(), new_pin_enc)?;
|
||||
self.pin_protocol_v1.reset_pin_uv_auth_token(env.rng());
|
||||
self.pin_protocol_v2.reset_pin_uv_auth_token(env.rng());
|
||||
Ok(())
|
||||
@@ -301,30 +319,33 @@ impl ClientPin {
|
||||
permissions_rp_id,
|
||||
..
|
||||
} = client_pin_params;
|
||||
// TODO: Parse slot_id from params if multi-PIN feature is enabled.
|
||||
let slot_id = 0;
|
||||
let key_agreement = ok_or_missing(key_agreement)?;
|
||||
let pin_hash_enc = ok_or_missing(pin_hash_enc)?;
|
||||
if permissions.is_some() || permissions_rp_id.is_some() {
|
||||
return Err(Ctap2StatusCode::CTAP1_ERR_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
if storage::pin_retries(env)? == 0 {
|
||||
if storage::pin_retries(env, slot_id)? == 0 {
|
||||
return Err(Ctap2StatusCode::CTAP2_ERR_PIN_BLOCKED);
|
||||
}
|
||||
let shared_secret = self.get_shared_secret(pin_uv_auth_protocol, key_agreement)?;
|
||||
self.verify_pin_hash_enc(
|
||||
env,
|
||||
slot_id,
|
||||
pin_uv_auth_protocol,
|
||||
shared_secret.as_ref(),
|
||||
pin_hash_enc,
|
||||
)?;
|
||||
if storage::has_force_pin_change(env)? {
|
||||
if storage::has_force_pin_change(env, slot_id)? {
|
||||
return Err(Ctap2StatusCode::CTAP2_ERR_PIN_INVALID);
|
||||
}
|
||||
|
||||
self.pin_protocol_v1.reset_pin_uv_auth_token(env.rng());
|
||||
self.pin_protocol_v2.reset_pin_uv_auth_token(env.rng());
|
||||
self.pin_uv_auth_token_state
|
||||
.begin_using_pin_uv_auth_token(now);
|
||||
.begin_using_pin_uv_auth_token(now, slot_id);
|
||||
self.pin_uv_auth_token_state.set_default_permissions();
|
||||
let pin_uv_auth_token = shared_secret.encrypt(
|
||||
env.rng(),
|
||||
@@ -391,7 +412,9 @@ impl ClientPin {
|
||||
now: CtapInstant,
|
||||
) -> Result<ResponseData, Ctap2StatusCode> {
|
||||
let response = match client_pin_params.sub_command {
|
||||
ClientPinSubCommand::GetPinRetries => Some(self.process_get_pin_retries(env)?),
|
||||
ClientPinSubCommand::GetPinRetries => {
|
||||
Some(self.process_get_pin_retries(env, client_pin_params)?)
|
||||
}
|
||||
ClientPinSubCommand::GetKeyAgreement => {
|
||||
Some(self.process_get_key_agreement(client_pin_params)?)
|
||||
}
|
||||
@@ -446,7 +469,9 @@ impl ClientPin {
|
||||
self.pin_protocol_v1.reset_pin_uv_auth_token(rng);
|
||||
self.pin_protocol_v2.regenerate(rng);
|
||||
self.pin_protocol_v2.reset_pin_uv_auth_token(rng);
|
||||
self.consecutive_pin_mismatches = 0;
|
||||
for v in &mut self.consecutive_pin_mismatches {
|
||||
*v = 0;
|
||||
}
|
||||
self.pin_uv_auth_token_state.stop_using_pin_uv_auth_token();
|
||||
}
|
||||
|
||||
@@ -555,24 +580,38 @@ impl ClientPin {
|
||||
self.pin_uv_auth_token_state.has_permissions_rp_id(rp_id)
|
||||
}
|
||||
|
||||
/// Get the slot_id_in_use of the current pin_uv_auth_token_state if multi-PIN
|
||||
/// feature is enabled. Otherwise return the default slot (0).
|
||||
pub fn get_slot_id_in_use_or_default(
|
||||
&self,
|
||||
env: &mut impl Env,
|
||||
) -> Result<Option<usize>, Ctap2StatusCode> {
|
||||
if storage::has_multi_pin(env)? {
|
||||
Ok(self.pin_uv_auth_token_state.slot_id_in_use())
|
||||
} else {
|
||||
Ok(Some(0))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub fn new_test(
|
||||
env: &mut impl Env,
|
||||
slot_id: usize,
|
||||
key_agreement_key: crypto::ecdh::SecKey,
|
||||
pin_uv_auth_token: [u8; PIN_TOKEN_LENGTH],
|
||||
pin_uv_auth_protocol: PinUvAuthProtocol,
|
||||
) -> ClientPin {
|
||||
let mut env = crate::env::test::TestEnv::new();
|
||||
let (key_agreement_key_v1, key_agreement_key_v2) = match pin_uv_auth_protocol {
|
||||
PinUvAuthProtocol::V1 => (key_agreement_key, crypto::ecdh::SecKey::gensk(env.rng())),
|
||||
PinUvAuthProtocol::V2 => (crypto::ecdh::SecKey::gensk(env.rng()), key_agreement_key),
|
||||
};
|
||||
let mut pin_uv_auth_token_state = PinUvAuthTokenState::new();
|
||||
pin_uv_auth_token_state.set_permissions(0xFF);
|
||||
pin_uv_auth_token_state.begin_using_pin_uv_auth_token(CtapInstant::new(0));
|
||||
pin_uv_auth_token_state.begin_using_pin_uv_auth_token(CtapInstant::new(0), slot_id);
|
||||
ClientPin {
|
||||
pin_protocol_v1: PinProtocol::new_test(key_agreement_key_v1, pin_uv_auth_token),
|
||||
pin_protocol_v2: PinProtocol::new_test(key_agreement_key_v2, pin_uv_auth_token),
|
||||
consecutive_pin_mismatches: 0,
|
||||
consecutive_pin_mismatches: vec![0; env.customization().slot_count()],
|
||||
pin_uv_auth_token_state,
|
||||
}
|
||||
}
|
||||
@@ -592,7 +631,7 @@ mod test {
|
||||
pin[..4].copy_from_slice(b"1234");
|
||||
let mut pin_hash = [0u8; 16];
|
||||
pin_hash.copy_from_slice(&Sha256::hash(&pin[..])[..16]);
|
||||
storage::set_pin(env, &pin_hash, 4).unwrap();
|
||||
storage::set_pin(env, 0, &pin_hash, 4).unwrap();
|
||||
}
|
||||
|
||||
/// Fails on PINs bigger than 64 bytes.
|
||||
@@ -611,6 +650,7 @@ mod test {
|
||||
/// tests using the wrong combination of PIN protocol and shared secret
|
||||
/// should fail.
|
||||
fn create_client_pin_and_shared_secret(
|
||||
slot_id: usize,
|
||||
pin_uv_auth_protocol: PinUvAuthProtocol,
|
||||
) -> (ClientPin, Box<dyn SharedSecret>) {
|
||||
let mut env = TestEnv::new();
|
||||
@@ -618,8 +658,13 @@ mod test {
|
||||
let pk = key_agreement_key.genpk();
|
||||
let key_agreement = CoseKey::from(pk);
|
||||
let pin_uv_auth_token = [0x91; PIN_TOKEN_LENGTH];
|
||||
let client_pin =
|
||||
ClientPin::new_test(key_agreement_key, pin_uv_auth_token, pin_uv_auth_protocol);
|
||||
let client_pin = ClientPin::new_test(
|
||||
&mut env,
|
||||
slot_id,
|
||||
key_agreement_key,
|
||||
pin_uv_auth_token,
|
||||
pin_uv_auth_protocol,
|
||||
);
|
||||
let shared_secret = client_pin
|
||||
.get_pin_protocol(pin_uv_auth_protocol)
|
||||
.decapsulate(key_agreement, pin_uv_auth_protocol)
|
||||
@@ -635,7 +680,9 @@ mod test {
|
||||
sub_command: ClientPinSubCommand,
|
||||
) -> (ClientPin, AuthenticatorClientPinParameters) {
|
||||
let mut env = TestEnv::new();
|
||||
let (client_pin, shared_secret) = create_client_pin_and_shared_secret(pin_uv_auth_protocol);
|
||||
// TODO: Make slot_id a passed parameter once we include it in AuthenticatorClientPinParameters.
|
||||
let (client_pin, shared_secret) =
|
||||
create_client_pin_and_shared_secret(0, pin_uv_auth_protocol);
|
||||
|
||||
let pin = b"1234";
|
||||
let mut padded_pin = [0u8; 64];
|
||||
@@ -677,7 +724,7 @@ mod test {
|
||||
#[test]
|
||||
fn test_mix_pin_protocols() {
|
||||
let mut env = TestEnv::new();
|
||||
let client_pin = ClientPin::new(env.rng());
|
||||
let client_pin = ClientPin::new(&mut env);
|
||||
let pin_protocol_v1 = client_pin.get_pin_protocol(PinUvAuthProtocol::V1);
|
||||
let pin_protocol_v2 = client_pin.get_pin_protocol(PinUvAuthProtocol::V2);
|
||||
let message = vec![0xAA; 16];
|
||||
@@ -718,7 +765,7 @@ mod test {
|
||||
|
||||
fn test_helper_verify_pin_hash_enc(pin_uv_auth_protocol: PinUvAuthProtocol) {
|
||||
let mut env = TestEnv::new();
|
||||
let mut client_pin = ClientPin::new(env.rng());
|
||||
let mut client_pin = ClientPin::new(&mut env);
|
||||
let pin_protocol = client_pin.get_pin_protocol(pin_uv_auth_protocol);
|
||||
let shared_secret = pin_protocol
|
||||
.decapsulate(pin_protocol.get_public_key(), pin_uv_auth_protocol)
|
||||
@@ -728,7 +775,7 @@ mod test {
|
||||
0x01, 0xD9, 0x88, 0x40, 0x50, 0xBB, 0xD0, 0x7A, 0x23, 0x1A, 0xEB, 0x69, 0xD8, 0x36,
|
||||
0xC4, 0x12,
|
||||
];
|
||||
storage::set_pin(&mut env, &pin_hash, 4).unwrap();
|
||||
storage::set_pin(&mut env, 0, &pin_hash, 4).unwrap();
|
||||
|
||||
let pin_hash_enc = shared_secret
|
||||
.as_ref()
|
||||
@@ -737,6 +784,7 @@ mod test {
|
||||
assert_eq!(
|
||||
client_pin.verify_pin_hash_enc(
|
||||
&mut env,
|
||||
0,
|
||||
pin_uv_auth_protocol,
|
||||
shared_secret.as_ref(),
|
||||
pin_hash_enc
|
||||
@@ -748,6 +796,7 @@ mod test {
|
||||
assert_eq!(
|
||||
client_pin.verify_pin_hash_enc(
|
||||
&mut env,
|
||||
0,
|
||||
pin_uv_auth_protocol,
|
||||
shared_secret.as_ref(),
|
||||
pin_hash_enc
|
||||
@@ -759,22 +808,24 @@ mod test {
|
||||
.as_ref()
|
||||
.encrypt(env.rng(), &pin_hash)
|
||||
.unwrap();
|
||||
client_pin.consecutive_pin_mismatches = 3;
|
||||
client_pin.consecutive_pin_mismatches[0] = 3;
|
||||
assert_eq!(
|
||||
client_pin.verify_pin_hash_enc(
|
||||
&mut env,
|
||||
0,
|
||||
pin_uv_auth_protocol,
|
||||
shared_secret.as_ref(),
|
||||
pin_hash_enc
|
||||
),
|
||||
Err(Ctap2StatusCode::CTAP2_ERR_PIN_AUTH_BLOCKED)
|
||||
);
|
||||
client_pin.consecutive_pin_mismatches = 0;
|
||||
client_pin.consecutive_pin_mismatches[0] = 0;
|
||||
|
||||
let pin_hash_enc = vec![0x77; PIN_AUTH_LENGTH - 1];
|
||||
assert_eq!(
|
||||
client_pin.verify_pin_hash_enc(
|
||||
&mut env,
|
||||
0,
|
||||
pin_uv_auth_protocol,
|
||||
shared_secret.as_ref(),
|
||||
pin_hash_enc
|
||||
@@ -786,6 +837,7 @@ mod test {
|
||||
assert_eq!(
|
||||
client_pin.verify_pin_hash_enc(
|
||||
&mut env,
|
||||
0,
|
||||
pin_uv_auth_protocol,
|
||||
shared_secret.as_ref(),
|
||||
pin_hash_enc
|
||||
@@ -813,7 +865,7 @@ mod test {
|
||||
let expected_response = Some(AuthenticatorClientPinResponse {
|
||||
key_agreement: None,
|
||||
pin_uv_auth_token: None,
|
||||
retries: Some(storage::pin_retries(&mut env).unwrap() as u64),
|
||||
retries: Some(storage::pin_retries(&mut env, 0).unwrap() as u64),
|
||||
power_cycle_state: Some(false),
|
||||
});
|
||||
assert_eq!(
|
||||
@@ -821,11 +873,11 @@ mod test {
|
||||
Ok(ResponseData::AuthenticatorClientPin(expected_response))
|
||||
);
|
||||
|
||||
client_pin.consecutive_pin_mismatches = 3;
|
||||
client_pin.consecutive_pin_mismatches[0] = 3;
|
||||
let expected_response = Some(AuthenticatorClientPinResponse {
|
||||
key_agreement: None,
|
||||
pin_uv_auth_token: None,
|
||||
retries: Some(storage::pin_retries(&mut env).unwrap() as u64),
|
||||
retries: Some(storage::pin_retries(&mut env, 0).unwrap() as u64),
|
||||
power_cycle_state: Some(true),
|
||||
});
|
||||
assert_eq!(
|
||||
@@ -921,8 +973,8 @@ mod test {
|
||||
Err(Ctap2StatusCode::CTAP2_ERR_PIN_AUTH_INVALID)
|
||||
);
|
||||
|
||||
while storage::pin_retries(&mut env).unwrap() > 0 {
|
||||
storage::decr_pin_retries(&mut env).unwrap();
|
||||
while storage::pin_retries(&mut env, 0).unwrap() > 0 {
|
||||
storage::decr_pin_retries(&mut env, 0).unwrap();
|
||||
}
|
||||
assert_eq!(
|
||||
client_pin.process_command(&mut env, params, CtapInstant::new(0)),
|
||||
@@ -1015,7 +1067,7 @@ mod test {
|
||||
let mut env = TestEnv::new();
|
||||
set_standard_pin(&mut env);
|
||||
|
||||
assert_eq!(storage::force_pin_change(&mut env), Ok(()));
|
||||
assert_eq!(storage::force_pin_change(&mut env, 0), Ok(()));
|
||||
assert_eq!(
|
||||
client_pin.process_command(&mut env, params, CtapInstant::new(0)),
|
||||
Err(Ctap2StatusCode::CTAP2_ERR_PIN_INVALID),
|
||||
@@ -1125,7 +1177,7 @@ mod test {
|
||||
let mut env = TestEnv::new();
|
||||
set_standard_pin(&mut env);
|
||||
|
||||
assert_eq!(storage::force_pin_change(&mut env), Ok(()));
|
||||
assert_eq!(storage::force_pin_change(&mut env, 0), Ok(()));
|
||||
assert_eq!(
|
||||
client_pin.process_command(&mut env, params, CtapInstant::new(0)),
|
||||
Err(Ctap2StatusCode::CTAP2_ERR_PIN_INVALID)
|
||||
@@ -1217,17 +1269,17 @@ mod test {
|
||||
),
|
||||
];
|
||||
for (pin, result) in test_cases {
|
||||
let old_pin_hash = storage::pin_hash(&mut env).unwrap();
|
||||
let old_pin_hash = storage::pin_hash(&mut env, 0).unwrap();
|
||||
let new_pin_enc = encrypt_pin(shared_secret.as_ref(), pin);
|
||||
|
||||
assert_eq!(
|
||||
check_and_store_new_pin(&mut env, shared_secret.as_ref(), new_pin_enc),
|
||||
check_and_store_new_pin(&mut env, 0, shared_secret.as_ref(), new_pin_enc),
|
||||
result
|
||||
);
|
||||
if result.is_ok() {
|
||||
assert_ne!(old_pin_hash, storage::pin_hash(&mut env).unwrap());
|
||||
assert_ne!(old_pin_hash, storage::pin_hash(&mut env, 0).unwrap());
|
||||
} else {
|
||||
assert_eq!(old_pin_hash, storage::pin_hash(&mut env).unwrap());
|
||||
assert_eq!(old_pin_hash, storage::pin_hash(&mut env, 0).unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1249,7 +1301,8 @@ mod test {
|
||||
salt: Vec<u8>,
|
||||
) -> Result<Vec<u8>, Ctap2StatusCode> {
|
||||
let mut env = TestEnv::new();
|
||||
let (client_pin, shared_secret) = create_client_pin_and_shared_secret(pin_uv_auth_protocol);
|
||||
let (client_pin, shared_secret) =
|
||||
create_client_pin_and_shared_secret(0, pin_uv_auth_protocol);
|
||||
|
||||
let salt_enc = shared_secret.as_ref().encrypt(env.rng(), &salt).unwrap();
|
||||
let salt_auth = shared_secret.authenticate(&salt_enc);
|
||||
@@ -1267,7 +1320,8 @@ mod test {
|
||||
|
||||
fn test_helper_process_hmac_secret_bad_salt_auth(pin_uv_auth_protocol: PinUvAuthProtocol) {
|
||||
let mut env = TestEnv::new();
|
||||
let (client_pin, shared_secret) = create_client_pin_and_shared_secret(pin_uv_auth_protocol);
|
||||
let (client_pin, shared_secret) =
|
||||
create_client_pin_and_shared_secret(0, pin_uv_auth_protocol);
|
||||
let cred_random = [0xC9; 32];
|
||||
|
||||
let salt_enc = vec![0x01; 32];
|
||||
@@ -1383,7 +1437,7 @@ mod test {
|
||||
#[test]
|
||||
fn test_has_permission() {
|
||||
let mut env = TestEnv::new();
|
||||
let mut client_pin = ClientPin::new(env.rng());
|
||||
let mut client_pin = ClientPin::new(&mut env);
|
||||
client_pin.pin_uv_auth_token_state.set_permissions(0x7F);
|
||||
for permission in PinPermission::into_enum_iter() {
|
||||
assert_eq!(
|
||||
@@ -1407,7 +1461,7 @@ mod test {
|
||||
#[test]
|
||||
fn test_has_no_rp_id_permission() {
|
||||
let mut env = TestEnv::new();
|
||||
let mut client_pin = ClientPin::new(env.rng());
|
||||
let mut client_pin = ClientPin::new(&mut env);
|
||||
assert_eq!(client_pin.has_no_rp_id_permission(), Ok(()));
|
||||
client_pin
|
||||
.pin_uv_auth_token_state
|
||||
@@ -1421,7 +1475,7 @@ mod test {
|
||||
#[test]
|
||||
fn test_has_no_or_rp_id_permission() {
|
||||
let mut env = TestEnv::new();
|
||||
let mut client_pin = ClientPin::new(env.rng());
|
||||
let mut client_pin = ClientPin::new(&mut env);
|
||||
assert_eq!(client_pin.has_no_or_rp_id_permission("example.com"), Ok(()));
|
||||
client_pin
|
||||
.pin_uv_auth_token_state
|
||||
@@ -1436,7 +1490,7 @@ mod test {
|
||||
#[test]
|
||||
fn test_has_no_or_rp_id_hash_permission() {
|
||||
let mut env = TestEnv::new();
|
||||
let mut client_pin = ClientPin::new(env.rng());
|
||||
let mut client_pin = ClientPin::new(&mut env);
|
||||
let rp_id_hash = Sha256::hash(b"example.com");
|
||||
assert_eq!(
|
||||
client_pin.has_no_or_rp_id_hash_permission(&rp_id_hash),
|
||||
@@ -1458,7 +1512,7 @@ mod test {
|
||||
#[test]
|
||||
fn test_ensure_rp_id_permission() {
|
||||
let mut env = TestEnv::new();
|
||||
let mut client_pin = ClientPin::new(env.rng());
|
||||
let mut client_pin = ClientPin::new(&mut env);
|
||||
assert_eq!(client_pin.ensure_rp_id_permission("example.com"), Ok(()));
|
||||
assert_eq!(
|
||||
client_pin
|
||||
@@ -1476,11 +1530,11 @@ mod test {
|
||||
#[test]
|
||||
fn test_verify_pin_uv_auth_token() {
|
||||
let mut env = TestEnv::new();
|
||||
let mut client_pin = ClientPin::new(env.rng());
|
||||
let mut client_pin = ClientPin::new(&mut env);
|
||||
let message = [0xAA];
|
||||
client_pin
|
||||
.pin_uv_auth_token_state
|
||||
.begin_using_pin_uv_auth_token(CtapInstant::new(0));
|
||||
.begin_using_pin_uv_auth_token(CtapInstant::new(0), 0);
|
||||
|
||||
let pin_uv_auth_token_v1 = client_pin
|
||||
.get_pin_protocol(PinUvAuthProtocol::V1)
|
||||
@@ -1497,6 +1551,7 @@ mod test {
|
||||
let pin_uv_auth_param_v2_from_v1_token =
|
||||
authenticate_pin_uv_auth_token(pin_uv_auth_token_v1, &message, PinUvAuthProtocol::V2);
|
||||
|
||||
assert_eq!(client_pin.pin_uv_auth_token_state.slot_id_in_use(), Some(0));
|
||||
assert_eq!(
|
||||
client_pin.verify_pin_uv_auth_token(
|
||||
&message,
|
||||
@@ -1550,7 +1605,7 @@ mod test {
|
||||
#[test]
|
||||
fn test_verify_pin_uv_auth_token_not_in_use() {
|
||||
let mut env = TestEnv::new();
|
||||
let client_pin = ClientPin::new(env.rng());
|
||||
let client_pin = ClientPin::new(&mut env);
|
||||
let message = [0xAA];
|
||||
|
||||
let pin_uv_auth_token_v1 = client_pin
|
||||
@@ -1572,7 +1627,7 @@ mod test {
|
||||
#[test]
|
||||
fn test_reset() {
|
||||
let mut env = TestEnv::new();
|
||||
let mut client_pin = ClientPin::new(env.rng());
|
||||
let mut client_pin = ClientPin::new(&mut env);
|
||||
let public_key_v1 = client_pin.pin_protocol_v1.get_public_key();
|
||||
let public_key_v2 = client_pin.pin_protocol_v2.get_public_key();
|
||||
let token_v1 = *client_pin.pin_protocol_v1.get_pin_uv_auth_token();
|
||||
|
||||
@@ -55,15 +55,21 @@ fn process_set_min_pin_length(
|
||||
if new_min_pin_length < store_min_pin_length {
|
||||
return Err(Ctap2StatusCode::CTAP2_ERR_PIN_POLICY_VIOLATION);
|
||||
}
|
||||
let mut force_change_pin = force_change_pin.unwrap_or(false);
|
||||
if force_change_pin && storage::pin_hash(env)?.is_none() {
|
||||
let force_change_pin = force_change_pin.unwrap_or(false);
|
||||
if force_change_pin && !storage::has_pin(env)? {
|
||||
return Err(Ctap2StatusCode::CTAP2_ERR_PIN_NOT_SET);
|
||||
}
|
||||
if let Some(old_length) = storage::pin_code_point_length(env)? {
|
||||
force_change_pin |= new_min_pin_length > old_length;
|
||||
}
|
||||
if force_change_pin {
|
||||
storage::force_pin_change(env)?;
|
||||
for slot_id in 0..env.customization().slot_count() {
|
||||
if storage::pin_hash(env, slot_id)?.is_none() {
|
||||
continue;
|
||||
}
|
||||
let mut force_change_pin = force_change_pin;
|
||||
if let Some(old_length) = storage::pin_code_point_length(env, slot_id)? {
|
||||
force_change_pin |= new_min_pin_length > old_length;
|
||||
}
|
||||
if force_change_pin {
|
||||
storage::force_pin_change(env, slot_id)?;
|
||||
}
|
||||
}
|
||||
storage::set_min_pin_length(env, new_min_pin_length)?;
|
||||
if let Some(min_pin_length_rp_ids) = min_pin_length_rp_ids {
|
||||
@@ -85,9 +91,13 @@ pub fn process_config(
|
||||
pin_uv_auth_protocol,
|
||||
} = params;
|
||||
|
||||
let slot_id = client_pin.get_slot_id_in_use_or_default(env)?;
|
||||
let enforce_uv =
|
||||
!matches!(sub_command, ConfigSubCommand::ToggleAlwaysUv) && storage::has_always_uv(env)?;
|
||||
if storage::pin_hash(env)?.is_some() || enforce_uv {
|
||||
// If multi-PIN feature is enabled, no PIN is in use, and the command is to turn off alwaysUv,
|
||||
// the PIN check will be skipped here but an OPERATION_DENIED will still be returned later,
|
||||
// which is correct behavior.
|
||||
if (slot_id.is_some() && storage::pin_hash(env, slot_id.unwrap())?.is_some()) || enforce_uv {
|
||||
let pin_uv_auth_param =
|
||||
pin_uv_auth_param.ok_or(Ctap2StatusCode::CTAP2_ERR_PUAT_REQUIRED)?;
|
||||
let pin_uv_auth_protocol =
|
||||
@@ -133,8 +143,13 @@ mod test {
|
||||
let mut env = TestEnv::new();
|
||||
let key_agreement_key = crypto::ecdh::SecKey::gensk(env.rng());
|
||||
let pin_uv_auth_token = [0x55; 32];
|
||||
let mut client_pin =
|
||||
ClientPin::new_test(key_agreement_key, pin_uv_auth_token, PinUvAuthProtocol::V1);
|
||||
let mut client_pin = ClientPin::new_test(
|
||||
&mut env,
|
||||
0,
|
||||
key_agreement_key,
|
||||
pin_uv_auth_token,
|
||||
PinUvAuthProtocol::V1,
|
||||
);
|
||||
|
||||
let config_params = AuthenticatorConfigParameters {
|
||||
sub_command: ConfigSubCommand::EnableEnterpriseAttestation,
|
||||
@@ -160,8 +175,13 @@ mod test {
|
||||
let mut env = TestEnv::new();
|
||||
let key_agreement_key = crypto::ecdh::SecKey::gensk(env.rng());
|
||||
let pin_uv_auth_token = [0x55; 32];
|
||||
let mut client_pin =
|
||||
ClientPin::new_test(key_agreement_key, pin_uv_auth_token, PinUvAuthProtocol::V1);
|
||||
let mut client_pin = ClientPin::new_test(
|
||||
&mut env,
|
||||
0,
|
||||
key_agreement_key,
|
||||
pin_uv_auth_token,
|
||||
PinUvAuthProtocol::V1,
|
||||
);
|
||||
|
||||
let config_params = AuthenticatorConfigParameters {
|
||||
sub_command: ConfigSubCommand::ToggleAlwaysUv,
|
||||
@@ -195,9 +215,14 @@ mod test {
|
||||
let mut env = TestEnv::new();
|
||||
let key_agreement_key = crypto::ecdh::SecKey::gensk(env.rng());
|
||||
let pin_uv_auth_token = [0x55; 32];
|
||||
let mut client_pin =
|
||||
ClientPin::new_test(key_agreement_key, pin_uv_auth_token, pin_uv_auth_protocol);
|
||||
storage::set_pin(&mut env, &[0x88; 16], 4).unwrap();
|
||||
let mut client_pin = ClientPin::new_test(
|
||||
&mut env,
|
||||
0,
|
||||
key_agreement_key,
|
||||
pin_uv_auth_token,
|
||||
pin_uv_auth_protocol,
|
||||
);
|
||||
storage::set_pin(&mut env, 0, &[0x88; 16], 4).unwrap();
|
||||
|
||||
let mut config_data = vec![0xFF; 32];
|
||||
config_data.extend(&[0x0D, ConfigSubCommand::ToggleAlwaysUv as u8]);
|
||||
@@ -265,8 +290,13 @@ mod test {
|
||||
let mut env = TestEnv::new();
|
||||
let key_agreement_key = crypto::ecdh::SecKey::gensk(env.rng());
|
||||
let pin_uv_auth_token = [0x55; 32];
|
||||
let mut client_pin =
|
||||
ClientPin::new_test(key_agreement_key, pin_uv_auth_token, PinUvAuthProtocol::V1);
|
||||
let mut client_pin = ClientPin::new_test(
|
||||
&mut env,
|
||||
0,
|
||||
key_agreement_key,
|
||||
pin_uv_auth_token,
|
||||
PinUvAuthProtocol::V1,
|
||||
);
|
||||
|
||||
// First, increase minimum PIN length from 4 to 6 without PIN auth.
|
||||
let min_pin_length = 6;
|
||||
@@ -277,7 +307,7 @@ mod test {
|
||||
|
||||
// Second, increase minimum PIN length from 6 to 8 with PIN auth.
|
||||
// The stored PIN or its length don't matter since we control the token.
|
||||
storage::set_pin(&mut env, &[0x88; 16], 8).unwrap();
|
||||
storage::set_pin(&mut env, 0, &[0x88; 16], 8).unwrap();
|
||||
let min_pin_length = 8;
|
||||
let mut config_params = create_min_pin_config_params(min_pin_length, None);
|
||||
let pin_uv_auth_param = vec![
|
||||
@@ -309,8 +339,13 @@ mod test {
|
||||
let mut env = TestEnv::new();
|
||||
let key_agreement_key = crypto::ecdh::SecKey::gensk(env.rng());
|
||||
let pin_uv_auth_token = [0x55; 32];
|
||||
let mut client_pin =
|
||||
ClientPin::new_test(key_agreement_key, pin_uv_auth_token, PinUvAuthProtocol::V1);
|
||||
let mut client_pin = ClientPin::new_test(
|
||||
&mut env,
|
||||
0,
|
||||
key_agreement_key,
|
||||
pin_uv_auth_token,
|
||||
PinUvAuthProtocol::V1,
|
||||
);
|
||||
|
||||
// First, set RP IDs without PIN auth.
|
||||
let min_pin_length = 6;
|
||||
@@ -329,7 +364,7 @@ mod test {
|
||||
let min_pin_length = 8;
|
||||
let min_pin_length_rp_ids = vec!["another.example.com".to_string()];
|
||||
// The stored PIN or its length don't matter since we control the token.
|
||||
storage::set_pin(&mut env, &[0x88; 16], 8).unwrap();
|
||||
storage::set_pin(&mut env, 0, &[0x88; 16], 8).unwrap();
|
||||
let mut config_params =
|
||||
create_min_pin_config_params(min_pin_length, Some(min_pin_length_rp_ids.clone()));
|
||||
let pin_uv_auth_param = vec![
|
||||
@@ -385,10 +420,15 @@ mod test {
|
||||
let mut env = TestEnv::new();
|
||||
let key_agreement_key = crypto::ecdh::SecKey::gensk(env.rng());
|
||||
let pin_uv_auth_token = [0x55; 32];
|
||||
let mut client_pin =
|
||||
ClientPin::new_test(key_agreement_key, pin_uv_auth_token, PinUvAuthProtocol::V1);
|
||||
let mut client_pin = ClientPin::new_test(
|
||||
&mut env,
|
||||
0,
|
||||
key_agreement_key,
|
||||
pin_uv_auth_token,
|
||||
PinUvAuthProtocol::V1,
|
||||
);
|
||||
|
||||
storage::set_pin(&mut env, &[0x88; 16], 4).unwrap();
|
||||
storage::set_pin(&mut env, 0, &[0x88; 16], 4).unwrap();
|
||||
// Increase min PIN, force PIN change.
|
||||
let min_pin_length = 6;
|
||||
let mut config_params = create_min_pin_config_params(min_pin_length, None);
|
||||
@@ -400,7 +440,7 @@ mod test {
|
||||
let config_response = process_config(&mut env, &mut client_pin, config_params);
|
||||
assert_eq!(config_response, Ok(ResponseData::AuthenticatorConfig));
|
||||
assert_eq!(storage::min_pin_length(&mut env), Ok(min_pin_length));
|
||||
assert_eq!(storage::has_force_pin_change(&mut env), Ok(true));
|
||||
assert_eq!(storage::has_force_pin_change(&mut env, 0), Ok(true));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -408,10 +448,15 @@ mod test {
|
||||
let mut env = TestEnv::new();
|
||||
let key_agreement_key = crypto::ecdh::SecKey::gensk(env.rng());
|
||||
let pin_uv_auth_token = [0x55; 32];
|
||||
let mut client_pin =
|
||||
ClientPin::new_test(key_agreement_key, pin_uv_auth_token, PinUvAuthProtocol::V1);
|
||||
let mut client_pin = ClientPin::new_test(
|
||||
&mut env,
|
||||
0,
|
||||
key_agreement_key,
|
||||
pin_uv_auth_token,
|
||||
PinUvAuthProtocol::V1,
|
||||
);
|
||||
|
||||
storage::set_pin(&mut env, &[0x88; 16], 4).unwrap();
|
||||
storage::set_pin(&mut env, 0, &[0x88; 16], 4).unwrap();
|
||||
let pin_uv_auth_param = Some(vec![
|
||||
0xE3, 0x74, 0xF4, 0x27, 0xBE, 0x7D, 0x40, 0xB5, 0x71, 0xB6, 0xB4, 0x1A, 0xD2, 0xC1,
|
||||
0x53, 0xD7,
|
||||
@@ -431,7 +476,7 @@ mod test {
|
||||
};
|
||||
let config_response = process_config(&mut env, &mut client_pin, config_params);
|
||||
assert_eq!(config_response, Ok(ResponseData::AuthenticatorConfig));
|
||||
assert_eq!(storage::has_force_pin_change(&mut env), Ok(true));
|
||||
assert_eq!(storage::has_force_pin_change(&mut env, 0), Ok(true));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -439,8 +484,13 @@ mod test {
|
||||
let mut env = TestEnv::new();
|
||||
let key_agreement_key = crypto::ecdh::SecKey::gensk(env.rng());
|
||||
let pin_uv_auth_token = [0x55; 32];
|
||||
let mut client_pin =
|
||||
ClientPin::new_test(key_agreement_key, pin_uv_auth_token, PinUvAuthProtocol::V1);
|
||||
let mut client_pin = ClientPin::new_test(
|
||||
&mut env,
|
||||
0,
|
||||
key_agreement_key,
|
||||
pin_uv_auth_token,
|
||||
PinUvAuthProtocol::V1,
|
||||
);
|
||||
|
||||
let config_params = AuthenticatorConfigParameters {
|
||||
sub_command: ConfigSubCommand::VendorPrototype,
|
||||
|
||||
@@ -19,7 +19,7 @@ use super::data_formats::{
|
||||
use super::status_code::Ctap2StatusCode;
|
||||
use super::{cbor_read, cbor_write};
|
||||
use crate::api::key_store::KeyStore;
|
||||
use crate::ctap::data_formats::{extract_byte_string, extract_map};
|
||||
use crate::ctap::data_formats::{extract_byte_string, extract_map, extract_unsigned};
|
||||
use crate::env::Env;
|
||||
use alloc::string::String;
|
||||
use alloc::vec::Vec;
|
||||
@@ -48,6 +48,7 @@ struct CredentialSource {
|
||||
rp_id_hash: [u8; 32],
|
||||
cred_protect_policy: Option<CredentialProtectionPolicy>,
|
||||
cred_blob: Option<Vec<u8>>,
|
||||
slot_id: Option<usize>,
|
||||
}
|
||||
|
||||
// The data fields contained in the credential ID are serialized using CBOR maps.
|
||||
@@ -57,6 +58,7 @@ enum CredentialSourceField {
|
||||
RpIdHash = 1,
|
||||
CredProtectPolicy = 2,
|
||||
CredBlob = 3,
|
||||
SlotId = 4,
|
||||
}
|
||||
|
||||
impl From<CredentialSourceField> for sk_cbor::Value {
|
||||
@@ -84,6 +86,7 @@ fn decrypt_legacy_credential_id(
|
||||
rp_id_hash: plaintext[32..64].try_into().unwrap(),
|
||||
cred_protect_policy: None,
|
||||
cred_blob: None,
|
||||
slot_id: None,
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -102,6 +105,7 @@ fn decrypt_cbor_credential_id(
|
||||
CredentialSourceField::RpIdHash=> rp_id_hash,
|
||||
CredentialSourceField::CredProtectPolicy => cred_protect_policy,
|
||||
CredentialSourceField::CredBlob => cred_blob,
|
||||
CredentialSourceField::SlotId => slot_id,
|
||||
} = extract_map(cbor_credential_source)?;
|
||||
}
|
||||
Ok(match (private_key, rp_id_hash) {
|
||||
@@ -115,11 +119,19 @@ fn decrypt_cbor_credential_id(
|
||||
.map(CredentialProtectionPolicy::try_from)
|
||||
.transpose()?;
|
||||
let cred_blob = cred_blob.map(extract_byte_string).transpose()?;
|
||||
let slot_id = match slot_id.map(extract_unsigned).transpose()? {
|
||||
Some(x) => Some(
|
||||
usize::try_from(x)
|
||||
.map_err(|_| Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR)?,
|
||||
),
|
||||
None => None,
|
||||
};
|
||||
Some(CredentialSource {
|
||||
private_key,
|
||||
rp_id_hash: rp_id_hash.try_into().unwrap(),
|
||||
cred_protect_policy,
|
||||
cred_blob,
|
||||
slot_id,
|
||||
})
|
||||
}
|
||||
_ => None,
|
||||
@@ -167,6 +179,7 @@ pub fn encrypt_to_credential_id(
|
||||
rp_id_hash: &[u8; 32],
|
||||
cred_protect_policy: Option<CredentialProtectionPolicy>,
|
||||
cred_blob: Option<Vec<u8>>,
|
||||
slot_id: usize,
|
||||
) -> Result<Vec<u8>, Ctap2StatusCode> {
|
||||
let mut payload = Vec::new();
|
||||
let cbor = cbor_map_options! {
|
||||
@@ -174,6 +187,7 @@ pub fn encrypt_to_credential_id(
|
||||
CredentialSourceField::RpIdHash=> rp_id_hash,
|
||||
CredentialSourceField::CredProtectPolicy => cred_protect_policy,
|
||||
CredentialSourceField::CredBlob => cred_blob,
|
||||
CredentialSourceField::SlotId => slot_id as u64,
|
||||
};
|
||||
cbor_write(cbor, &mut payload)?;
|
||||
add_padding(&mut payload)?;
|
||||
@@ -262,6 +276,7 @@ pub fn decrypt_credential_id(
|
||||
user_icon: None,
|
||||
cred_blob: credential_source.cred_blob,
|
||||
large_blob_key: None,
|
||||
slot_id: credential_source.slot_id,
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -282,7 +297,7 @@ mod test {
|
||||
|
||||
let rp_id_hash = [0x55; 32];
|
||||
let encrypted_id =
|
||||
encrypt_to_credential_id(&mut env, &private_key, &rp_id_hash, None, None).unwrap();
|
||||
encrypt_to_credential_id(&mut env, &private_key, &rp_id_hash, None, None, 0).unwrap();
|
||||
let decrypted_source = decrypt_credential_id(&mut env, encrypted_id, &rp_id_hash)
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
@@ -308,7 +323,7 @@ mod test {
|
||||
|
||||
let rp_id_hash = [0x55; 32];
|
||||
let mut encrypted_id =
|
||||
encrypt_to_credential_id(&mut env, &private_key, &rp_id_hash, None, None).unwrap();
|
||||
encrypt_to_credential_id(&mut env, &private_key, &rp_id_hash, None, None, 0).unwrap();
|
||||
encrypted_id[0] = UNSUPPORTED_CREDENTIAL_ID_VERSION;
|
||||
// Override the HMAC to pass the check.
|
||||
encrypted_id.truncate(&encrypted_id.len() - 32);
|
||||
@@ -328,7 +343,7 @@ mod test {
|
||||
|
||||
let rp_id_hash = [0x55; 32];
|
||||
let encrypted_id =
|
||||
encrypt_to_credential_id(&mut env, &private_key, &rp_id_hash, None, None).unwrap();
|
||||
encrypt_to_credential_id(&mut env, &private_key, &rp_id_hash, None, None, 0).unwrap();
|
||||
for i in 0..encrypted_id.len() {
|
||||
let mut modified_id = encrypted_id.clone();
|
||||
modified_id[i] ^= 0x01;
|
||||
@@ -356,7 +371,7 @@ mod test {
|
||||
|
||||
let rp_id_hash = [0x55; 32];
|
||||
let encrypted_id =
|
||||
encrypt_to_credential_id(&mut env, &private_key, &rp_id_hash, None, None).unwrap();
|
||||
encrypt_to_credential_id(&mut env, &private_key, &rp_id_hash, None, None, 0).unwrap();
|
||||
|
||||
for length in (1..CBOR_CREDENTIAL_ID_SIZE).step_by(16) {
|
||||
assert_eq!(
|
||||
@@ -423,7 +438,7 @@ mod test {
|
||||
|
||||
let rp_id_hash = [0x55; 32];
|
||||
let encrypted_id =
|
||||
encrypt_to_credential_id(&mut env, &private_key, &rp_id_hash, None, None).unwrap();
|
||||
encrypt_to_credential_id(&mut env, &private_key, &rp_id_hash, None, None, 0).unwrap();
|
||||
assert_eq!(encrypted_id.len(), CBOR_CREDENTIAL_ID_SIZE);
|
||||
}
|
||||
|
||||
@@ -444,6 +459,7 @@ mod test {
|
||||
&rp_id_hash,
|
||||
cred_protect_policy,
|
||||
cred_blob,
|
||||
0,
|
||||
);
|
||||
|
||||
assert!(encrypted_id.is_ok());
|
||||
@@ -461,6 +477,7 @@ mod test {
|
||||
&rp_id_hash,
|
||||
Some(CredentialProtectionPolicy::UserVerificationRequired),
|
||||
None,
|
||||
0,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -481,9 +498,15 @@ mod test {
|
||||
|
||||
let rp_id_hash = [0x55; 32];
|
||||
let cred_blob = Some(vec![0x55; env.customization().max_cred_blob_length()]);
|
||||
let encrypted_id =
|
||||
encrypt_to_credential_id(&mut env, &private_key, &rp_id_hash, None, cred_blob.clone())
|
||||
.unwrap();
|
||||
let encrypted_id = encrypt_to_credential_id(
|
||||
&mut env,
|
||||
&private_key,
|
||||
&rp_id_hash,
|
||||
None,
|
||||
cred_blob.clone(),
|
||||
0,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let decrypted_source = decrypt_credential_id(&mut env, encrypted_id, &rp_id_hash)
|
||||
.unwrap()
|
||||
@@ -491,4 +514,22 @@ mod test {
|
||||
assert_eq!(decrypted_source.private_key, private_key);
|
||||
assert_eq!(decrypted_source.cred_blob, cred_blob);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_slot_id_persisted() {
|
||||
let mut env = TestEnv::new();
|
||||
let private_key = PrivateKey::new(&mut env, SignatureAlgorithm::Es256);
|
||||
|
||||
let rp_id_hash = [0x55; 32];
|
||||
let slot_id = 1;
|
||||
let encrypted_id =
|
||||
encrypt_to_credential_id(&mut env, &private_key, &rp_id_hash, None, None, slot_id)
|
||||
.unwrap();
|
||||
|
||||
let decrypted_source = decrypt_credential_id(&mut env, encrypted_id, &rp_id_hash)
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
assert_eq!(decrypted_source.private_key, private_key);
|
||||
assert_eq!(decrypted_source.slot_id, Some(slot_id));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,6 +81,7 @@ fn enumerate_credentials_response(
|
||||
user_icon,
|
||||
cred_blob: _,
|
||||
large_blob_key,
|
||||
slot_id: _,
|
||||
} = credential;
|
||||
let user = PublicKeyCredentialUserEntity {
|
||||
user_id: user_handle,
|
||||
@@ -183,12 +184,17 @@ fn process_enumerate_credentials_begin(
|
||||
.rp_id_hash
|
||||
.ok_or(Ctap2StatusCode::CTAP2_ERR_MISSING_PARAMETER)?;
|
||||
client_pin.has_no_or_rp_id_hash_permission(&rp_id_hash[..])?;
|
||||
// enumerateCredentials needs UV, so slot_id must not be None.
|
||||
let slot_id = client_pin
|
||||
.get_slot_id_in_use_or_default(env)?
|
||||
.ok_or(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR)?;
|
||||
let mut iter_result = Ok(());
|
||||
let iter = storage::iter_credentials(env, &mut iter_result)?;
|
||||
let mut rp_credentials: Vec<usize> = iter
|
||||
.filter_map(|(key, credential)| {
|
||||
let cred_rp_id_hash = Sha256::hash(credential.rp_id.as_bytes());
|
||||
if cred_rp_id_hash == rp_id_hash.as_slice() {
|
||||
let slot_id_matches = credential.slot_id.unwrap_or(0) == slot_id;
|
||||
if cred_rp_id_hash == rp_id_hash.as_slice() && slot_id_matches {
|
||||
Some(key)
|
||||
} else {
|
||||
None
|
||||
@@ -385,6 +391,7 @@ mod test {
|
||||
user_icon: Some("icon".to_string()),
|
||||
cred_blob: None,
|
||||
large_blob_key: None,
|
||||
slot_id: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -392,14 +399,19 @@ mod test {
|
||||
let mut env = TestEnv::new();
|
||||
let key_agreement_key = crypto::ecdh::SecKey::gensk(env.rng());
|
||||
let pin_uv_auth_token = [0x55; 32];
|
||||
let client_pin =
|
||||
ClientPin::new_test(key_agreement_key, pin_uv_auth_token, pin_uv_auth_protocol);
|
||||
let client_pin = ClientPin::new_test(
|
||||
&mut env,
|
||||
0,
|
||||
key_agreement_key,
|
||||
pin_uv_auth_token,
|
||||
pin_uv_auth_protocol,
|
||||
);
|
||||
let credential_source = create_credential_source(&mut env);
|
||||
|
||||
let mut ctap_state = CtapState::new(&mut env, CtapInstant::new(0));
|
||||
ctap_state.client_pin = client_pin;
|
||||
|
||||
storage::set_pin(&mut env, &[0u8; 16], 4).unwrap();
|
||||
storage::set_pin(&mut env, 0, &[0u8; 16], 4).unwrap();
|
||||
let management_data = vec![CredentialManagementSubCommand::GetCredsMetadata as u8];
|
||||
let pin_uv_auth_param = authenticate_pin_uv_auth_token(
|
||||
&pin_uv_auth_token,
|
||||
@@ -474,8 +486,13 @@ mod test {
|
||||
let mut env = TestEnv::new();
|
||||
let key_agreement_key = crypto::ecdh::SecKey::gensk(env.rng());
|
||||
let pin_uv_auth_token = [0x55; 32];
|
||||
let client_pin =
|
||||
ClientPin::new_test(key_agreement_key, pin_uv_auth_token, PinUvAuthProtocol::V1);
|
||||
let client_pin = ClientPin::new_test(
|
||||
&mut env,
|
||||
0,
|
||||
key_agreement_key,
|
||||
pin_uv_auth_token,
|
||||
PinUvAuthProtocol::V1,
|
||||
);
|
||||
let credential_source1 = create_credential_source(&mut env);
|
||||
let mut credential_source2 = create_credential_source(&mut env);
|
||||
credential_source2.rp_id = "another.example.com".to_string();
|
||||
@@ -486,7 +503,7 @@ mod test {
|
||||
storage::store_credential(&mut env, credential_source1).unwrap();
|
||||
storage::store_credential(&mut env, credential_source2).unwrap();
|
||||
|
||||
storage::set_pin(&mut env, &[0u8; 16], 4).unwrap();
|
||||
storage::set_pin(&mut env, 0, &[0u8; 16], 4).unwrap();
|
||||
let pin_uv_auth_param = Some(vec![
|
||||
0x1A, 0xA4, 0x96, 0xDA, 0x62, 0x80, 0x28, 0x13, 0xEB, 0x32, 0xB9, 0xF1, 0xD2, 0xA9,
|
||||
0xD0, 0xD1,
|
||||
@@ -568,8 +585,13 @@ mod test {
|
||||
let mut env = TestEnv::new();
|
||||
let key_agreement_key = crypto::ecdh::SecKey::gensk(env.rng());
|
||||
let pin_uv_auth_token = [0x55; 32];
|
||||
let client_pin =
|
||||
ClientPin::new_test(key_agreement_key, pin_uv_auth_token, PinUvAuthProtocol::V1);
|
||||
let client_pin = ClientPin::new_test(
|
||||
&mut env,
|
||||
0,
|
||||
key_agreement_key,
|
||||
pin_uv_auth_token,
|
||||
PinUvAuthProtocol::V1,
|
||||
);
|
||||
let credential_source = create_credential_source(&mut env);
|
||||
|
||||
let mut ctap_state = CtapState::new(&mut env, CtapInstant::new(0));
|
||||
@@ -582,7 +604,7 @@ mod test {
|
||||
storage::store_credential(&mut env, credential).unwrap();
|
||||
}
|
||||
|
||||
storage::set_pin(&mut env, &[0u8; 16], 4).unwrap();
|
||||
storage::set_pin(&mut env, 0, &[0u8; 16], 4).unwrap();
|
||||
let pin_uv_auth_param = Some(vec![
|
||||
0x1A, 0xA4, 0x96, 0xDA, 0x62, 0x80, 0x28, 0x13, 0xEB, 0x32, 0xB9, 0xF1, 0xD2, 0xA9,
|
||||
0xD0, 0xD1,
|
||||
@@ -649,8 +671,13 @@ mod test {
|
||||
let mut env = TestEnv::new();
|
||||
let key_agreement_key = crypto::ecdh::SecKey::gensk(env.rng());
|
||||
let pin_uv_auth_token = [0x55; 32];
|
||||
let client_pin =
|
||||
ClientPin::new_test(key_agreement_key, pin_uv_auth_token, PinUvAuthProtocol::V1);
|
||||
let client_pin = ClientPin::new_test(
|
||||
&mut env,
|
||||
0,
|
||||
key_agreement_key,
|
||||
pin_uv_auth_token,
|
||||
PinUvAuthProtocol::V1,
|
||||
);
|
||||
let credential_source1 = create_credential_source(&mut env);
|
||||
let mut credential_source2 = create_credential_source(&mut env);
|
||||
credential_source2.user_handle = vec![0x02];
|
||||
@@ -664,7 +691,7 @@ mod test {
|
||||
storage::store_credential(&mut env, credential_source1).unwrap();
|
||||
storage::store_credential(&mut env, credential_source2).unwrap();
|
||||
|
||||
storage::set_pin(&mut env, &[0u8; 16], 4).unwrap();
|
||||
storage::set_pin(&mut env, 0, &[0u8; 16], 4).unwrap();
|
||||
let pin_uv_auth_param = Some(vec![
|
||||
0xF8, 0xB0, 0x3C, 0xC1, 0xD5, 0x58, 0x9C, 0xB7, 0x4D, 0x42, 0xA1, 0x64, 0x14, 0x28,
|
||||
0x2B, 0x68,
|
||||
@@ -746,13 +773,132 @@ mod test {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_process_enumerate_credentials_multi_pin() {
|
||||
let mut env = TestEnv::new();
|
||||
storage::_enable_multi_pin_for_test(&mut env).unwrap();
|
||||
let key_agreement_key = crypto::ecdh::SecKey::gensk(env.rng());
|
||||
let pin_uv_auth_token = [0x55; 32];
|
||||
let client_pin = ClientPin::new_test(
|
||||
&mut env,
|
||||
1,
|
||||
key_agreement_key,
|
||||
pin_uv_auth_token,
|
||||
PinUvAuthProtocol::V1,
|
||||
);
|
||||
|
||||
// credential_source1 has no slot_id, so should be treated as slot 0. Only credential_source 2 and 4
|
||||
// should be discovered.
|
||||
let credential_source1 = create_credential_source(&mut env);
|
||||
let mut credential_source2 = create_credential_source(&mut env);
|
||||
credential_source2.user_handle = vec![0x02];
|
||||
credential_source2.slot_id = Some(1);
|
||||
let mut credential_source3 = create_credential_source(&mut env);
|
||||
credential_source3.user_handle = vec![0x03];
|
||||
credential_source3.slot_id = Some(2);
|
||||
let mut credential_source4 = create_credential_source(&mut env);
|
||||
credential_source4.user_handle = vec![0x04];
|
||||
credential_source4.slot_id = Some(1);
|
||||
|
||||
let mut ctap_state = CtapState::new(&mut env, CtapInstant::new(0));
|
||||
ctap_state.client_pin = client_pin;
|
||||
|
||||
storage::store_credential(&mut env, credential_source1).unwrap();
|
||||
storage::store_credential(&mut env, credential_source2).unwrap();
|
||||
storage::store_credential(&mut env, credential_source3).unwrap();
|
||||
storage::store_credential(&mut env, credential_source4).unwrap();
|
||||
|
||||
storage::set_pin(&mut env, 1, &[0u8; 16], 4).unwrap();
|
||||
let pin_uv_auth_param = Some(vec![
|
||||
0xF8, 0xB0, 0x3C, 0xC1, 0xD5, 0x58, 0x9C, 0xB7, 0x4D, 0x42, 0xA1, 0x64, 0x14, 0x28,
|
||||
0x2B, 0x68,
|
||||
]);
|
||||
|
||||
let sub_command_params = CredentialManagementSubCommandParameters {
|
||||
rp_id_hash: Some(Sha256::hash(b"example.com").to_vec()),
|
||||
credential_id: None,
|
||||
user: None,
|
||||
};
|
||||
// RP ID hash:
|
||||
// A379A6F6EEAFB9A55E378C118034E2751E682FAB9F2D30AB13D2125586CE1947
|
||||
let cred_management_params = AuthenticatorCredentialManagementParameters {
|
||||
sub_command: CredentialManagementSubCommand::EnumerateCredentialsBegin,
|
||||
sub_command_params: Some(sub_command_params),
|
||||
pin_uv_auth_protocol: Some(PinUvAuthProtocol::V1),
|
||||
pin_uv_auth_param,
|
||||
};
|
||||
let cred_management_response = process_credential_management(
|
||||
&mut env,
|
||||
&mut ctap_state.stateful_command_permission,
|
||||
&mut ctap_state.client_pin,
|
||||
cred_management_params,
|
||||
DUMMY_CHANNEL,
|
||||
CtapInstant::new(0),
|
||||
);
|
||||
match cred_management_response.unwrap() {
|
||||
ResponseData::AuthenticatorCredentialManagement(Some(response)) => {
|
||||
assert!(response.user.is_some());
|
||||
assert!(response.public_key.is_some());
|
||||
assert_eq!(response.total_credentials, Some(2));
|
||||
}
|
||||
_ => panic!("Invalid response type"),
|
||||
};
|
||||
|
||||
let cred_management_params = AuthenticatorCredentialManagementParameters {
|
||||
sub_command: CredentialManagementSubCommand::EnumerateCredentialsGetNextCredential,
|
||||
sub_command_params: None,
|
||||
pin_uv_auth_protocol: None,
|
||||
pin_uv_auth_param: None,
|
||||
};
|
||||
let cred_management_response = process_credential_management(
|
||||
&mut env,
|
||||
&mut ctap_state.stateful_command_permission,
|
||||
&mut ctap_state.client_pin,
|
||||
cred_management_params,
|
||||
DUMMY_CHANNEL,
|
||||
CtapInstant::new(0),
|
||||
);
|
||||
match cred_management_response.unwrap() {
|
||||
ResponseData::AuthenticatorCredentialManagement(Some(response)) => {
|
||||
assert!(response.user.is_some());
|
||||
assert!(response.public_key.is_some());
|
||||
assert_eq!(response.total_credentials, None);
|
||||
}
|
||||
_ => panic!("Invalid response type"),
|
||||
};
|
||||
|
||||
let cred_management_params = AuthenticatorCredentialManagementParameters {
|
||||
sub_command: CredentialManagementSubCommand::EnumerateCredentialsGetNextCredential,
|
||||
sub_command_params: None,
|
||||
pin_uv_auth_protocol: None,
|
||||
pin_uv_auth_param: None,
|
||||
};
|
||||
let cred_management_response = process_credential_management(
|
||||
&mut env,
|
||||
&mut ctap_state.stateful_command_permission,
|
||||
&mut ctap_state.client_pin,
|
||||
cred_management_params,
|
||||
DUMMY_CHANNEL,
|
||||
CtapInstant::new(0),
|
||||
);
|
||||
assert_eq!(
|
||||
cred_management_response,
|
||||
Err(Ctap2StatusCode::CTAP2_ERR_NOT_ALLOWED)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_process_delete_credential() {
|
||||
let mut env = TestEnv::new();
|
||||
let key_agreement_key = crypto::ecdh::SecKey::gensk(env.rng());
|
||||
let pin_uv_auth_token = [0x55; 32];
|
||||
let client_pin =
|
||||
ClientPin::new_test(key_agreement_key, pin_uv_auth_token, PinUvAuthProtocol::V1);
|
||||
let client_pin = ClientPin::new_test(
|
||||
&mut env,
|
||||
0,
|
||||
key_agreement_key,
|
||||
pin_uv_auth_token,
|
||||
PinUvAuthProtocol::V1,
|
||||
);
|
||||
let mut credential_source = create_credential_source(&mut env);
|
||||
credential_source.credential_id = vec![0x1D; 32];
|
||||
|
||||
@@ -761,7 +907,7 @@ mod test {
|
||||
|
||||
storage::store_credential(&mut env, credential_source).unwrap();
|
||||
|
||||
storage::set_pin(&mut env, &[0u8; 16], 4).unwrap();
|
||||
storage::set_pin(&mut env, 0, &[0u8; 16], 4).unwrap();
|
||||
let pin_uv_auth_param = Some(vec![
|
||||
0xBD, 0xE3, 0xEF, 0x8A, 0x77, 0x01, 0xB1, 0x69, 0x19, 0xE6, 0x62, 0xB9, 0x9B, 0x89,
|
||||
0x9C, 0x64,
|
||||
@@ -821,8 +967,13 @@ mod test {
|
||||
let mut env = TestEnv::new();
|
||||
let key_agreement_key = crypto::ecdh::SecKey::gensk(env.rng());
|
||||
let pin_uv_auth_token = [0x55; 32];
|
||||
let client_pin =
|
||||
ClientPin::new_test(key_agreement_key, pin_uv_auth_token, PinUvAuthProtocol::V1);
|
||||
let client_pin = ClientPin::new_test(
|
||||
&mut env,
|
||||
0,
|
||||
key_agreement_key,
|
||||
pin_uv_auth_token,
|
||||
PinUvAuthProtocol::V1,
|
||||
);
|
||||
let mut credential_source = create_credential_source(&mut env);
|
||||
credential_source.credential_id = vec![0x1D; 32];
|
||||
|
||||
@@ -831,7 +982,7 @@ mod test {
|
||||
|
||||
storage::store_credential(&mut env, credential_source).unwrap();
|
||||
|
||||
storage::set_pin(&mut env, &[0u8; 16], 4).unwrap();
|
||||
storage::set_pin(&mut env, 0, &[0u8; 16], 4).unwrap();
|
||||
let pin_uv_auth_param = Some(vec![
|
||||
0xA5, 0x55, 0x8F, 0x03, 0xC3, 0xD3, 0x73, 0x1C, 0x07, 0xDA, 0x1F, 0x8C, 0xC7, 0xBD,
|
||||
0x9D, 0xB7,
|
||||
@@ -889,7 +1040,7 @@ mod test {
|
||||
let mut env = TestEnv::new();
|
||||
let mut ctap_state = CtapState::new(&mut env, CtapInstant::new(0));
|
||||
|
||||
storage::set_pin(&mut env, &[0u8; 16], 4).unwrap();
|
||||
storage::set_pin(&mut env, 0, &[0u8; 16], 4).unwrap();
|
||||
|
||||
let cred_management_params = AuthenticatorCredentialManagementParameters {
|
||||
sub_command: CredentialManagementSubCommand::GetCredsMetadata,
|
||||
|
||||
@@ -249,7 +249,7 @@ impl Ctap1Command {
|
||||
.ecdsa_key(env)
|
||||
.map_err(|_| Ctap1StatusCode::SW_INTERNAL_EXCEPTION)?;
|
||||
let pk = sk.genpk();
|
||||
let key_handle = encrypt_to_credential_id(env, &private_key, &application, None, None)
|
||||
let key_handle = encrypt_to_credential_id(env, &private_key, &application, None, None, 0)
|
||||
.map_err(|_| Ctap1StatusCode::SW_INTERNAL_EXCEPTION)?;
|
||||
if key_handle.len() > 0xFF {
|
||||
// This is just being defensive with unreachable code.
|
||||
@@ -320,11 +320,12 @@ impl Ctap1Command {
|
||||
return Err(Ctap1StatusCode::SW_COND_USE_NOT_SATISFIED);
|
||||
}
|
||||
ctap_state
|
||||
.increment_global_signature_counter(env)
|
||||
.increment_global_signature_counter(env, 0)
|
||||
.map_err(|_| Ctap1StatusCode::SW_WRONG_DATA)?;
|
||||
let mut signature_data = ctap_state
|
||||
.generate_auth_data(
|
||||
env,
|
||||
0,
|
||||
&application,
|
||||
Ctap1Command::USER_PRESENCE_INDICATOR_BYTE,
|
||||
)
|
||||
@@ -498,7 +499,8 @@ mod test {
|
||||
|
||||
let rp_id = "example.com";
|
||||
let application = crypto::sha256::Sha256::hash(rp_id.as_bytes());
|
||||
let key_handle = encrypt_to_credential_id(&mut env, &sk, &application, None, None).unwrap();
|
||||
let key_handle =
|
||||
encrypt_to_credential_id(&mut env, &sk, &application, None, None, 0).unwrap();
|
||||
let message = create_authenticate_message(&application, Ctap1Flags::CheckOnly, &key_handle);
|
||||
|
||||
let response =
|
||||
@@ -516,7 +518,8 @@ mod test {
|
||||
|
||||
let rp_id = "example.com";
|
||||
let application = crypto::sha256::Sha256::hash(rp_id.as_bytes());
|
||||
let key_handle = encrypt_to_credential_id(&mut env, &sk, &application, None, None).unwrap();
|
||||
let key_handle =
|
||||
encrypt_to_credential_id(&mut env, &sk, &application, None, None, 0).unwrap();
|
||||
let application = [0x55; 32];
|
||||
let message = create_authenticate_message(&application, Ctap1Flags::CheckOnly, &key_handle);
|
||||
|
||||
@@ -535,7 +538,8 @@ mod test {
|
||||
|
||||
let rp_id = "example.com";
|
||||
let application = crypto::sha256::Sha256::hash(rp_id.as_bytes());
|
||||
let key_handle = encrypt_to_credential_id(&mut env, &sk, &application, None, None).unwrap();
|
||||
let key_handle =
|
||||
encrypt_to_credential_id(&mut env, &sk, &application, None, None, 0).unwrap();
|
||||
let mut message = create_authenticate_message(
|
||||
&application,
|
||||
Ctap1Flags::DontEnforceUpAndSign,
|
||||
@@ -573,7 +577,8 @@ mod test {
|
||||
|
||||
let rp_id = "example.com";
|
||||
let application = crypto::sha256::Sha256::hash(rp_id.as_bytes());
|
||||
let key_handle = encrypt_to_credential_id(&mut env, &sk, &application, None, None).unwrap();
|
||||
let key_handle =
|
||||
encrypt_to_credential_id(&mut env, &sk, &application, None, None, 0).unwrap();
|
||||
let mut message =
|
||||
create_authenticate_message(&application, Ctap1Flags::CheckOnly, &key_handle);
|
||||
message[0] = 0xEE;
|
||||
@@ -593,7 +598,8 @@ mod test {
|
||||
|
||||
let rp_id = "example.com";
|
||||
let application = crypto::sha256::Sha256::hash(rp_id.as_bytes());
|
||||
let key_handle = encrypt_to_credential_id(&mut env, &sk, &application, None, None).unwrap();
|
||||
let key_handle =
|
||||
encrypt_to_credential_id(&mut env, &sk, &application, None, None, 0).unwrap();
|
||||
let mut message =
|
||||
create_authenticate_message(&application, Ctap1Flags::CheckOnly, &key_handle);
|
||||
message[1] = 0xEE;
|
||||
@@ -613,7 +619,8 @@ mod test {
|
||||
|
||||
let rp_id = "example.com";
|
||||
let application = crypto::sha256::Sha256::hash(rp_id.as_bytes());
|
||||
let key_handle = encrypt_to_credential_id(&mut env, &sk, &application, None, None).unwrap();
|
||||
let key_handle =
|
||||
encrypt_to_credential_id(&mut env, &sk, &application, None, None, 0).unwrap();
|
||||
let mut message =
|
||||
create_authenticate_message(&application, Ctap1Flags::CheckOnly, &key_handle);
|
||||
message[2] = 0xEE;
|
||||
@@ -641,7 +648,8 @@ mod test {
|
||||
|
||||
let rp_id = "example.com";
|
||||
let application = crypto::sha256::Sha256::hash(rp_id.as_bytes());
|
||||
let key_handle = encrypt_to_credential_id(&mut env, &sk, &application, None, None).unwrap();
|
||||
let key_handle =
|
||||
encrypt_to_credential_id(&mut env, &sk, &application, None, None, 0).unwrap();
|
||||
let message =
|
||||
create_authenticate_message(&application, Ctap1Flags::EnforceUpAndSign, &key_handle);
|
||||
|
||||
@@ -651,7 +659,7 @@ mod test {
|
||||
Ctap1Command::process_command(&mut env, &message, &mut ctap_state, CtapInstant::new(0))
|
||||
.unwrap();
|
||||
assert_eq!(response[0], 0x01);
|
||||
let global_signature_counter = storage::global_signature_counter(&mut env).unwrap();
|
||||
let global_signature_counter = storage::global_signature_counter(&mut env, 0).unwrap();
|
||||
check_signature_counter(
|
||||
&mut env,
|
||||
array_ref!(response, 1, 4),
|
||||
@@ -669,7 +677,8 @@ mod test {
|
||||
|
||||
let rp_id = "example.com";
|
||||
let application = crypto::sha256::Sha256::hash(rp_id.as_bytes());
|
||||
let key_handle = encrypt_to_credential_id(&mut env, &sk, &application, None, None).unwrap();
|
||||
let key_handle =
|
||||
encrypt_to_credential_id(&mut env, &sk, &application, None, None, 0).unwrap();
|
||||
let message = create_authenticate_message(
|
||||
&application,
|
||||
Ctap1Flags::DontEnforceUpAndSign,
|
||||
@@ -684,7 +693,7 @@ mod test {
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(response[0], 0x01);
|
||||
let global_signature_counter = storage::global_signature_counter(&mut env).unwrap();
|
||||
let global_signature_counter = storage::global_signature_counter(&mut env, 0).unwrap();
|
||||
check_signature_counter(
|
||||
&mut env,
|
||||
array_ref!(response, 1, 4),
|
||||
|
||||
@@ -595,6 +595,7 @@ pub struct PublicKeyCredentialSource {
|
||||
pub user_icon: Option<String>,
|
||||
pub cred_blob: Option<Vec<u8>>,
|
||||
pub large_blob_key: Option<Vec<u8>>,
|
||||
pub slot_id: Option<usize>,
|
||||
}
|
||||
|
||||
// We serialize credentials for the persistent storage using CBOR maps. Each field of a credential
|
||||
@@ -613,6 +614,7 @@ enum PublicKeyCredentialSourceField {
|
||||
CredBlob = 10,
|
||||
LargeBlobKey = 11,
|
||||
PrivateKey = 12,
|
||||
SlotId = 13,
|
||||
// When a field is removed, its tag should be reserved and not used for new fields. We document
|
||||
// those reserved tags below.
|
||||
// Reserved tags:
|
||||
@@ -639,6 +641,7 @@ impl From<PublicKeyCredentialSource> for cbor::Value {
|
||||
PublicKeyCredentialSourceField::CredBlob => credential.cred_blob,
|
||||
PublicKeyCredentialSourceField::LargeBlobKey => credential.large_blob_key,
|
||||
PublicKeyCredentialSourceField::PrivateKey => credential.private_key,
|
||||
PublicKeyCredentialSourceField::SlotId => credential.slot_id.map(|x| x as u64),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -661,6 +664,7 @@ impl TryFrom<cbor::Value> for PublicKeyCredentialSource {
|
||||
PublicKeyCredentialSourceField::CredBlob => cred_blob,
|
||||
PublicKeyCredentialSourceField::LargeBlobKey => large_blob_key,
|
||||
PublicKeyCredentialSourceField::PrivateKey => private_key,
|
||||
PublicKeyCredentialSourceField::SlotId => slot_id,
|
||||
} = extract_map(cbor_value)?;
|
||||
}
|
||||
|
||||
@@ -687,6 +691,12 @@ impl TryFrom<cbor::Value> for PublicKeyCredentialSource {
|
||||
.ok_or(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR)?,
|
||||
(None, Some(k)) => k,
|
||||
};
|
||||
let slot_id = match slot_id.map(extract_unsigned).transpose()? {
|
||||
Some(x) => Some(
|
||||
usize::try_from(x).map_err(|_| Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR)?,
|
||||
),
|
||||
None => None,
|
||||
};
|
||||
|
||||
// We don't return whether there were unknown fields in the CBOR value. This means that
|
||||
// deserialization is not injective. In particular deserialization is only an inverse of
|
||||
@@ -711,6 +721,7 @@ impl TryFrom<cbor::Value> for PublicKeyCredentialSource {
|
||||
user_icon,
|
||||
cred_blob,
|
||||
large_blob_key,
|
||||
slot_id,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -2229,6 +2240,7 @@ mod test {
|
||||
user_icon: None,
|
||||
cred_blob: None,
|
||||
large_blob_key: None,
|
||||
slot_id: None,
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
@@ -2291,6 +2303,16 @@ mod test {
|
||||
..credential
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
PublicKeyCredentialSource::try_from(cbor::Value::from(credential.clone())),
|
||||
Ok(credential.clone())
|
||||
);
|
||||
|
||||
let credential = PublicKeyCredentialSource {
|
||||
slot_id: Some(1),
|
||||
..credential
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
PublicKeyCredentialSource::try_from(cbor::Value::from(credential.clone())),
|
||||
Ok(credential)
|
||||
@@ -2315,6 +2337,7 @@ mod test {
|
||||
user_icon: None,
|
||||
cred_blob: None,
|
||||
large_blob_key: None,
|
||||
slot_id: None,
|
||||
};
|
||||
|
||||
let source_cbor = cbor_map! {
|
||||
@@ -2347,6 +2370,7 @@ mod test {
|
||||
user_icon: None,
|
||||
cred_blob: None,
|
||||
large_blob_key: None,
|
||||
slot_id: None,
|
||||
};
|
||||
|
||||
let source_cbor = cbor_map! {
|
||||
|
||||
@@ -87,7 +87,9 @@ impl LargeBlobs {
|
||||
if offset != self.expected_next_offset {
|
||||
return Err(Ctap2StatusCode::CTAP1_ERR_INVALID_SEQ);
|
||||
}
|
||||
if storage::pin_hash(env)?.is_some() || storage::has_always_uv(env)? {
|
||||
// We only check whether slot 0 has a PIN here because if multi-PIN is enabled,
|
||||
// has_always_uv will always be true and the condition will always pass.
|
||||
if storage::pin_hash(env, 0)?.is_some() || storage::has_always_uv(env)? {
|
||||
let pin_uv_auth_param =
|
||||
pin_uv_auth_param.ok_or(Ctap2StatusCode::CTAP2_ERR_PUAT_REQUIRED)?;
|
||||
let pin_uv_auth_protocol =
|
||||
@@ -147,8 +149,13 @@ mod test {
|
||||
let mut env = TestEnv::new();
|
||||
let key_agreement_key = crypto::ecdh::SecKey::gensk(env.rng());
|
||||
let pin_uv_auth_token = [0x55; 32];
|
||||
let mut client_pin =
|
||||
ClientPin::new_test(key_agreement_key, pin_uv_auth_token, PinUvAuthProtocol::V1);
|
||||
let mut client_pin = ClientPin::new_test(
|
||||
&mut env,
|
||||
0,
|
||||
key_agreement_key,
|
||||
pin_uv_auth_token,
|
||||
PinUvAuthProtocol::V1,
|
||||
);
|
||||
let mut large_blobs = LargeBlobs::new();
|
||||
|
||||
let large_blob = vec![
|
||||
@@ -178,8 +185,13 @@ mod test {
|
||||
let mut env = TestEnv::new();
|
||||
let key_agreement_key = crypto::ecdh::SecKey::gensk(env.rng());
|
||||
let pin_uv_auth_token = [0x55; 32];
|
||||
let mut client_pin =
|
||||
ClientPin::new_test(key_agreement_key, pin_uv_auth_token, PinUvAuthProtocol::V1);
|
||||
let mut client_pin = ClientPin::new_test(
|
||||
&mut env,
|
||||
0,
|
||||
key_agreement_key,
|
||||
pin_uv_auth_token,
|
||||
PinUvAuthProtocol::V1,
|
||||
);
|
||||
let mut large_blobs = LargeBlobs::new();
|
||||
|
||||
const BLOB_LEN: usize = 200;
|
||||
@@ -240,8 +252,13 @@ mod test {
|
||||
let mut env = TestEnv::new();
|
||||
let key_agreement_key = crypto::ecdh::SecKey::gensk(env.rng());
|
||||
let pin_uv_auth_token = [0x55; 32];
|
||||
let mut client_pin =
|
||||
ClientPin::new_test(key_agreement_key, pin_uv_auth_token, PinUvAuthProtocol::V1);
|
||||
let mut client_pin = ClientPin::new_test(
|
||||
&mut env,
|
||||
0,
|
||||
key_agreement_key,
|
||||
pin_uv_auth_token,
|
||||
PinUvAuthProtocol::V1,
|
||||
);
|
||||
let mut large_blobs = LargeBlobs::new();
|
||||
|
||||
const BLOB_LEN: usize = 200;
|
||||
@@ -286,8 +303,13 @@ mod test {
|
||||
let mut env = TestEnv::new();
|
||||
let key_agreement_key = crypto::ecdh::SecKey::gensk(env.rng());
|
||||
let pin_uv_auth_token = [0x55; 32];
|
||||
let mut client_pin =
|
||||
ClientPin::new_test(key_agreement_key, pin_uv_auth_token, PinUvAuthProtocol::V1);
|
||||
let mut client_pin = ClientPin::new_test(
|
||||
&mut env,
|
||||
0,
|
||||
key_agreement_key,
|
||||
pin_uv_auth_token,
|
||||
PinUvAuthProtocol::V1,
|
||||
);
|
||||
let mut large_blobs = LargeBlobs::new();
|
||||
|
||||
const BLOB_LEN: usize = 200;
|
||||
@@ -332,8 +354,13 @@ mod test {
|
||||
let mut env = TestEnv::new();
|
||||
let key_agreement_key = crypto::ecdh::SecKey::gensk(env.rng());
|
||||
let pin_uv_auth_token = [0x55; 32];
|
||||
let mut client_pin =
|
||||
ClientPin::new_test(key_agreement_key, pin_uv_auth_token, PinUvAuthProtocol::V1);
|
||||
let mut client_pin = ClientPin::new_test(
|
||||
&mut env,
|
||||
0,
|
||||
key_agreement_key,
|
||||
pin_uv_auth_token,
|
||||
PinUvAuthProtocol::V1,
|
||||
);
|
||||
let mut large_blobs = LargeBlobs::new();
|
||||
|
||||
let large_blobs_params = AuthenticatorLargeBlobsParameters {
|
||||
@@ -355,8 +382,13 @@ mod test {
|
||||
let mut env = TestEnv::new();
|
||||
let key_agreement_key = crypto::ecdh::SecKey::gensk(env.rng());
|
||||
let pin_uv_auth_token = [0x55; 32];
|
||||
let mut client_pin =
|
||||
ClientPin::new_test(key_agreement_key, pin_uv_auth_token, PinUvAuthProtocol::V1);
|
||||
let mut client_pin = ClientPin::new_test(
|
||||
&mut env,
|
||||
0,
|
||||
key_agreement_key,
|
||||
pin_uv_auth_token,
|
||||
PinUvAuthProtocol::V1,
|
||||
);
|
||||
let mut large_blobs = LargeBlobs::new();
|
||||
|
||||
const BLOB_LEN: usize = 20;
|
||||
@@ -383,8 +415,13 @@ mod test {
|
||||
let mut env = TestEnv::new();
|
||||
let key_agreement_key = crypto::ecdh::SecKey::gensk(env.rng());
|
||||
let pin_uv_auth_token = [0x55; 32];
|
||||
let mut client_pin =
|
||||
ClientPin::new_test(key_agreement_key, pin_uv_auth_token, pin_uv_auth_protocol);
|
||||
let mut client_pin = ClientPin::new_test(
|
||||
&mut env,
|
||||
0,
|
||||
key_agreement_key,
|
||||
pin_uv_auth_token,
|
||||
pin_uv_auth_protocol,
|
||||
);
|
||||
let mut large_blobs = LargeBlobs::new();
|
||||
|
||||
const BLOB_LEN: usize = 20;
|
||||
@@ -392,7 +429,7 @@ mod test {
|
||||
let mut large_blob = vec![0x1B; DATA_LEN];
|
||||
large_blob.extend_from_slice(&Sha256::hash(&large_blob[..])[..TRUNCATED_HASH_LEN]);
|
||||
|
||||
storage::set_pin(&mut env, &[0u8; 16], 4).unwrap();
|
||||
storage::set_pin(&mut env, 0, &[0u8; 16], 4).unwrap();
|
||||
let mut large_blob_data = vec![0xFF; 32];
|
||||
// Command constant and offset bytes.
|
||||
large_blob_data.extend(&[0x0C, 0x00, 0x00, 0x00, 0x00, 0x00]);
|
||||
|
||||
833
src/ctap/mod.rs
833
src/ctap/mod.rs
File diff suppressed because it is too large
Load Diff
@@ -30,7 +30,7 @@ use alloc::vec::Vec;
|
||||
use arrayref::array_ref;
|
||||
use core::cmp;
|
||||
use core::convert::TryInto;
|
||||
use persistent_store::{fragment, StoreUpdate};
|
||||
use persistent_store::{concat, fragment};
|
||||
use rng256::Rng256;
|
||||
use sk_cbor::cbor_array_vec;
|
||||
|
||||
@@ -237,9 +237,34 @@ pub fn new_creation_order(env: &mut impl Env) -> Result<u64, Ctap2StatusCode> {
|
||||
Ok(max.unwrap_or(0).wrapping_add(1))
|
||||
}
|
||||
|
||||
fn check_and_get_key_for_slot(
|
||||
env: &mut impl Env,
|
||||
slot_id: usize,
|
||||
first_key: usize,
|
||||
key_array: core::ops::Range<usize>,
|
||||
) -> Result<usize, Ctap2StatusCode> {
|
||||
if slot_id >= env.customization().slot_count() {
|
||||
return Err(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR);
|
||||
}
|
||||
Ok(if slot_id == 0 {
|
||||
first_key
|
||||
} else {
|
||||
key_array.start + slot_id - 1
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the global signature counter.
|
||||
pub fn global_signature_counter(env: &mut impl Env) -> Result<u32, Ctap2StatusCode> {
|
||||
match env.store().find(key::GLOBAL_SIGNATURE_COUNTER)? {
|
||||
pub fn global_signature_counter(
|
||||
env: &mut impl Env,
|
||||
slot_id: usize,
|
||||
) -> Result<u32, Ctap2StatusCode> {
|
||||
let key = check_and_get_key_for_slot(
|
||||
env,
|
||||
slot_id,
|
||||
key::FIRST_GLOBAL_SIGNATURE_COUNTER,
|
||||
key::GLOBAL_SIGNATURE_COUNTER,
|
||||
)?;
|
||||
match env.store().find(key)? {
|
||||
None => Ok(INITIAL_SIGNATURE_COUNTER),
|
||||
Some(value) if value.len() == 4 => Ok(u32::from_ne_bytes(*array_ref!(&value, 0, 4))),
|
||||
Some(_) => Err(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR),
|
||||
@@ -249,13 +274,19 @@ pub fn global_signature_counter(env: &mut impl Env) -> Result<u32, Ctap2StatusCo
|
||||
/// Increments the global signature counter.
|
||||
pub fn incr_global_signature_counter(
|
||||
env: &mut impl Env,
|
||||
slot_id: usize,
|
||||
increment: u32,
|
||||
) -> Result<(), Ctap2StatusCode> {
|
||||
let old_value = global_signature_counter(env)?;
|
||||
let key = check_and_get_key_for_slot(
|
||||
env,
|
||||
slot_id,
|
||||
key::FIRST_GLOBAL_SIGNATURE_COUNTER,
|
||||
key::GLOBAL_SIGNATURE_COUNTER,
|
||||
)?;
|
||||
let old_value = global_signature_counter(env, slot_id)?;
|
||||
// In hopes that servers handle the wrapping gracefully.
|
||||
let new_value = old_value.wrapping_add(increment);
|
||||
env.store()
|
||||
.insert(key::GLOBAL_SIGNATURE_COUNTER, &new_value.to_ne_bytes())?;
|
||||
env.store().insert(key, &new_value.to_ne_bytes())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -273,9 +304,22 @@ pub fn cred_random_secret(env: &mut impl Env, has_uv: bool) -> Result<[u8; 32],
|
||||
}
|
||||
|
||||
/// Reads the PIN properties and wraps them into PinProperties.
|
||||
fn pin_properties(env: &mut impl Env) -> Result<Option<PinProperties>, Ctap2StatusCode> {
|
||||
let pin_properties = match env.store().find(key::PIN_PROPERTIES)? {
|
||||
None => return Ok(None),
|
||||
fn pin_properties(
|
||||
env: &mut impl Env,
|
||||
slot_id: usize,
|
||||
) -> Result<Option<PinProperties>, Ctap2StatusCode> {
|
||||
let pin_properties = match concat::read(env.store(), key::PIN_PROPERTIES, slot_id as u8)? {
|
||||
None => {
|
||||
// Backward compatibility: old implementation where there is only 1 PIN slot
|
||||
// uses the entry with key `FIRST_PIN_PROPERTIES`.
|
||||
if slot_id != 0 {
|
||||
return Ok(None);
|
||||
}
|
||||
match env.store().find(key::FIRST_PIN_PROPERTIES)? {
|
||||
None => return Ok(None),
|
||||
Some(pin_properties) => pin_properties,
|
||||
}
|
||||
}
|
||||
Some(pin_properties) => pin_properties,
|
||||
};
|
||||
const PROPERTIES_LENGTH: usize = PIN_AUTH_LENGTH + 1;
|
||||
@@ -288,14 +332,30 @@ fn pin_properties(env: &mut impl Env) -> Result<Option<PinProperties>, Ctap2Stat
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns if PIN is set for at least one slot.
|
||||
pub fn has_pin(env: &mut impl Env) -> Result<bool, Ctap2StatusCode> {
|
||||
for slot_id in 0..env.customization().slot_count() {
|
||||
if pin_hash(env, slot_id)?.is_some() {
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
/// Returns the PIN hash if defined.
|
||||
pub fn pin_hash(env: &mut impl Env) -> Result<Option<[u8; PIN_AUTH_LENGTH]>, Ctap2StatusCode> {
|
||||
Ok(pin_properties(env)?.map(|p| p.hash))
|
||||
pub fn pin_hash(
|
||||
env: &mut impl Env,
|
||||
slot_id: usize,
|
||||
) -> Result<Option<[u8; PIN_AUTH_LENGTH]>, Ctap2StatusCode> {
|
||||
Ok(pin_properties(env, slot_id)?.map(|p| p.hash))
|
||||
}
|
||||
|
||||
/// Returns the length of the currently set PIN if defined.
|
||||
pub fn pin_code_point_length(env: &mut impl Env) -> Result<Option<u8>, Ctap2StatusCode> {
|
||||
Ok(pin_properties(env)?.map(|p| p.code_point_length))
|
||||
pub fn pin_code_point_length(
|
||||
env: &mut impl Env,
|
||||
slot_id: usize,
|
||||
) -> Result<Option<u8>, Ctap2StatusCode> {
|
||||
Ok(pin_properties(env, slot_id)?.map(|p| p.code_point_length))
|
||||
}
|
||||
|
||||
/// Sets the PIN hash and length.
|
||||
@@ -303,26 +363,32 @@ pub fn pin_code_point_length(env: &mut impl Env) -> Result<Option<u8>, Ctap2Stat
|
||||
/// If it was already defined, it is updated.
|
||||
pub fn set_pin(
|
||||
env: &mut impl Env,
|
||||
slot_id: usize,
|
||||
pin_hash: &[u8; PIN_AUTH_LENGTH],
|
||||
pin_code_point_length: u8,
|
||||
) -> Result<(), Ctap2StatusCode> {
|
||||
concat::delete(env.store(), key::FORCE_PIN_CHANGE, slot_id as u8)?;
|
||||
if slot_id == 0 {
|
||||
// Backward compatibility: data might be stored in these entries for slot 0 as well.
|
||||
env.store().remove(key::FIRST_FORCE_PIN_CHANGE)?;
|
||||
env.store().remove(key::FIRST_PIN_PROPERTIES)?;
|
||||
}
|
||||
let mut pin_properties = [0; 1 + PIN_AUTH_LENGTH];
|
||||
pin_properties[0] = pin_code_point_length;
|
||||
pin_properties[1..].clone_from_slice(pin_hash);
|
||||
Ok(env.store().transaction(&[
|
||||
StoreUpdate::Insert {
|
||||
key: key::PIN_PROPERTIES,
|
||||
value: &pin_properties[..],
|
||||
},
|
||||
StoreUpdate::Remove {
|
||||
key: key::FORCE_PIN_CHANGE,
|
||||
},
|
||||
])?)
|
||||
concat::write(
|
||||
env.store(),
|
||||
key::PIN_PROPERTIES,
|
||||
slot_id as u8,
|
||||
&pin_properties[..],
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns the number of remaining PIN retries.
|
||||
pub fn pin_retries(env: &mut impl Env) -> Result<u8, Ctap2StatusCode> {
|
||||
match env.store().find(key::PIN_RETRIES)? {
|
||||
pub fn pin_retries(env: &mut impl Env, slot_id: usize) -> Result<u8, Ctap2StatusCode> {
|
||||
let key = check_and_get_key_for_slot(env, slot_id, key::FIRST_PIN_RETRIES, key::PIN_RETRIES)?;
|
||||
match env.store().find(key)? {
|
||||
None => Ok(env.customization().max_pin_retries()),
|
||||
Some(value) if value.len() == 1 => Ok(value[0]),
|
||||
_ => Err(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR),
|
||||
@@ -330,18 +396,20 @@ pub fn pin_retries(env: &mut impl Env) -> Result<u8, Ctap2StatusCode> {
|
||||
}
|
||||
|
||||
/// Decrements the number of remaining PIN retries.
|
||||
pub fn decr_pin_retries(env: &mut impl Env) -> Result<(), Ctap2StatusCode> {
|
||||
let old_value = pin_retries(env)?;
|
||||
pub fn decr_pin_retries(env: &mut impl Env, slot_id: usize) -> Result<(), Ctap2StatusCode> {
|
||||
let key = check_and_get_key_for_slot(env, slot_id, key::FIRST_PIN_RETRIES, key::PIN_RETRIES)?;
|
||||
let old_value = pin_retries(env, slot_id)?;
|
||||
let new_value = old_value.saturating_sub(1);
|
||||
if new_value != old_value {
|
||||
env.store().insert(key::PIN_RETRIES, &[new_value])?;
|
||||
env.store().insert(key, &[new_value])?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Resets the number of remaining PIN retries.
|
||||
pub fn reset_pin_retries(env: &mut impl Env) -> Result<(), Ctap2StatusCode> {
|
||||
Ok(env.store().remove(key::PIN_RETRIES)?)
|
||||
pub fn reset_pin_retries(env: &mut impl Env, slot_id: usize) -> Result<(), Ctap2StatusCode> {
|
||||
let key = check_and_get_key_for_slot(env, slot_id, key::FIRST_PIN_RETRIES, key::PIN_RETRIES)?;
|
||||
Ok(env.store().remove(key)?)
|
||||
}
|
||||
|
||||
/// Returns the minimum PIN length.
|
||||
@@ -467,17 +535,34 @@ pub fn reset(env: &mut impl Env) -> Result<(), Ctap2StatusCode> {
|
||||
}
|
||||
|
||||
/// Returns whether the PIN needs to be changed before its next usage.
|
||||
pub fn has_force_pin_change(env: &mut impl Env) -> Result<bool, Ctap2StatusCode> {
|
||||
match env.store().find(key::FORCE_PIN_CHANGE)? {
|
||||
None => Ok(false),
|
||||
pub fn has_force_pin_change(env: &mut impl Env, slot_id: usize) -> Result<bool, Ctap2StatusCode> {
|
||||
match concat::read(env.store(), key::FORCE_PIN_CHANGE, slot_id as u8)? {
|
||||
None => {
|
||||
if slot_id != 0 {
|
||||
Ok(false)
|
||||
} else {
|
||||
// Backward compatibility: old implementation where there is only 1 PIN slot
|
||||
// uses the entry with key `FIRST_FORCE_PIN_CHANGE`.
|
||||
match env.store().find(key::FIRST_FORCE_PIN_CHANGE)? {
|
||||
None => Ok(false),
|
||||
Some(value) if value.is_empty() => Ok(true),
|
||||
_ => Err(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR),
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(value) if value.is_empty() => Ok(true),
|
||||
_ => Err(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR),
|
||||
}
|
||||
}
|
||||
|
||||
/// Marks the PIN as outdated with respect to the new PIN policy.
|
||||
pub fn force_pin_change(env: &mut impl Env) -> Result<(), Ctap2StatusCode> {
|
||||
Ok(env.store().insert(key::FORCE_PIN_CHANGE, &[])?)
|
||||
pub fn force_pin_change(env: &mut impl Env, slot_id: usize) -> Result<(), Ctap2StatusCode> {
|
||||
Ok(concat::write(
|
||||
env.store(),
|
||||
key::FORCE_PIN_CHANGE,
|
||||
slot_id as u8,
|
||||
&[],
|
||||
)?)
|
||||
}
|
||||
|
||||
/// Returns whether enterprise attestation is enabled.
|
||||
@@ -528,6 +613,25 @@ pub fn toggle_always_uv(env: &mut impl Env) -> Result<(), Ctap2StatusCode> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns whether multi-PIN is enabled.
|
||||
pub fn has_multi_pin(env: &mut impl Env) -> Result<bool, Ctap2StatusCode> {
|
||||
match env.store().find(key::MULTI_PIN)? {
|
||||
None => Ok(false),
|
||||
Some(value) if value.is_empty() => Ok(true),
|
||||
_ => Err(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR),
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Call this in config_commands after the whole multi-PIN feature is ready.
|
||||
// Before that, this function only be used for testing purpose.
|
||||
/// Enables multi-PIN, when disabled.
|
||||
pub fn _enable_multi_pin_for_test(env: &mut impl Env) -> Result<(), Ctap2StatusCode> {
|
||||
if !has_multi_pin(env)? {
|
||||
env.store().insert(key::MULTI_PIN, &[])?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl From<persistent_store::StoreError> for Ctap2StatusCode {
|
||||
fn from(error: persistent_store::StoreError) -> Ctap2StatusCode {
|
||||
use persistent_store::StoreError;
|
||||
@@ -651,6 +755,7 @@ mod test {
|
||||
CredentialProtectionPolicy, PublicKeyCredentialSource, PublicKeyCredentialType,
|
||||
};
|
||||
use crate::env::test::TestEnv;
|
||||
use persistent_store::StoreUpdate;
|
||||
use rng256::Rng256;
|
||||
|
||||
fn create_credential_source(
|
||||
@@ -672,6 +777,7 @@ mod test {
|
||||
user_icon: None,
|
||||
cred_blob: None,
|
||||
large_blob_key: None,
|
||||
slot_id: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -868,6 +974,7 @@ mod test {
|
||||
user_icon: None,
|
||||
cred_blob: None,
|
||||
large_blob_key: None,
|
||||
slot_id: None,
|
||||
};
|
||||
assert_eq!(found_credential, Some(expected_credential));
|
||||
}
|
||||
@@ -899,8 +1006,8 @@ mod test {
|
||||
let mut env = TestEnv::new();
|
||||
|
||||
// Pin hash is initially not set.
|
||||
assert!(pin_hash(&mut env).unwrap().is_none());
|
||||
assert!(pin_code_point_length(&mut env).unwrap().is_none());
|
||||
assert!(pin_hash(&mut env, 0).unwrap().is_none());
|
||||
assert!(pin_code_point_length(&mut env, 0).unwrap().is_none());
|
||||
|
||||
// Setting the pin sets the pin hash.
|
||||
let random_data = env.rng().gen_uniform_u8x32();
|
||||
@@ -909,17 +1016,131 @@ mod test {
|
||||
let pin_hash_2 = *array_ref!(random_data, PIN_AUTH_LENGTH, PIN_AUTH_LENGTH);
|
||||
let pin_length_1 = 4;
|
||||
let pin_length_2 = 63;
|
||||
set_pin(&mut env, &pin_hash_1, pin_length_1).unwrap();
|
||||
assert_eq!(pin_hash(&mut env).unwrap(), Some(pin_hash_1));
|
||||
assert_eq!(pin_code_point_length(&mut env).unwrap(), Some(pin_length_1));
|
||||
set_pin(&mut env, &pin_hash_2, pin_length_2).unwrap();
|
||||
assert_eq!(pin_hash(&mut env).unwrap(), Some(pin_hash_2));
|
||||
assert_eq!(pin_code_point_length(&mut env).unwrap(), Some(pin_length_2));
|
||||
set_pin(&mut env, 0, &pin_hash_1, pin_length_1).unwrap();
|
||||
assert_eq!(pin_hash(&mut env, 0).unwrap(), Some(pin_hash_1));
|
||||
assert_eq!(
|
||||
pin_code_point_length(&mut env, 0).unwrap(),
|
||||
Some(pin_length_1)
|
||||
);
|
||||
set_pin(&mut env, 0, &pin_hash_2, pin_length_2).unwrap();
|
||||
assert_eq!(pin_hash(&mut env, 0).unwrap(), Some(pin_hash_2));
|
||||
assert_eq!(
|
||||
pin_code_point_length(&mut env, 0).unwrap(),
|
||||
Some(pin_length_2)
|
||||
);
|
||||
|
||||
// Resetting the storage resets the pin hash.
|
||||
reset(&mut env).unwrap();
|
||||
assert!(pin_hash(&mut env).unwrap().is_none());
|
||||
assert!(pin_code_point_length(&mut env).unwrap().is_none());
|
||||
assert!(pin_hash(&mut env, 0).unwrap().is_none());
|
||||
assert!(pin_code_point_length(&mut env, 0).unwrap().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pin_hash_and_length_multi_pin() {
|
||||
let mut env = TestEnv::new();
|
||||
|
||||
for i in 0..env.customization().slot_count() {
|
||||
// Pin hash is initially not set.
|
||||
assert!(pin_hash(&mut env, i).unwrap().is_none());
|
||||
assert!(pin_code_point_length(&mut env, i).unwrap().is_none());
|
||||
}
|
||||
|
||||
// Setting the pin sets the pin hash.
|
||||
let random_data = env.rng().gen_uniform_u8x32();
|
||||
assert_eq!(random_data.len(), 2 * PIN_AUTH_LENGTH);
|
||||
let pin_hash_1 = *array_ref!(random_data, 0, PIN_AUTH_LENGTH);
|
||||
let pin_hash_2 = *array_ref!(random_data, PIN_AUTH_LENGTH, PIN_AUTH_LENGTH);
|
||||
let pin_length_1 = 4;
|
||||
let pin_length_2 = 63;
|
||||
set_pin(&mut env, 1, &pin_hash_1, pin_length_1).unwrap();
|
||||
assert_eq!(pin_hash(&mut env, 1).unwrap(), Some(pin_hash_1));
|
||||
assert_eq!(
|
||||
pin_code_point_length(&mut env, 1).unwrap(),
|
||||
Some(pin_length_1)
|
||||
);
|
||||
// Other slots aren't affected.
|
||||
assert!(pin_hash(&mut env, 0).unwrap().is_none());
|
||||
assert!(pin_code_point_length(&mut env, 0).unwrap().is_none());
|
||||
|
||||
set_pin(&mut env, 1, &pin_hash_2, pin_length_2).unwrap();
|
||||
assert_eq!(pin_hash(&mut env, 1).unwrap(), Some(pin_hash_2));
|
||||
assert_eq!(
|
||||
pin_code_point_length(&mut env, 1).unwrap(),
|
||||
Some(pin_length_2)
|
||||
);
|
||||
// Other slots aren't affected.
|
||||
assert!(pin_hash(&mut env, 0).unwrap().is_none());
|
||||
assert!(pin_code_point_length(&mut env, 0).unwrap().is_none());
|
||||
|
||||
// Set PIN for multiple slots is supported.
|
||||
set_pin(&mut env, 2, &pin_hash_1, pin_length_1).unwrap();
|
||||
assert_eq!(pin_hash(&mut env, 2).unwrap(), Some(pin_hash_1));
|
||||
assert_eq!(
|
||||
pin_code_point_length(&mut env, 2).unwrap(),
|
||||
Some(pin_length_1)
|
||||
);
|
||||
|
||||
// Resetting the storage resets the pin hash.
|
||||
reset(&mut env).unwrap();
|
||||
for i in 0..env.customization().slot_count() {
|
||||
assert!(pin_hash(&mut env, i).unwrap().is_none());
|
||||
assert!(pin_code_point_length(&mut env, i).unwrap().is_none());
|
||||
}
|
||||
}
|
||||
|
||||
fn set_pin_legacy(
|
||||
env: &mut impl Env,
|
||||
pin_hash: &[u8; PIN_AUTH_LENGTH],
|
||||
pin_code_point_length: u8,
|
||||
) -> Result<(), Ctap2StatusCode> {
|
||||
let mut pin_properties = [0; 1 + PIN_AUTH_LENGTH];
|
||||
pin_properties[0] = pin_code_point_length;
|
||||
pin_properties[1..].clone_from_slice(pin_hash);
|
||||
Ok(env.store().transaction(&[
|
||||
StoreUpdate::Insert {
|
||||
key: key::FIRST_PIN_PROPERTIES,
|
||||
value: &pin_properties[..],
|
||||
},
|
||||
StoreUpdate::Remove {
|
||||
key: key::FIRST_FORCE_PIN_CHANGE,
|
||||
},
|
||||
])?)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pin_hash_and_length_backward_compat() {
|
||||
let mut env = TestEnv::new();
|
||||
|
||||
// Setting the pin sets the pin hash.
|
||||
let random_data = env.rng().gen_uniform_u8x32();
|
||||
assert_eq!(random_data.len(), 2 * PIN_AUTH_LENGTH);
|
||||
|
||||
let pin_hash_1 = *array_ref!(random_data, 0, PIN_AUTH_LENGTH);
|
||||
let pin_hash_2 = *array_ref!(random_data, PIN_AUTH_LENGTH, PIN_AUTH_LENGTH);
|
||||
let pin_length_1 = 4;
|
||||
let pin_length_2 = 63;
|
||||
|
||||
assert!(set_pin_legacy(&mut env, &pin_hash_1, pin_length_1).is_ok());
|
||||
|
||||
// Should fallback to read from legacy storage location successfully.
|
||||
assert_eq!(pin_hash(&mut env, 0).unwrap(), Some(pin_hash_1));
|
||||
assert_eq!(
|
||||
pin_code_point_length(&mut env, 0).unwrap(),
|
||||
Some(pin_length_1)
|
||||
);
|
||||
// Fallback logic should only apply to slot 0.
|
||||
assert!(pin_hash(&mut env, 1).unwrap().is_none());
|
||||
assert!(pin_code_point_length(&mut env, 1).unwrap().is_none());
|
||||
|
||||
// Setting PIN again should use the new storage location, and erase the old one.
|
||||
set_pin(&mut env, 0, &pin_hash_2, pin_length_2).unwrap();
|
||||
assert_eq!(pin_hash(&mut env, 0).unwrap(), Some(pin_hash_2));
|
||||
assert_eq!(
|
||||
pin_code_point_length(&mut env, 0).unwrap(),
|
||||
Some(pin_length_2)
|
||||
);
|
||||
assert_eq!(env.store().find(key::FIRST_PIN_PROPERTIES), Ok(None));
|
||||
assert_eq!(env.store().find(key::FIRST_FORCE_PIN_CHANGE), Ok(None));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -928,24 +1149,76 @@ mod test {
|
||||
|
||||
// The pin retries is initially at the maximum.
|
||||
assert_eq!(
|
||||
pin_retries(&mut env),
|
||||
pin_retries(&mut env, 0),
|
||||
Ok(env.customization().max_pin_retries())
|
||||
);
|
||||
|
||||
// Decrementing the pin retries decrements the pin retries.
|
||||
for retries in (0..env.customization().max_pin_retries()).rev() {
|
||||
decr_pin_retries(&mut env).unwrap();
|
||||
assert_eq!(pin_retries(&mut env), Ok(retries));
|
||||
decr_pin_retries(&mut env, 0).unwrap();
|
||||
assert_eq!(pin_retries(&mut env, 0), Ok(retries));
|
||||
}
|
||||
|
||||
// Decrementing the pin retries after zero does not modify the pin retries.
|
||||
decr_pin_retries(&mut env).unwrap();
|
||||
assert_eq!(pin_retries(&mut env), Ok(0));
|
||||
decr_pin_retries(&mut env, 0).unwrap();
|
||||
assert_eq!(pin_retries(&mut env, 0), Ok(0));
|
||||
|
||||
// Resetting the pin retries resets the pin retries.
|
||||
reset_pin_retries(&mut env).unwrap();
|
||||
reset_pin_retries(&mut env, 0).unwrap();
|
||||
assert_eq!(
|
||||
pin_retries(&mut env),
|
||||
pin_retries(&mut env, 0),
|
||||
Ok(env.customization().max_pin_retries())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pin_retries_multi_pin() {
|
||||
let mut env = TestEnv::new();
|
||||
|
||||
for i in 0..env.customization().slot_count() {
|
||||
// The pin retries is initially at the maximum.
|
||||
assert_eq!(
|
||||
pin_retries(&mut env, i),
|
||||
Ok(env.customization().max_pin_retries())
|
||||
);
|
||||
}
|
||||
|
||||
// Decrementing the pin retries decrements the pin retries.
|
||||
for retries in (0..env.customization().max_pin_retries()).rev() {
|
||||
decr_pin_retries(&mut env, 1).unwrap();
|
||||
assert_eq!(pin_retries(&mut env, 1), Ok(retries));
|
||||
// Other slots shouldn't be affected.
|
||||
assert_eq!(
|
||||
pin_retries(&mut env, 2),
|
||||
Ok(env.customization().max_pin_retries())
|
||||
);
|
||||
}
|
||||
|
||||
// Decrementing the pin retries after zero does not modify the pin retries.
|
||||
decr_pin_retries(&mut env, 1).unwrap();
|
||||
assert_eq!(pin_retries(&mut env, 1), Ok(0));
|
||||
|
||||
// Operating on multiple slots is supported.
|
||||
decr_pin_retries(&mut env, 2).unwrap();
|
||||
assert_eq!(
|
||||
pin_retries(&mut env, 2),
|
||||
Ok(env.customization().max_pin_retries() - 1)
|
||||
);
|
||||
|
||||
// Resetting the pin retries resets the pin retries.
|
||||
reset_pin_retries(&mut env, 1).unwrap();
|
||||
assert_eq!(
|
||||
pin_retries(&mut env, 1),
|
||||
Ok(env.customization().max_pin_retries())
|
||||
);
|
||||
|
||||
// Other slots shouldn't be affected.
|
||||
assert_eq!(
|
||||
pin_retries(&mut env, 2),
|
||||
Ok(env.customization().max_pin_retries() - 1)
|
||||
);
|
||||
assert_eq!(
|
||||
pin_retries(&mut env, 3),
|
||||
Ok(env.customization().max_pin_retries())
|
||||
);
|
||||
}
|
||||
@@ -1088,11 +1361,56 @@ mod test {
|
||||
let mut env = TestEnv::new();
|
||||
|
||||
let mut counter_value = 1;
|
||||
assert_eq!(global_signature_counter(&mut env).unwrap(), counter_value);
|
||||
assert_eq!(
|
||||
global_signature_counter(&mut env, 0).unwrap(),
|
||||
counter_value
|
||||
);
|
||||
for increment in 1..10 {
|
||||
assert!(incr_global_signature_counter(&mut env, increment).is_ok());
|
||||
assert!(incr_global_signature_counter(&mut env, 0, increment).is_ok());
|
||||
counter_value += increment;
|
||||
assert_eq!(global_signature_counter(&mut env).unwrap(), counter_value);
|
||||
assert_eq!(
|
||||
global_signature_counter(&mut env, 0).unwrap(),
|
||||
counter_value
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_global_signature_counter_multi_pin() {
|
||||
let mut env = TestEnv::new();
|
||||
|
||||
let mut counter_value = 1;
|
||||
for i in 0..env.customization().slot_count() {
|
||||
assert_eq!(
|
||||
global_signature_counter(&mut env, i).unwrap(),
|
||||
counter_value
|
||||
);
|
||||
}
|
||||
for increment in 1..10 {
|
||||
assert!(incr_global_signature_counter(&mut env, 1, increment).is_ok());
|
||||
counter_value += increment;
|
||||
assert_eq!(
|
||||
global_signature_counter(&mut env, 1).unwrap(),
|
||||
counter_value
|
||||
);
|
||||
// Other slots aren't affected.
|
||||
assert_eq!(global_signature_counter(&mut env, 2).unwrap(), 1);
|
||||
}
|
||||
let counter_value_for_slot_1 = counter_value;
|
||||
counter_value = 1;
|
||||
|
||||
for increment in 1..10 {
|
||||
assert!(incr_global_signature_counter(&mut env, 2, increment).is_ok());
|
||||
counter_value += increment;
|
||||
assert_eq!(
|
||||
global_signature_counter(&mut env, 2).unwrap(),
|
||||
counter_value
|
||||
);
|
||||
// Other slots aren't affected.
|
||||
assert_eq!(
|
||||
global_signature_counter(&mut env, 1).unwrap(),
|
||||
counter_value_for_slot_1
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1100,11 +1418,60 @@ mod test {
|
||||
fn test_force_pin_change() {
|
||||
let mut env = TestEnv::new();
|
||||
|
||||
assert!(!has_force_pin_change(&mut env).unwrap());
|
||||
assert_eq!(force_pin_change(&mut env), Ok(()));
|
||||
assert!(has_force_pin_change(&mut env).unwrap());
|
||||
assert_eq!(set_pin(&mut env, &[0x88; 16], 8), Ok(()));
|
||||
assert!(!has_force_pin_change(&mut env).unwrap());
|
||||
assert!(!has_force_pin_change(&mut env, 0).unwrap());
|
||||
assert_eq!(force_pin_change(&mut env, 0), Ok(()));
|
||||
assert!(has_force_pin_change(&mut env, 0).unwrap());
|
||||
assert_eq!(set_pin(&mut env, 0, &[0x88; 16], 8), Ok(()));
|
||||
assert!(!has_force_pin_change(&mut env, 0).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_force_pin_change_multi_pin() {
|
||||
let mut env = TestEnv::new();
|
||||
|
||||
for i in 0..env.customization().slot_count() {
|
||||
assert!(!has_force_pin_change(&mut env, i).unwrap());
|
||||
}
|
||||
|
||||
assert_eq!(force_pin_change(&mut env, 1), Ok(()));
|
||||
assert!(has_force_pin_change(&mut env, 1).unwrap());
|
||||
// Other slots shouldn't be affected.
|
||||
assert!(!has_force_pin_change(&mut env, 2).unwrap());
|
||||
|
||||
assert_eq!(set_pin(&mut env, 1, &[0x88; 16], 8), Ok(()));
|
||||
assert!(!has_force_pin_change(&mut env, 1).unwrap());
|
||||
// Other slots shouldn't be affected.
|
||||
assert!(!has_force_pin_change(&mut env, 2).unwrap());
|
||||
|
||||
// Operating on multiple slots is supported.
|
||||
assert_eq!(force_pin_change(&mut env, 2), Ok(()));
|
||||
assert!(has_force_pin_change(&mut env, 2).unwrap());
|
||||
assert!(!has_force_pin_change(&mut env, 1).unwrap());
|
||||
}
|
||||
|
||||
fn force_pin_change_legacy(env: &mut impl Env) -> Result<(), Ctap2StatusCode> {
|
||||
Ok(env.store().insert(key::FIRST_FORCE_PIN_CHANGE, &[])?)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_force_pin_change_backward_compat() {
|
||||
let mut env = TestEnv::new();
|
||||
|
||||
assert!(!has_force_pin_change(&mut env, 0).unwrap());
|
||||
assert!(!has_force_pin_change(&mut env, 1).unwrap());
|
||||
assert_eq!(force_pin_change_legacy(&mut env), Ok(()));
|
||||
// Should fallback to read from legacy storage location successfully.
|
||||
assert!(has_force_pin_change(&mut env, 0).unwrap());
|
||||
// Fallback logic should only apply to slot 0.
|
||||
assert!(!has_force_pin_change(&mut env, 1).unwrap());
|
||||
|
||||
assert_eq!(set_pin(&mut env, 0, &[0x88; 16], 8), Ok(()));
|
||||
assert!(!has_force_pin_change(&mut env, 0).unwrap());
|
||||
// Old storage location should be cleared.
|
||||
assert_eq!(env.store().find(key::FIRST_FORCE_PIN_CHANGE), Ok(None));
|
||||
|
||||
assert_eq!(force_pin_change(&mut env, 0), Ok(()));
|
||||
assert!(has_force_pin_change(&mut env, 0).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1145,6 +1512,15 @@ mod test {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multi_pin() {
|
||||
let mut env = TestEnv::new();
|
||||
|
||||
assert!(!has_multi_pin(&mut env).unwrap());
|
||||
assert_eq!(_enable_multi_pin_for_test(&mut env), Ok(()));
|
||||
assert!(has_multi_pin(&mut env).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serialize_deserialize_credential() {
|
||||
let mut env = TestEnv::new();
|
||||
@@ -1162,6 +1538,7 @@ mod test {
|
||||
user_icon: Some(String::from("icon")),
|
||||
cred_blob: Some(vec![0xCB]),
|
||||
large_blob_key: Some(vec![0x1B]),
|
||||
slot_id: Some(1),
|
||||
};
|
||||
let serialized = serialize_credential(credential.clone()).unwrap();
|
||||
let reconstructed = deserialize_credential(&serialized).unwrap();
|
||||
|
||||
@@ -73,6 +73,37 @@ make_partition! {
|
||||
// - When adding a (non-persistent) key below this message, make sure its value is bigger or
|
||||
// equal than NUM_PERSISTENT_KEYS.
|
||||
|
||||
/// Whether multi-PIN is enabled.
|
||||
///
|
||||
/// The value must be empty. Only presence of the value matters.
|
||||
MULTI_PIN = 983;
|
||||
|
||||
// Start of key arrays for multi-PIN feature: these fields are separated for each slots, so
|
||||
// a unique key is needed for each slot. However, we reuse the existing fields and rename them
|
||||
// to `FIRST_{KEY_NAME}` so the upgrade is backward compatible.
|
||||
// Depending on `Customization::slot_count()`, only a prefix of those keys is used.
|
||||
|
||||
/// Whether the PIN needs to be changed each slot.
|
||||
///
|
||||
/// The PIN needs to be changed if the slot exists and its data is empty.
|
||||
FORCE_PIN_CHANGE = 984;
|
||||
|
||||
/// The number of PIN retries for each slot, except the first.
|
||||
PIN_RETRIES = 985..992;
|
||||
|
||||
/// The PIN hash and length for each slot.
|
||||
///
|
||||
/// If a slot is absent, there is no PIN set for that slot. The first byte represents
|
||||
/// the length, the following are an array with the hash.
|
||||
PIN_PROPERTIES = 992;
|
||||
|
||||
/// The global signature counters for each slot, except the first.
|
||||
///
|
||||
/// If the entry is absent, the counter is 0.
|
||||
GLOBAL_SIGNATURE_COUNTER = 993..1000;
|
||||
|
||||
// End of key arrays for multi-PIN feature.
|
||||
|
||||
/// Reserved for future credential-related objects.
|
||||
///
|
||||
/// In particular, additional credentials could be added there by reducing the lower bound of
|
||||
@@ -97,8 +128,10 @@ make_partition! {
|
||||
/// If this entry exists and is empty, enterprise attestation is enabled.
|
||||
ENTERPRISE_ATTESTATION = 2039;
|
||||
|
||||
/// If this entry exists and is empty, the PIN needs to be changed.
|
||||
FORCE_PIN_CHANGE = 2040;
|
||||
/// Whether the PIN needs to be changed for the first slot.
|
||||
///
|
||||
/// The PIN needs to be changed if this entry exists and is empty.
|
||||
FIRST_FORCE_PIN_CHANGE = 2040;
|
||||
|
||||
/// The secret of the CredRandom feature.
|
||||
CRED_RANDOM_SECRET = 2041;
|
||||
@@ -111,24 +144,22 @@ make_partition! {
|
||||
/// If the entry is absent, the minimum PIN length is `Customization::default_min_pin_length()`.
|
||||
MIN_PIN_LENGTH = 2043;
|
||||
|
||||
/// The number of PIN retries.
|
||||
/// The number of PIN retries for the first slot.
|
||||
///
|
||||
/// If the entry is absent, the number of PIN retries is `Customization::max_pin_retries()`.
|
||||
PIN_RETRIES = 2044;
|
||||
FIRST_PIN_RETRIES = 2044;
|
||||
|
||||
/// The PIN hash and length.
|
||||
/// The PIN hash and length for the first slot.
|
||||
///
|
||||
/// If the entry is absent, there is no PIN set. The first byte represents
|
||||
/// the length, the following are an array with the hash.
|
||||
PIN_PROPERTIES = 2045;
|
||||
FIRST_PIN_PROPERTIES = 2045;
|
||||
|
||||
/// Reserved for the key store implementation of the environment.
|
||||
_RESERVED_KEY_STORE = 2046;
|
||||
|
||||
/// The global signature counter.
|
||||
///
|
||||
/// If the entry is absent, the counter is 0.
|
||||
GLOBAL_SIGNATURE_COUNTER = 2047;
|
||||
/// The global signature counter for the first slot.
|
||||
FIRST_GLOBAL_SIGNATURE_COUNTER = 2047;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -41,7 +41,7 @@ pub struct PinUvAuthTokenState {
|
||||
permissions_rp_id: Option<String>,
|
||||
usage_timer: TimedPermission,
|
||||
user_verified: bool,
|
||||
in_use: bool,
|
||||
slot_id_in_use: Option<usize>,
|
||||
}
|
||||
|
||||
impl PinUvAuthTokenState {
|
||||
@@ -52,13 +52,18 @@ impl PinUvAuthTokenState {
|
||||
permissions_rp_id: None,
|
||||
usage_timer: TimedPermission::waiting(),
|
||||
user_verified: false,
|
||||
in_use: false,
|
||||
slot_id_in_use: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns whether the pinUvAuthToken is active.
|
||||
pub fn is_in_use(&self) -> bool {
|
||||
self.in_use
|
||||
self.slot_id_in_use.is_some()
|
||||
}
|
||||
|
||||
/// Returns the slot id in use.
|
||||
pub fn slot_id_in_use(&self) -> Option<usize> {
|
||||
self.slot_id_in_use
|
||||
}
|
||||
|
||||
/// Checks if the permission is granted.
|
||||
@@ -113,15 +118,15 @@ impl PinUvAuthTokenState {
|
||||
}
|
||||
|
||||
/// Starts the timer for pinUvAuthToken usage.
|
||||
pub fn begin_using_pin_uv_auth_token(&mut self, now: CtapInstant) {
|
||||
pub fn begin_using_pin_uv_auth_token(&mut self, now: CtapInstant, slot_id: usize) {
|
||||
self.user_verified = true;
|
||||
self.usage_timer = TimedPermission::granted(now, INITIAL_USAGE_TIME_LIMIT);
|
||||
self.in_use = true;
|
||||
self.slot_id_in_use = Some(slot_id);
|
||||
}
|
||||
|
||||
/// Updates the usage timer, and disables the pinUvAuthToken on timeout.
|
||||
pub fn pin_uv_auth_token_usage_timer_observer(&mut self, now: CtapInstant) {
|
||||
if !self.in_use {
|
||||
if !self.is_in_use() {
|
||||
return;
|
||||
}
|
||||
self.usage_timer = self.usage_timer.check_expiration(now);
|
||||
@@ -132,7 +137,7 @@ impl PinUvAuthTokenState {
|
||||
|
||||
/// Returns whether the user is verified.
|
||||
pub fn get_user_verified_flag_value(&self) -> bool {
|
||||
self.in_use && self.user_verified
|
||||
self.is_in_use() && self.user_verified
|
||||
}
|
||||
|
||||
/// Consumes the user verification.
|
||||
@@ -151,7 +156,7 @@ impl PinUvAuthTokenState {
|
||||
self.permissions_set = 0;
|
||||
self.usage_timer = TimedPermission::waiting();
|
||||
self.user_verified = false;
|
||||
self.in_use = false;
|
||||
self.slot_id_in_use = None;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,24 +169,28 @@ mod test {
|
||||
fn test_observer() {
|
||||
let mut token_state = PinUvAuthTokenState::new();
|
||||
let mut now: CtapInstant = CtapInstant::new(0);
|
||||
token_state.begin_using_pin_uv_auth_token(now);
|
||||
token_state.begin_using_pin_uv_auth_token(now, 0);
|
||||
assert!(token_state.is_in_use());
|
||||
assert_eq!(token_state.slot_id_in_use(), Some(0));
|
||||
now = now + Milliseconds(100_u32);
|
||||
token_state.pin_uv_auth_token_usage_timer_observer(now);
|
||||
assert!(token_state.is_in_use());
|
||||
now = now + INITIAL_USAGE_TIME_LIMIT;
|
||||
token_state.pin_uv_auth_token_usage_timer_observer(now);
|
||||
assert!(!token_state.is_in_use());
|
||||
assert!(token_state.slot_id_in_use().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stop() {
|
||||
let mut token_state = PinUvAuthTokenState::new();
|
||||
let now: CtapInstant = CtapInstant::new(0);
|
||||
token_state.begin_using_pin_uv_auth_token(now);
|
||||
token_state.begin_using_pin_uv_auth_token(now, 0);
|
||||
assert!(token_state.is_in_use());
|
||||
assert_eq!(token_state.slot_id_in_use(), Some(0));
|
||||
token_state.stop_using_pin_uv_auth_token();
|
||||
assert!(!token_state.is_in_use());
|
||||
assert!(token_state.slot_id_in_use().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -265,11 +274,11 @@ mod test {
|
||||
let mut token_state = PinUvAuthTokenState::new();
|
||||
assert!(!token_state.get_user_verified_flag_value());
|
||||
let now: CtapInstant = CtapInstant::new(0);
|
||||
token_state.begin_using_pin_uv_auth_token(now);
|
||||
token_state.begin_using_pin_uv_auth_token(now, 0);
|
||||
assert!(token_state.get_user_verified_flag_value());
|
||||
token_state.clear_user_verified_flag();
|
||||
assert!(!token_state.get_user_verified_flag_value());
|
||||
token_state.begin_using_pin_uv_auth_token(now);
|
||||
token_state.begin_using_pin_uv_auth_token(now, 0);
|
||||
assert!(token_state.get_user_verified_flag_value());
|
||||
token_state.stop_using_pin_uv_auth_token();
|
||||
assert!(!token_state.get_user_verified_flag_value());
|
||||
|
||||
7
src/env/test/customization.rs
vendored
7
src/env/test/customization.rs
vendored
@@ -33,6 +33,7 @@ pub struct TestCustomization {
|
||||
max_large_blob_array_size: usize,
|
||||
max_rp_ids_length: usize,
|
||||
max_supported_resident_keys: usize,
|
||||
slot_count: usize,
|
||||
}
|
||||
|
||||
impl TestCustomization {
|
||||
@@ -112,6 +113,10 @@ impl Customization for TestCustomization {
|
||||
fn max_supported_resident_keys(&self) -> usize {
|
||||
self.max_supported_resident_keys
|
||||
}
|
||||
|
||||
fn slot_count(&self) -> usize {
|
||||
self.slot_count
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CustomizationImpl> for TestCustomization {
|
||||
@@ -132,6 +137,7 @@ impl From<CustomizationImpl> for TestCustomization {
|
||||
max_large_blob_array_size,
|
||||
max_rp_ids_length,
|
||||
max_supported_resident_keys,
|
||||
slot_count,
|
||||
} = c;
|
||||
|
||||
let default_min_pin_length_rp_ids = default_min_pin_length_rp_ids
|
||||
@@ -160,6 +166,7 @@ impl From<CustomizationImpl> for TestCustomization {
|
||||
max_large_blob_array_size,
|
||||
max_rp_ids_length,
|
||||
max_supported_resident_keys,
|
||||
slot_count,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
76
third_party/lang-items/Cargo.lock
generated
vendored
Normal file
76
third_party/lang-items/Cargo.lock
generated
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "lang_items"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libtock_core",
|
||||
"libtock_drivers",
|
||||
"linked_list_allocator",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libtock_codegen"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libtock_core"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libtock_codegen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libtock_drivers"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libtock_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linked_list_allocator"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "822add9edb1860698b79522510da17bef885171f75aa395cff099d770c609c24"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52205623b1b0f064a4e71182c3b18ae902267282930c6d5462c91b859668426e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd"
|
||||
61
third_party/libtock-drivers/Cargo.lock
generated
vendored
Normal file
61
third_party/libtock-drivers/Cargo.lock
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "libtock_codegen"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libtock_core"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libtock_codegen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libtock_drivers"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libtock_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52205623b1b0f064a4e71182c3b18ae902267282930c6d5462c91b859668426e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd"
|
||||
179
tools/heapviz/Cargo.lock
generated
Normal file
179
tools/heapviz/Cargo.lock
generated
Normal file
@@ -0,0 +1,179 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.34.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"atty",
|
||||
"bitflags",
|
||||
"strsim",
|
||||
"textwrap",
|
||||
"unicode-width",
|
||||
"vec_map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heapviz"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"lazy_static",
|
||||
"ncurses",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.133"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "ncurses"
|
||||
version = "5.101.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e2c5d34d72657dc4b638a1c25d40aae81e4f1c699062f72f467237920752032"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||
dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
Reference in New Issue
Block a user