Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cafb0b2c18 | |||
| 0c7441a81e | |||
| a50addc15b | |||
| 0809f300b7 | |||
| d55079f9a6 | |||
| 10241230b3 | |||
| 1e02f135f0 | |||
| 0c2633ab31 | |||
| f49c617a9d | |||
| 1d33ea1747 | |||
| 18eb4bf4f4 | |||
| 10941bfb5b | |||
| 002491193e | |||
| 2e5139b237 |
+3
-3
@@ -1,5 +1,5 @@
|
|||||||
[advisories]
|
[advisories]
|
||||||
ignore = [
|
ignore = [
|
||||||
"RUSTSEC-2020-0071", # time
|
"RUSTSEC-2020-0071", # chrono
|
||||||
"RUSTSEC-2020-0159", # chrono
|
"RUSTSEC-2021-0145", # atty
|
||||||
]
|
] # advisory IDs to ignore e.g. ["RUSTSEC-2019-0001", ...]
|
||||||
|
|||||||
@@ -36,13 +36,13 @@ jobs:
|
|||||||
toolchain: stable
|
toolchain: stable
|
||||||
deps: true
|
deps: true
|
||||||
- platform: ubuntu-latest
|
- platform: ubuntu-latest
|
||||||
toolchain: 1.60.0 # MSRV
|
toolchain: 1.65.0 # MSRV
|
||||||
deps: sudo apt-get install libpcsclite-dev
|
deps: sudo apt-get install libpcsclite-dev
|
||||||
- platform: windows-latest
|
- platform: windows-latest
|
||||||
toolchain: 1.60.0 # MSRV
|
toolchain: 1.65.0 # MSRV
|
||||||
deps: true
|
deps: true
|
||||||
- platform: macos-latest
|
- platform: macos-latest
|
||||||
toolchain: 1.60.0 # MSRV
|
toolchain: 1.65.0 # MSRV
|
||||||
deps: true
|
deps: true
|
||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
@@ -42,4 +42,4 @@ jobs:
|
|||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
command: audit
|
command: audit
|
||||||
args: --deny warnings --ignore RUSTSEC-2019-0031 # spin
|
args: --deny warnings
|
||||||
|
|||||||
@@ -4,6 +4,26 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
### Added
|
||||||
|
- `YubiKey::disconnect`
|
||||||
|
- `impl Debug for {Context, YubiKey}`
|
||||||
|
- `Error::AppletNotFound`
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- `Reader::open` now returns `Error::AppletNotFound` instead of `Error::Generic`
|
||||||
|
if the PIV applet is not present on the device. This is returned by non-PIV
|
||||||
|
virtual smart cards like Windows Hello for Business, as well as some smart
|
||||||
|
card readers when no card is present.
|
||||||
|
- `Reader::open` now avoids resetting the card if an error occurs (equivalent to
|
||||||
|
calling `YubiKey::disconnect(pcsc::Disposition::LeaveCard)` if `Reader::open`
|
||||||
|
succeeds).
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- `StatusWords::code` now returns the correct code (including embedded `tries`
|
||||||
|
count) for `StatusWords::VerifyFailError`. Previously the returned code lost
|
||||||
|
information and was not round-trip compatible with `StatusWords::from(u16)`.
|
||||||
|
|
||||||
## 0.7.0 (2022-11-14)
|
## 0.7.0 (2022-11-14)
|
||||||
### Added
|
### Added
|
||||||
- Display inner PC/SC errors ([#420])
|
- Display inner PC/SC errors ([#420])
|
||||||
|
|||||||
Generated
+242
-123
@@ -4,9 +4,9 @@ version = 3
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "0.7.19"
|
version = "0.7.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e"
|
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
@@ -59,17 +59,6 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[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]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
@@ -78,9 +67,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base16ct"
|
name = "base16ct"
|
||||||
version = "0.1.1"
|
version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce"
|
checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64"
|
name = "base64"
|
||||||
@@ -123,9 +112,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.76"
|
version = "1.0.78"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "76a284da2e6fe2092f2353e51713435363112dfd60030e22add80be333fb928f"
|
checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
@@ -143,7 +132,7 @@ dependencies = [
|
|||||||
"js-sys",
|
"js-sys",
|
||||||
"num-integer",
|
"num-integer",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"time 0.1.44",
|
"time 0.1.45",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
@@ -160,14 +149,14 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.0.23"
|
version = "4.0.32"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0eb41c13df48950b20eb4cd0eefa618819469df1bffc49d11e8487c4ba0037e5"
|
checksum = "a7db700bc935f9e43e88d00b0850dae18a63773cfbec6d8e070fccf7fef89a39"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"clap_derive",
|
"clap_derive",
|
||||||
"clap_lex",
|
"clap_lex",
|
||||||
|
"is-terminal",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"strsim",
|
"strsim",
|
||||||
"termcolor",
|
"termcolor",
|
||||||
@@ -207,9 +196,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "const-oid"
|
name = "const-oid"
|
||||||
version = "0.9.0"
|
version = "0.9.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "722e23542a15cea1f65d4a1419c4cfd7a26706c70871a13a04238ca3f40f1661"
|
checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cookie-factory"
|
name = "cookie-factory"
|
||||||
@@ -234,9 +223,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crypto-bigint"
|
name = "crypto-bigint"
|
||||||
version = "0.4.9"
|
version = "0.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef"
|
checksum = "7c2538c4e68e52548bacb3e83ac549f903d44f011ac9d5abb5e132e67d0808f7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"generic-array",
|
"generic-array",
|
||||||
"rand_core",
|
"rand_core",
|
||||||
@@ -256,9 +245,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxx"
|
name = "cxx"
|
||||||
version = "1.0.81"
|
version = "1.0.85"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "97abf9f0eca9e52b7f81b945524e76710e6cb2366aead23b7d4fbf72e281f888"
|
checksum = "5add3fc1717409d029b20c5b6903fc0c0b02fa6741d820054f4a2efa5e5816fd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"cxxbridge-flags",
|
"cxxbridge-flags",
|
||||||
@@ -268,9 +257,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxx-build"
|
name = "cxx-build"
|
||||||
version = "1.0.81"
|
version = "1.0.85"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7cc32cc5fea1d894b77d269ddb9f192110069a8a9c1f1d441195fba90553dea3"
|
checksum = "b4c87959ba14bc6fbc61df77c3fcfe180fc32b93538c4f1031dd802ccb5f2ff0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"codespan-reporting",
|
"codespan-reporting",
|
||||||
@@ -283,15 +272,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxxbridge-flags"
|
name = "cxxbridge-flags"
|
||||||
version = "1.0.81"
|
version = "1.0.85"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8ca220e4794c934dc6b1207c3b42856ad4c302f2df1712e9f8d2eec5afaacf1f"
|
checksum = "69a3e162fde4e594ed2b07d0f83c6c67b745e7f28ce58c6df5e6b6bef99dfb59"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxxbridge-macro"
|
name = "cxxbridge-macro"
|
||||||
version = "1.0.81"
|
version = "1.0.85"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b846f081361125bfc8dc9d3940c84e1fd83ba54bbca7b17cd29483c828be0704"
|
checksum = "3e7e2adeb6a0d4a282e581096b06e1791532b7d576dcde5ccd9382acf55db8e6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -300,15 +289,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "data-encoding"
|
name = "data-encoding"
|
||||||
version = "2.3.2"
|
version = "2.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57"
|
checksum = "23d8666cb01533c39dde32bcbab8e227b4ed6679b2c925eba05feabea39508fb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "der"
|
name = "der"
|
||||||
version = "0.6.0"
|
version = "0.7.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "13dd2ae565c0a381dde7fade45fce95984c568bdcb4700a4fdbe3175e0380b2f"
|
checksum = "bc906908ea6458456e5eaa160a9c08543ec3d1e6f71e2235cedd660cb65f9df0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"const-oid",
|
"const-oid",
|
||||||
"pem-rfc7468",
|
"pem-rfc7468",
|
||||||
@@ -340,9 +329,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "digest"
|
name = "digest"
|
||||||
version = "0.10.5"
|
version = "0.10.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c"
|
checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"block-buffer",
|
"block-buffer",
|
||||||
"const-oid",
|
"const-oid",
|
||||||
@@ -363,9 +352,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ecdsa"
|
name = "ecdsa"
|
||||||
version = "0.14.8"
|
version = "0.16.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c"
|
checksum = "d1b0a1222f8072619e8a6b667a854020a03d363738303203c09468b3424a420a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"der",
|
"der",
|
||||||
"elliptic-curve",
|
"elliptic-curve",
|
||||||
@@ -375,13 +364,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "elliptic-curve"
|
name = "elliptic-curve"
|
||||||
version = "0.12.3"
|
version = "0.13.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3"
|
checksum = "6ea5a92946e8614bb585254898bb7dd1ddad241ace60c52149e3765e34cc039d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base16ct",
|
"base16ct",
|
||||||
"crypto-bigint",
|
"crypto-bigint",
|
||||||
"der",
|
|
||||||
"digest",
|
"digest",
|
||||||
"ff",
|
"ff",
|
||||||
"generic-array",
|
"generic-array",
|
||||||
@@ -397,22 +385,43 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "env_logger"
|
name = "env_logger"
|
||||||
version = "0.9.3"
|
version = "0.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7"
|
checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
|
||||||
"humantime",
|
"humantime",
|
||||||
|
"is-terminal",
|
||||||
"log",
|
"log",
|
||||||
"regex",
|
"regex",
|
||||||
"termcolor",
|
"termcolor",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ff"
|
name = "errno"
|
||||||
version = "0.12.1"
|
version = "0.2.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160"
|
checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
|
||||||
|
dependencies = [
|
||||||
|
"errno-dragonfly",
|
||||||
|
"libc",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "errno-dragonfly"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ff"
|
||||||
|
version = "0.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rand_core",
|
"rand_core",
|
||||||
"subtle",
|
"subtle",
|
||||||
@@ -426,6 +435,7 @@ checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"typenum",
|
"typenum",
|
||||||
"version_check",
|
"version_check",
|
||||||
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -441,9 +451,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "group"
|
name = "group"
|
||||||
version = "0.12.1"
|
version = "0.13.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7"
|
checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ff",
|
"ff",
|
||||||
"rand_core",
|
"rand_core",
|
||||||
@@ -458,9 +468,9 @@ checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.1.19"
|
version = "0.2.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
@@ -523,10 +533,32 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "io-lifetimes"
|
||||||
version = "1.0.4"
|
version = "1.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
|
checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "is-terminal"
|
||||||
|
version = "0.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189"
|
||||||
|
dependencies = [
|
||||||
|
"hermit-abi",
|
||||||
|
"io-lifetimes",
|
||||||
|
"rustix",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
@@ -548,9 +580,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.137"
|
version = "0.2.139"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
|
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libm"
|
name = "libm"
|
||||||
@@ -560,13 +592,19 @@ checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "link-cplusplus"
|
name = "link-cplusplus"
|
||||||
version = "1.0.7"
|
version = "1.0.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369"
|
checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linux-raw-sys"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.17"
|
version = "0.4.17"
|
||||||
@@ -590,9 +628,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nom"
|
name = "nom"
|
||||||
version = "7.1.1"
|
version = "7.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36"
|
checksum = "e5507769c4919c998e69e49c839d9dc6e693ede4cc4290d6ad8b41d4f09c548c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
"minimal-lexical",
|
"minimal-lexical",
|
||||||
@@ -611,9 +649,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-bigint-dig"
|
name = "num-bigint-dig"
|
||||||
version = "0.8.1"
|
version = "0.8.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "566d173b2f9406afbc5510a90925d5a2cd80cae4605631f1212303df265de011"
|
checksum = "2399c9463abc5f909349d8aa9ba080e0b88b3ce2885389b60b993f39b1a56905"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
@@ -660,61 +698,64 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oid-registry"
|
name = "oid-registry"
|
||||||
version = "0.6.0"
|
version = "0.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7d4bda43fd1b844cbc6e6e54b5444e2b1bc7838bce59ad205902cccbb26d6761"
|
checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"asn1-rs",
|
"asn1-rs",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.16.0"
|
version = "1.17.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
|
checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "os_str_bytes"
|
name = "os_str_bytes"
|
||||||
version = "6.4.0"
|
version = "6.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7b5bf27447411e9ee3ff51186bf7a08e16c341efdde93f4d823e8844429bed7e"
|
checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "p256"
|
name = "p256"
|
||||||
version = "0.11.1"
|
version = "0.13.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594"
|
checksum = "7270da3e5caa82afd3deb054cc237905853813aea3859544bc082c3fe55b8d47"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ecdsa",
|
"ecdsa",
|
||||||
"elliptic-curve",
|
"elliptic-curve",
|
||||||
|
"primeorder",
|
||||||
"sha2",
|
"sha2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "p384"
|
name = "p384"
|
||||||
version = "0.11.2"
|
version = "0.13.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dfc8c5bf642dde52bb9e87c0ecd8ca5a76faac2eeed98dedb7c717997e1080aa"
|
checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ecdsa",
|
"ecdsa",
|
||||||
"elliptic-curve",
|
"elliptic-curve",
|
||||||
|
"primeorder",
|
||||||
"sha2",
|
"sha2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pbkdf2"
|
name = "pbkdf2"
|
||||||
version = "0.11.0"
|
version = "0.12.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917"
|
checksum = "f0ca0b5a68607598bf3bad68f32227a8164f6254833f84eafaac409cd6746c31"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"digest",
|
"digest",
|
||||||
|
"hmac",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pcsc"
|
name = "pcsc"
|
||||||
version = "2.7.0"
|
version = "2.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7e29e4de78a433aeecd06fb5bd55a0f9fde11dc85a14c22d482972c7edc4fdc4"
|
checksum = "37cab0be9d04e808a8d8059fa54befcd71dc8b168f9f0c04bdb7e59832abbab4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"pcsc-sys",
|
"pcsc-sys",
|
||||||
@@ -731,18 +772,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pem-rfc7468"
|
name = "pem-rfc7468"
|
||||||
version = "0.6.0"
|
version = "0.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "24d159833a9105500e0398934e205e0773f0b27529557134ecfc51c27646adac"
|
checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64ct",
|
"base64ct",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pkcs1"
|
name = "pkcs1"
|
||||||
version = "0.4.1"
|
version = "0.7.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "eff33bdbdfc54cc98a2eca766ebdec3e1b8fb7387523d5c9c9a2891da856f719"
|
checksum = "178ba28ece1961eafdff1991bd1744c29564cbab5d803f3ccb4a4895a6c550a7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"der",
|
"der",
|
||||||
"pkcs8",
|
"pkcs8",
|
||||||
@@ -752,9 +793,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pkcs8"
|
name = "pkcs8"
|
||||||
version = "0.9.0"
|
version = "0.10.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba"
|
checksum = "3d2820d87d2b008616e5c27212dd9e0e694fb4c6b522de06094106813328cb49"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"der",
|
"der",
|
||||||
"spki",
|
"spki",
|
||||||
@@ -772,6 +813,15 @@ version = "0.2.17"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "primeorder"
|
||||||
|
version = "0.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7613fdcc0831c10060fa69833ea8fa2caa94b6456f51e25356a885b530a2e3d0"
|
||||||
|
dependencies = [
|
||||||
|
"elliptic-curve",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro-error"
|
name = "proc-macro-error"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
@@ -798,18 +848,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.47"
|
version = "1.0.49"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
|
checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.21"
|
version = "1.0.23"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
|
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
@@ -863,20 +913,19 @@ checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rfc6979"
|
name = "rfc6979"
|
||||||
version = "0.3.1"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb"
|
checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crypto-bigint",
|
|
||||||
"hmac",
|
"hmac",
|
||||||
"zeroize",
|
"subtle",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rsa"
|
name = "rsa"
|
||||||
version = "0.7.1"
|
version = "0.9.0-pre.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b0ecc3307be66bfb3574577895555bacfb9a37a8d5cd959444b72ff02495c618"
|
checksum = "a7bc1d34159d63536b4d89944e9ab5bb952f45db6fa0b8b03c2f8c09fb5b7171"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"digest",
|
"digest",
|
||||||
@@ -888,7 +937,6 @@ dependencies = [
|
|||||||
"pkcs8",
|
"pkcs8",
|
||||||
"rand_core",
|
"rand_core",
|
||||||
"signature",
|
"signature",
|
||||||
"smallvec",
|
|
||||||
"subtle",
|
"subtle",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
@@ -903,16 +951,30 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scratch"
|
name = "rustix"
|
||||||
version = "1.0.2"
|
version = "0.36.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898"
|
checksum = "4feacf7db682c6c329c4ede12649cd36ecab0f3be5b7d74e6a20304725db4549"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"errno",
|
||||||
|
"io-lifetimes",
|
||||||
|
"libc",
|
||||||
|
"linux-raw-sys",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scratch"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sec1"
|
name = "sec1"
|
||||||
version = "0.3.0"
|
version = "0.7.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928"
|
checksum = "48518a2b5775ba8ca5b46596aae011caa431e6ce7e4a67ead66d92f08884220e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base16ct",
|
"base16ct",
|
||||||
"der",
|
"der",
|
||||||
@@ -933,9 +995,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.147"
|
version = "1.0.152"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965"
|
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha1"
|
name = "sha1"
|
||||||
@@ -961,9 +1023,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "signature"
|
name = "signature"
|
||||||
version = "1.6.4"
|
version = "2.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c"
|
checksum = "8fe458c98333f9c8152221191a77e2a44e8325d0193484af2e9421a53019e57d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"digest",
|
"digest",
|
||||||
"rand_core",
|
"rand_core",
|
||||||
@@ -983,9 +1045,9 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spki"
|
name = "spki"
|
||||||
version = "0.6.0"
|
version = "0.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b"
|
checksum = "c0445c905640145c7ea8c1993555957f65e7c46d0535b91ba501bc9bfc85522f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64ct",
|
"base64ct",
|
||||||
"der",
|
"der",
|
||||||
@@ -1005,9 +1067,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.103"
|
version = "1.0.107"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d"
|
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -1037,18 +1099,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.37"
|
version = "1.0.38"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e"
|
checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl",
|
"thiserror-impl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror-impl"
|
name = "thiserror-impl"
|
||||||
version = "1.0.37"
|
version = "1.0.38"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb"
|
checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -1057,9 +1119,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time"
|
name = "time"
|
||||||
version = "0.1.44"
|
version = "0.1.45"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
|
checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"wasi 0.10.0+wasi-snapshot-preview1",
|
"wasi 0.10.0+wasi-snapshot-preview1",
|
||||||
@@ -1095,15 +1157,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
version = "1.15.0"
|
version = "1.16.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
|
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.5"
|
version = "1.0.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
|
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-width"
|
name = "unicode-width"
|
||||||
@@ -1119,9 +1181,9 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uuid"
|
name = "uuid"
|
||||||
version = "1.2.1"
|
version = "1.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "feb41e78f93363bb2df8b0e86a2ca30eed7806ea16ea0c790d757cf93f79be83"
|
checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom",
|
"getrandom",
|
||||||
]
|
]
|
||||||
@@ -1229,6 +1291,63 @@ version = "0.4.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.42.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_gnullvm",
|
||||||
|
"windows_aarch64_msvc",
|
||||||
|
"windows_i686_gnu",
|
||||||
|
"windows_i686_msvc",
|
||||||
|
"windows_x86_64_gnu",
|
||||||
|
"windows_x86_64_gnullvm",
|
||||||
|
"windows_x86_64_msvc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_gnullvm"
|
||||||
|
version = "0.42.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.42.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.42.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.42.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.42.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnullvm"
|
||||||
|
version = "0.42.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.42.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "x509"
|
name = "x509"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
@@ -1259,7 +1378,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yubikey"
|
name = "yubikey"
|
||||||
version = "0.7.0"
|
version = "0.8.0-pre.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base16ct",
|
"base16ct",
|
||||||
"chrono",
|
"chrono",
|
||||||
@@ -1294,7 +1413,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yubikey-cli"
|
name = "yubikey-cli"
|
||||||
version = "0.6.0"
|
version = "0.7.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base16ct",
|
"base16ct",
|
||||||
"clap",
|
"clap",
|
||||||
|
|||||||
+11
-12
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "yubikey"
|
name = "yubikey"
|
||||||
version = "0.7.0"
|
version = "0.8.0-pre.0"
|
||||||
description = """
|
description = """
|
||||||
Pure Rust cross-platform host-side driver for YubiKey devices from Yubico with
|
Pure Rust cross-platform host-side driver for YubiKey devices from Yubico with
|
||||||
support for hardware-backed public-key decryption and digital signatures using
|
support for hardware-backed public-key decryption and digital signatures using
|
||||||
@@ -14,7 +14,7 @@ readme = "README.md"
|
|||||||
categories = ["api-bindings", "authentication", "cryptography", "hardware-support"]
|
categories = ["api-bindings", "authentication", "cryptography", "hardware-support"]
|
||||||
keywords = ["ecdsa", "encryption", "rsa", "piv", "signature"]
|
keywords = ["ecdsa", "encryption", "rsa", "piv", "signature"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.60"
|
rust-version = "1.65"
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [".", "cli"]
|
members = [".", "cli"]
|
||||||
@@ -24,20 +24,20 @@ chrono = "0.4.23"
|
|||||||
cookie-factory = "0.3"
|
cookie-factory = "0.3"
|
||||||
der-parser = "8"
|
der-parser = "8"
|
||||||
des = "0.8"
|
des = "0.8"
|
||||||
elliptic-curve = "0.12"
|
elliptic-curve = "0.13"
|
||||||
hex = { package = "base16ct", version = "0.1", features = ["alloc"] }
|
hex = { package = "base16ct", version = "0.2", features = ["alloc"] }
|
||||||
hmac = "0.12"
|
hmac = "0.12"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
nom = "7"
|
nom = "7"
|
||||||
num-bigint-dig = { version = "0.8", features = ["rand"] }
|
num-bigint-dig = { version = "0.8", features = ["rand"] }
|
||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
num-integer = "0.1"
|
num-integer = "0.1"
|
||||||
pbkdf2 = { version = "0.11", default-features = false }
|
p256 = "0.13"
|
||||||
p256 = "0.11"
|
p384 = "0.13"
|
||||||
p384 = "0.11"
|
pbkdf2 = { version = "0.12", default-features = false, features = ["hmac"] }
|
||||||
pcsc = "2"
|
pcsc = "2.3.1"
|
||||||
rand_core = { version = "0.6", features = ["std"] }
|
rand_core = { version = "0.6", features = ["std"] }
|
||||||
rsa = "0.7"
|
rsa = "=0.9.0-pre.0"
|
||||||
secrecy = "0.8"
|
secrecy = "0.8"
|
||||||
sha1 = { version = "0.10", features = ["oid"] }
|
sha1 = { version = "0.10", features = ["oid"] }
|
||||||
sha2 = { version = "0.10", features = ["oid"] }
|
sha2 = { version = "0.10", features = ["oid"] }
|
||||||
@@ -48,10 +48,9 @@ x509-parser = "0.14"
|
|||||||
zeroize = "1"
|
zeroize = "1"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
env_logger = "0.9"
|
env_logger = "0.10"
|
||||||
once_cell = "1"
|
once_cell = "1"
|
||||||
rsa = { version = "0.7.1", features = ["hazmat"] }
|
signature = "2"
|
||||||
signature = { version = "1.6.4", features = ["hazmat-preview"] }
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
untested = []
|
untested = []
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ Yubico's [yubico-piv-tool], a C library/CLI program. The original library
|
|||||||
was licensed under a [2-Clause BSD License][BSDL], which this library inherits
|
was licensed under a [2-Clause BSD License][BSDL], which this library inherits
|
||||||
as a derived work.
|
as a derived work.
|
||||||
|
|
||||||
Copyright (c) 2014-2022 Yubico AB, Tony Arcieri
|
Copyright (c) 2014-2023 Yubico AB, Tony Arcieri
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
@@ -214,7 +214,7 @@ or conditions.
|
|||||||
[docs-link]: https://docs.rs/yubikey/
|
[docs-link]: https://docs.rs/yubikey/
|
||||||
[license-image]: https://img.shields.io/badge/license-BSD-blue.svg
|
[license-image]: https://img.shields.io/badge/license-BSD-blue.svg
|
||||||
[license-link]: https://github.com/iqlusioninc/yubikey.rs/blob/main/COPYING
|
[license-link]: https://github.com/iqlusioninc/yubikey.rs/blob/main/COPYING
|
||||||
[msrv-image]: https://img.shields.io/badge/rustc-1.60+-blue.svg
|
[msrv-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg
|
||||||
[safety-image]: https://img.shields.io/badge/unsafe-forbidden-success.svg
|
[safety-image]: https://img.shields.io/badge/unsafe-forbidden-success.svg
|
||||||
[safety-link]: https://github.com/rust-secure-code/safety-dance/
|
[safety-link]: https://github.com/rust-secure-code/safety-dance/
|
||||||
[build-image]: https://github.com/iqlusioninc/yubikey.rs/workflows/CI/badge.svg?branch=main&event=push
|
[build-image]: https://github.com/iqlusioninc/yubikey.rs/workflows/CI/badge.svg?branch=main&event=push
|
||||||
|
|||||||
@@ -4,6 +4,20 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## 0.7.0 (2022-11-14)
|
||||||
|
### Changed
|
||||||
|
- Bump `clap` to v4.0 ([#438])
|
||||||
|
- Bump `x509-parser` to v0.14 ([#441])
|
||||||
|
- Switch from `lazy_static` to `once_cell` ([#442])
|
||||||
|
- Switch from `subtle-encoding` to `base16ct` ([#443])
|
||||||
|
- Bump `yubikey` dependency to v0.7 ([#444])
|
||||||
|
|
||||||
|
[#438]: https://github.com/iqlusioninc/yubikey.rs/pull/438
|
||||||
|
[#441]: https://github.com/iqlusioninc/yubikey.rs/pull/441
|
||||||
|
[#442]: https://github.com/iqlusioninc/yubikey.rs/pull/442
|
||||||
|
[#443]: https://github.com/iqlusioninc/yubikey.rs/pull/443
|
||||||
|
[#444]: https://github.com/iqlusioninc/yubikey.rs/pull/444
|
||||||
|
|
||||||
## 0.6.0 (2022-08-10)
|
## 0.6.0 (2022-08-10)
|
||||||
### Changed
|
### Changed
|
||||||
- 2021 edition upgrade; MSRV 1.57 ([#343])
|
- 2021 edition upgrade; MSRV 1.57 ([#343])
|
||||||
|
|||||||
+4
-4
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "yubikey-cli"
|
name = "yubikey-cli"
|
||||||
version = "0.6.0"
|
version = "0.7.0"
|
||||||
description = """
|
description = """
|
||||||
Command-line interface for performing encryption and signing using RSA/ECC keys
|
Command-line interface for performing encryption and signing using RSA/ECC keys
|
||||||
stored on YubiKey devices.
|
stored on YubiKey devices.
|
||||||
@@ -16,11 +16,11 @@ rust-version = "1.56"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = { version = "4", features = ["derive"] }
|
clap = { version = "4", features = ["derive"] }
|
||||||
env_logger = "0.9"
|
env_logger = "0.10"
|
||||||
hex = { package = "base16ct", version = "0.1", features = ["alloc"] }
|
hex = { package = "base16ct", version = "0.2", features = ["alloc"] }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
once_cell = "1"
|
once_cell = "1"
|
||||||
sha2 = "0.10"
|
sha2 = "0.10"
|
||||||
termcolor = "1"
|
termcolor = "1"
|
||||||
x509-parser = "0.14"
|
x509-parser = "0.14"
|
||||||
yubikey = { version = "0.7", path = ".." }
|
yubikey = { version = "0.8.0-pre.0", path = ".." }
|
||||||
|
|||||||
+1
-1
@@ -43,7 +43,7 @@ For more information, please see [CODE_OF_CONDUCT.md][cc-md].
|
|||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Copyright (c) 2014-2022 Yubico AB, Tony Arcieri
|
Copyright (c) 2014-2023 Yubico AB, Tony Arcieri
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
|||||||
+48
-1
@@ -353,6 +353,12 @@ pub(crate) enum StatusWords {
|
|||||||
/// Successful execution
|
/// Successful execution
|
||||||
Success,
|
Success,
|
||||||
|
|
||||||
|
/// The requested data was too large for the response, and there is data remaining.
|
||||||
|
BytesRemaining {
|
||||||
|
/// The number of bytes remaining, as indicated in the response.
|
||||||
|
len: u8,
|
||||||
|
},
|
||||||
|
|
||||||
/// https://github.com/Yubico/yubikey-manager/blob/1f22620b623c6b345dd9f9193ec765a542dddc80/ykman/driver_ccid.py#L53
|
/// https://github.com/Yubico/yubikey-manager/blob/1f22620b623c6b345dd9f9193ec765a542dddc80/ykman/driver_ccid.py#L53
|
||||||
NoInputDataError,
|
NoInputDataError,
|
||||||
|
|
||||||
@@ -410,8 +416,9 @@ impl StatusWords {
|
|||||||
pub fn code(self) -> u16 {
|
pub fn code(self) -> u16 {
|
||||||
match self {
|
match self {
|
||||||
StatusWords::None => 0,
|
StatusWords::None => 0,
|
||||||
|
StatusWords::BytesRemaining { len } => 0x6100 | len as u16,
|
||||||
StatusWords::NoInputDataError => 0x6285,
|
StatusWords::NoInputDataError => 0x6285,
|
||||||
StatusWords::VerifyFailError { tries } => 0x63c0 & tries as u16,
|
StatusWords::VerifyFailError { tries } => 0x63c0 | tries as u16,
|
||||||
StatusWords::WrongLengthError => 0x6700,
|
StatusWords::WrongLengthError => 0x6700,
|
||||||
StatusWords::SecurityStatusError => 0x6982,
|
StatusWords::SecurityStatusError => 0x6982,
|
||||||
StatusWords::AuthBlockedError => 0x6983,
|
StatusWords::AuthBlockedError => 0x6983,
|
||||||
@@ -439,6 +446,9 @@ impl From<u16> for StatusWords {
|
|||||||
fn from(sw: u16) -> Self {
|
fn from(sw: u16) -> Self {
|
||||||
match sw {
|
match sw {
|
||||||
0x0000 => StatusWords::None,
|
0x0000 => StatusWords::None,
|
||||||
|
sw if sw & 0xff00 == 0x6100 => Self::BytesRemaining {
|
||||||
|
len: (sw & 0x00ff) as u8,
|
||||||
|
},
|
||||||
0x6285 => StatusWords::NoInputDataError,
|
0x6285 => StatusWords::NoInputDataError,
|
||||||
sw if sw & 0xfff0 == 0x63c0 => StatusWords::VerifyFailError {
|
sw if sw & 0xfff0 == 0x63c0 => StatusWords::VerifyFailError {
|
||||||
tries: (sw & 0x000f) as u8,
|
tries: (sw & 0x000f) as u8,
|
||||||
@@ -466,3 +476,40 @@ impl From<StatusWords> for u16 {
|
|||||||
sw.code()
|
sw.code()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::StatusWords;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn status_words_round_trip() {
|
||||||
|
let round_trip = |sw: StatusWords| {
|
||||||
|
assert_eq!(StatusWords::from(sw.code()), sw);
|
||||||
|
};
|
||||||
|
|
||||||
|
round_trip(StatusWords::None);
|
||||||
|
round_trip(StatusWords::BytesRemaining { len: 1 });
|
||||||
|
round_trip(StatusWords::BytesRemaining { len: 10 });
|
||||||
|
round_trip(StatusWords::BytesRemaining { len: 0xFF });
|
||||||
|
round_trip(StatusWords::Success);
|
||||||
|
round_trip(StatusWords::NoInputDataError);
|
||||||
|
round_trip(StatusWords::VerifyFailError { tries: 0x0F });
|
||||||
|
round_trip(StatusWords::VerifyFailError { tries: 3 });
|
||||||
|
round_trip(StatusWords::VerifyFailError { tries: 2 });
|
||||||
|
round_trip(StatusWords::VerifyFailError { tries: 1 });
|
||||||
|
round_trip(StatusWords::VerifyFailError { tries: 0 });
|
||||||
|
round_trip(StatusWords::WrongLengthError);
|
||||||
|
round_trip(StatusWords::SecurityStatusError);
|
||||||
|
round_trip(StatusWords::AuthBlockedError);
|
||||||
|
round_trip(StatusWords::DataInvalidError);
|
||||||
|
round_trip(StatusWords::ConditionsNotSatisfiedError);
|
||||||
|
round_trip(StatusWords::CommandNotAllowedError);
|
||||||
|
round_trip(StatusWords::IncorrectParamError);
|
||||||
|
round_trip(StatusWords::NotFoundError);
|
||||||
|
round_trip(StatusWords::NoSpaceError);
|
||||||
|
round_trip(StatusWords::IncorrectSlotError);
|
||||||
|
round_trip(StatusWords::NotSupportedError);
|
||||||
|
round_trip(StatusWords::CommandAbortedError);
|
||||||
|
round_trip(StatusWords::Other(0x1337));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -45,6 +45,12 @@ pub enum Error {
|
|||||||
/// Applet error
|
/// Applet error
|
||||||
AppletError,
|
AppletError,
|
||||||
|
|
||||||
|
/// We tried to select an applet that could not be found.
|
||||||
|
AppletNotFound {
|
||||||
|
/// Human-readable name of the applet.
|
||||||
|
applet_name: &'static str,
|
||||||
|
},
|
||||||
|
|
||||||
/// Argument error
|
/// Argument error
|
||||||
ArgumentError,
|
ArgumentError,
|
||||||
|
|
||||||
@@ -125,6 +131,9 @@ impl Error {
|
|||||||
match self {
|
match self {
|
||||||
Error::AlgorithmError => f.write_str("algorithm error"),
|
Error::AlgorithmError => f.write_str("algorithm error"),
|
||||||
Error::AppletError => f.write_str("applet error"),
|
Error::AppletError => f.write_str("applet error"),
|
||||||
|
Error::AppletNotFound { applet_name } => {
|
||||||
|
f.write_str(&format!("{} applet not found", applet_name))
|
||||||
|
}
|
||||||
Error::ArgumentError => f.write_str("argument error"),
|
Error::ArgumentError => f.write_str("argument error"),
|
||||||
Error::AuthenticationError => f.write_str("authentication error"),
|
Error::AuthenticationError => f.write_str("authentication error"),
|
||||||
Error::GenericError => f.write_str("generic error"),
|
Error::GenericError => f.write_str("generic error"),
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ mod mgm;
|
|||||||
mod mscmap;
|
mod mscmap;
|
||||||
#[cfg(feature = "untested")]
|
#[cfg(feature = "untested")]
|
||||||
mod msroots;
|
mod msroots;
|
||||||
|
mod otp;
|
||||||
pub mod piv;
|
pub mod piv;
|
||||||
mod policy;
|
mod policy;
|
||||||
pub mod reader;
|
pub mod reader;
|
||||||
|
|||||||
+12
-2
@@ -46,7 +46,17 @@ use des::{
|
|||||||
TdesEde3,
|
TdesEde3,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "untested")]
|
#[cfg(feature = "untested")]
|
||||||
use {hmac::Hmac, pbkdf2::pbkdf2, sha1::Sha1};
|
use {pbkdf2::pbkdf2_hmac, sha1::Sha1};
|
||||||
|
|
||||||
|
/// YubiKey MGMT Applet Name
|
||||||
|
#[cfg(feature = "untested")]
|
||||||
|
pub(crate) const APPLET_NAME: &str = "YubiKey MGMT";
|
||||||
|
|
||||||
|
/// MGMT Applet ID.
|
||||||
|
///
|
||||||
|
/// <https://developers.yubico.com/PIV/Introduction/Admin_access.html>
|
||||||
|
#[cfg(feature = "untested")]
|
||||||
|
pub(crate) const APPLET_ID: &[u8] = &[0xa0, 0x00, 0x00, 0x05, 0x27, 0x47, 0x11, 0x17];
|
||||||
|
|
||||||
pub(crate) const ADMIN_FLAGS_1_PROTECTED_MGM: u8 = 0x02;
|
pub(crate) const ADMIN_FLAGS_1_PROTECTED_MGM: u8 = 0x02;
|
||||||
|
|
||||||
@@ -137,7 +147,7 @@ impl MgmKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut mgm = [0u8; DES_LEN_3DES];
|
let mut mgm = [0u8; DES_LEN_3DES];
|
||||||
pbkdf2::<Hmac<Sha1>>(pin, salt, ITER_MGM_PBKDF2, &mut mgm);
|
pbkdf2_hmac::<Sha1>(pin, salt, ITER_MGM_PBKDF2, &mut mgm);
|
||||||
MgmKey::from_bytes(mgm)
|
MgmKey::from_bytes(mgm)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
/// YubiKey OTP Applet Name
|
||||||
|
pub(crate) const APPLET_NAME: &str = "YubiKey OTP";
|
||||||
|
|
||||||
|
/// YubiKey OTP Applet ID. Needed to query serial on YK4.
|
||||||
|
pub(crate) const APPLET_ID: &[u8] = &[0xa0, 0x00, 0x00, 0x05, 0x27, 0x20, 0x01, 0x01];
|
||||||
@@ -73,6 +73,12 @@ use {
|
|||||||
#[cfg(feature = "untested")]
|
#[cfg(feature = "untested")]
|
||||||
use zeroize::Zeroizing;
|
use zeroize::Zeroizing;
|
||||||
|
|
||||||
|
/// PIV Applet Name
|
||||||
|
pub(crate) const APPLET_NAME: &str = "PIV";
|
||||||
|
|
||||||
|
/// PIV Applet ID
|
||||||
|
pub(crate) const APPLET_ID: &[u8] = &[0xa0, 0x00, 0x00, 0x03, 0x08];
|
||||||
|
|
||||||
const CB_ECC_POINTP256: usize = 65;
|
const CB_ECC_POINTP256: usize = 65;
|
||||||
const CB_ECC_POINTP384: usize = 97;
|
const CB_ECC_POINTP384: usize = 97;
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use crate::{Result, YubiKey};
|
|||||||
use std::{
|
use std::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
ffi::CStr,
|
ffi::CStr,
|
||||||
|
fmt,
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -19,6 +20,12 @@ pub struct Context {
|
|||||||
reader_names: Vec<u8>,
|
reader_names: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for Context {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
f.debug_struct("Context").finish_non_exhaustive()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
/// Open a PC/SC context, which can be used to enumerate available PC/SC
|
/// Open a PC/SC context, which can be used to enumerate available PC/SC
|
||||||
/// readers (which can be used to connect to YubiKeys).
|
/// readers (which can be used to connect to YubiKeys).
|
||||||
|
|||||||
+54
-42
@@ -5,7 +5,8 @@ use crate::{
|
|||||||
apdu::{Apdu, Ins, StatusWords},
|
apdu::{Apdu, Ins, StatusWords},
|
||||||
consts::{CB_BUF_MAX, CB_OBJ_MAX},
|
consts::{CB_BUF_MAX, CB_OBJ_MAX},
|
||||||
error::{Error, Result},
|
error::{Error, Result},
|
||||||
piv::{AlgorithmId, SlotId},
|
otp,
|
||||||
|
piv::{self, AlgorithmId, SlotId},
|
||||||
serialization::*,
|
serialization::*,
|
||||||
yubikey::*,
|
yubikey::*,
|
||||||
Buffer, ObjectId,
|
Buffer, ObjectId,
|
||||||
@@ -16,12 +17,6 @@ use zeroize::Zeroizing;
|
|||||||
#[cfg(feature = "untested")]
|
#[cfg(feature = "untested")]
|
||||||
use crate::mgm::{MgmKey, DES_LEN_3DES};
|
use crate::mgm::{MgmKey, DES_LEN_3DES};
|
||||||
|
|
||||||
/// PIV Applet ID
|
|
||||||
const PIV_AID: [u8; 5] = [0xa0, 0x00, 0x00, 0x03, 0x08];
|
|
||||||
|
|
||||||
/// YubiKey OTP Applet ID. Needed to query serial on YK4.
|
|
||||||
const YK_AID: [u8; 8] = [0xa0, 0x00, 0x00, 0x05, 0x27, 0x20, 0x01, 0x01];
|
|
||||||
|
|
||||||
const CB_PIN_MAX: usize = 8;
|
const CB_PIN_MAX: usize = 8;
|
||||||
|
|
||||||
#[cfg(feature = "untested")]
|
#[cfg(feature = "untested")]
|
||||||
@@ -69,7 +64,7 @@ impl<'tx> Transaction<'tx> {
|
|||||||
pub fn select_application(&self) -> Result<()> {
|
pub fn select_application(&self) -> Result<()> {
|
||||||
let response = Apdu::new(Ins::SelectApplication)
|
let response = Apdu::new(Ins::SelectApplication)
|
||||||
.p1(0x04)
|
.p1(0x04)
|
||||||
.data(PIV_AID)
|
.data(piv::APPLET_ID)
|
||||||
.transmit(self, 0xFF)
|
.transmit(self, 0xFF)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
error!("failed communicating with card: '{}'", e);
|
error!("failed communicating with card: '{}'", e);
|
||||||
@@ -81,7 +76,12 @@ impl<'tx> Transaction<'tx> {
|
|||||||
"failed selecting application: {:04x}",
|
"failed selecting application: {:04x}",
|
||||||
response.status_words().code()
|
response.status_words().code()
|
||||||
);
|
);
|
||||||
return Err(Error::GenericError);
|
return Err(match response.status_words() {
|
||||||
|
StatusWords::NotFoundError => Error::AppletNotFound {
|
||||||
|
applet_name: piv::APPLET_NAME,
|
||||||
|
},
|
||||||
|
_ => Error::GenericError,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -105,25 +105,32 @@ impl<'tx> Transaction<'tx> {
|
|||||||
|
|
||||||
/// Get YubiKey device serial number.
|
/// Get YubiKey device serial number.
|
||||||
pub fn get_serial(&self, version: Version) -> Result<Serial> {
|
pub fn get_serial(&self, version: Version) -> Result<Serial> {
|
||||||
let response = if version.major < 5 {
|
match version.major {
|
||||||
// YK4 requires switching to the yk applet to retrieve the serial
|
// YK4 requires switching to the YK applet to retrieve the serial
|
||||||
|
4 => {
|
||||||
let sw = Apdu::new(Ins::SelectApplication)
|
let sw = Apdu::new(Ins::SelectApplication)
|
||||||
.p1(0x04)
|
.p1(0x04)
|
||||||
.data(YK_AID)
|
.data(otp::APPLET_ID)
|
||||||
.transmit(self, 0xFF)?
|
.transmit(self, 0xFF)?
|
||||||
.status_words();
|
.status_words();
|
||||||
|
|
||||||
if !sw.is_success() {
|
if !sw.is_success() {
|
||||||
error!("failed selecting yk application: {:04x}", sw.code());
|
error!("failed selecting yk application: {:04x}", sw.code());
|
||||||
return Err(Error::GenericError);
|
return Err(match sw {
|
||||||
|
StatusWords::NotFoundError => Error::AppletNotFound {
|
||||||
|
applet_name: otp::APPLET_NAME,
|
||||||
|
},
|
||||||
|
_ => Error::GenericError,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let resp = Apdu::new(0x01).p1(0x10).transmit(self, 0xFF)?;
|
let response = Apdu::new(0x01).p1(0x10).transmit(self, 0xFF)?;
|
||||||
|
|
||||||
if !resp.is_success() {
|
if !response.is_success() {
|
||||||
|
// TODO(tarcieri): still reselect the PIV applet in this case?
|
||||||
error!(
|
error!(
|
||||||
"failed retrieving serial number: {:04x}",
|
"failed retrieving serial number: {:04x}",
|
||||||
resp.status_words().code()
|
response.status_words().code()
|
||||||
);
|
);
|
||||||
return Err(Error::GenericError);
|
return Err(Error::GenericError);
|
||||||
}
|
}
|
||||||
@@ -131,35 +138,41 @@ impl<'tx> Transaction<'tx> {
|
|||||||
// reselect the PIV applet
|
// reselect the PIV applet
|
||||||
let sw = Apdu::new(Ins::SelectApplication)
|
let sw = Apdu::new(Ins::SelectApplication)
|
||||||
.p1(0x04)
|
.p1(0x04)
|
||||||
.data(PIV_AID)
|
.data(piv::APPLET_ID)
|
||||||
.transmit(self, 0xFF)?
|
.transmit(self, 0xFF)?
|
||||||
.status_words();
|
.status_words();
|
||||||
|
|
||||||
if !sw.is_success() {
|
if !sw.is_success() {
|
||||||
error!("failed selecting application: {:04x}", sw.code());
|
error!("failed selecting application: {:04x}", sw.code());
|
||||||
return Err(Error::GenericError);
|
return Err(match sw {
|
||||||
|
StatusWords::NotFoundError => Error::AppletNotFound {
|
||||||
|
applet_name: piv::APPLET_NAME,
|
||||||
|
},
|
||||||
|
_ => Error::GenericError,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
resp
|
response.data().try_into()
|
||||||
} else {
|
}
|
||||||
// YK5 implements getting the serial as a PIV applet command (0xf8)
|
|
||||||
let resp = Apdu::new(Ins::GetSerial).transmit(self, 0xFF)?;
|
|
||||||
|
|
||||||
if !resp.is_success() {
|
// YK5 implements getting the serial as a PIV applet command (0xf8)
|
||||||
|
5 => {
|
||||||
|
let response = Apdu::new(Ins::GetSerial).transmit(self, 0xFF)?;
|
||||||
|
|
||||||
|
if !response.is_success() {
|
||||||
error!(
|
error!(
|
||||||
"failed retrieving serial number: {:04x}",
|
"failed retrieving serial number: {:04x}",
|
||||||
resp.status_words().code()
|
response.status_words().code()
|
||||||
);
|
);
|
||||||
return Err(Error::GenericError);
|
return Err(Error::GenericError);
|
||||||
}
|
}
|
||||||
|
|
||||||
resp
|
response.data().try_into()
|
||||||
};
|
}
|
||||||
|
|
||||||
response.data()[..4]
|
// Other versions unsupported
|
||||||
.try_into()
|
_ => Err(Error::NotSupported),
|
||||||
.map(|serial| Serial::from(u32::from_be_bytes(serial)))
|
}
|
||||||
.map_err(|_| Error::SizeError)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Verify device PIN.
|
/// Verify device PIN.
|
||||||
@@ -387,11 +400,12 @@ impl<'tx> Transaction<'tx> {
|
|||||||
.data(&in_data[in_offset..(in_offset + this_size)])
|
.data(&in_data[in_offset..(in_offset + this_size)])
|
||||||
.transmit(self, 261)?;
|
.transmit(self, 261)?;
|
||||||
|
|
||||||
sw = response.status_words().code();
|
sw = response.status_words();
|
||||||
|
|
||||||
if !response.is_success() && (sw >> 8 != 0x61) {
|
match sw {
|
||||||
|
StatusWords::Success | StatusWords::BytesRemaining { .. } => (),
|
||||||
// TODO(tarcieri): is this really OK?
|
// TODO(tarcieri): is this really OK?
|
||||||
return Ok(Response::new(sw.into(), out_data));
|
_ => return Ok(Response::new(sw, out_data)),
|
||||||
}
|
}
|
||||||
|
|
||||||
if !out_data.is_empty() && (out_data.len() - response.data().len() > max_out) {
|
if !out_data.is_empty() && (out_data.len() - response.data().len() > max_out) {
|
||||||
@@ -412,17 +426,15 @@ impl<'tx> Transaction<'tx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while sw >> 8 == 0x61 {
|
while let StatusWords::BytesRemaining { len } = sw {
|
||||||
trace!(
|
trace!("The card indicates there is {} bytes more data for us", len);
|
||||||
"The card indicates there is {} bytes more data for us",
|
|
||||||
sw & 0xff
|
|
||||||
);
|
|
||||||
|
|
||||||
let response = Apdu::new(Ins::GetResponseApdu).transmit(self, 261)?;
|
let response = Apdu::new(Ins::GetResponseApdu).transmit(self, 261)?;
|
||||||
sw = response.status_words().code();
|
sw = response.status_words();
|
||||||
|
|
||||||
if sw != StatusWords::Success.code() && (sw >> 8 != 0x61) {
|
match sw {
|
||||||
return Ok(Response::new(sw.into(), vec![]));
|
StatusWords::Success | StatusWords::BytesRemaining { .. } => (),
|
||||||
|
_ => return Ok(Response::new(sw, vec![])),
|
||||||
}
|
}
|
||||||
|
|
||||||
if out_data.len() + response.data().len() > max_out {
|
if out_data.len() + response.data().len() > max_out {
|
||||||
@@ -438,7 +450,7 @@ impl<'tx> Transaction<'tx> {
|
|||||||
out_data.extend_from_slice(&response.data()[..response.data().len()]);
|
out_data.extend_from_slice(&response.data()[..response.data().len()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Response::new(sw.into(), out_data))
|
Ok(Response::new(sw, out_data))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fetch an object.
|
/// Fetch an object.
|
||||||
|
|||||||
+109
-25
@@ -42,7 +42,7 @@ use crate::{
|
|||||||
transaction::Transaction,
|
transaction::Transaction,
|
||||||
};
|
};
|
||||||
use log::{error, info};
|
use log::{error, info};
|
||||||
use pcsc::Card;
|
use pcsc::{Card, Disposition};
|
||||||
use rand_core::{OsRng, RngCore};
|
use rand_core::{OsRng, RngCore};
|
||||||
use std::{
|
use std::{
|
||||||
fmt::{self, Display},
|
fmt::{self, Display},
|
||||||
@@ -55,6 +55,7 @@ use {
|
|||||||
apdu::StatusWords,
|
apdu::StatusWords,
|
||||||
consts::{TAG_ADMIN_FLAGS_1, TAG_ADMIN_TIMESTAMP},
|
consts::{TAG_ADMIN_FLAGS_1, TAG_ADMIN_TIMESTAMP},
|
||||||
metadata::AdminData,
|
metadata::AdminData,
|
||||||
|
mgm,
|
||||||
transaction::ChangeRefAction,
|
transaction::ChangeRefAction,
|
||||||
Buffer, ObjectId,
|
Buffer, ObjectId,
|
||||||
},
|
},
|
||||||
@@ -71,12 +72,6 @@ pub(crate) const ALGO_3DES: u8 = 0x03;
|
|||||||
/// Card management key
|
/// Card management key
|
||||||
pub(crate) const KEY_CARDMGM: u8 = 0x9b;
|
pub(crate) const KEY_CARDMGM: u8 = 0x9b;
|
||||||
|
|
||||||
/// MGMT Applet ID.
|
|
||||||
///
|
|
||||||
/// <https://developers.yubico.com/PIV/Introduction/Admin_access.html>
|
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
const MGMT_AID: [u8; 8] = [0xa0, 0x00, 0x00, 0x05, 0x27, 0x47, 0x11, 0x17];
|
|
||||||
|
|
||||||
const TAG_DYN_AUTH: u8 = 0x7c;
|
const TAG_DYN_AUTH: u8 = 0x7c;
|
||||||
|
|
||||||
/// Cached YubiKey PIN.
|
/// Cached YubiKey PIN.
|
||||||
@@ -98,6 +93,20 @@ impl From<Serial> for u32 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TryFrom<&[u8]> for Serial {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn try_from(bytes: &[u8]) -> Result<Self> {
|
||||||
|
if bytes.len() > 4 {
|
||||||
|
return Err(Error::SizeError);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut arr = [0u8; 4];
|
||||||
|
arr[(4 - bytes.len())..].copy_from_slice(bytes);
|
||||||
|
Ok(Self(u32::from_be_bytes(arr)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl FromStr for Serial {
|
impl FromStr for Serial {
|
||||||
type Err = Error;
|
type Err = Error;
|
||||||
|
|
||||||
@@ -156,6 +165,16 @@ pub struct YubiKey {
|
|||||||
pub(crate) serial: Serial,
|
pub(crate) serial: Serial,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for YubiKey {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
f.debug_struct("YubiKey")
|
||||||
|
.field("name", &self.name)
|
||||||
|
.field("version", &self.version)
|
||||||
|
.field("serial", &self.serial)
|
||||||
|
.finish_non_exhaustive()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl YubiKey {
|
impl YubiKey {
|
||||||
/// Open a connection to a YubiKey.
|
/// Open a connection to a YubiKey.
|
||||||
///
|
///
|
||||||
@@ -166,12 +185,7 @@ impl YubiKey {
|
|||||||
/// [`yubikey::reader::Context`][`Context`] to select from the available
|
/// [`yubikey::reader::Context`][`Context`] to select from the available
|
||||||
/// PC/SC readers.
|
/// PC/SC readers.
|
||||||
pub fn open() -> Result<Self> {
|
pub fn open() -> Result<Self> {
|
||||||
let mut readers = Context::open().map_err(|e| match e {
|
let mut readers = Context::open()?;
|
||||||
Error::PcscError {
|
|
||||||
inner: Some(pcsc::Error::NoReadersAvailable),
|
|
||||||
} => Error::NotFound,
|
|
||||||
other => other,
|
|
||||||
})?;
|
|
||||||
let mut reader_iter = readers.iter()?;
|
let mut reader_iter = readers.iter()?;
|
||||||
|
|
||||||
if let Some(reader) = reader_iter.next() {
|
if let Some(reader) = reader_iter.next() {
|
||||||
@@ -189,26 +203,42 @@ impl YubiKey {
|
|||||||
|
|
||||||
/// Open a YubiKey with a specific serial number.
|
/// Open a YubiKey with a specific serial number.
|
||||||
pub fn open_by_serial(serial: Serial) -> Result<Self> {
|
pub fn open_by_serial(serial: Serial) -> Result<Self> {
|
||||||
let mut readers = Context::open().map_err(|e| match e {
|
let mut readers = Context::open()?;
|
||||||
Error::PcscError {
|
|
||||||
inner: Some(pcsc::Error::NoReadersAvailable),
|
let mut open_error = None;
|
||||||
} => Error::NotFound,
|
|
||||||
other => other,
|
|
||||||
})?;
|
|
||||||
|
|
||||||
for reader in readers.iter()? {
|
for reader in readers.iter()? {
|
||||||
let yubikey = match reader.open() {
|
let yubikey = match reader.open() {
|
||||||
Ok(yk) => yk,
|
Ok(yk) => yk,
|
||||||
Err(_) => continue,
|
Err(e) => {
|
||||||
|
// Save the first error we see that indicates we might have been able
|
||||||
|
// to find a matching YubiKey.
|
||||||
|
if open_error.is_none() {
|
||||||
|
if let Error::PcscError {
|
||||||
|
inner: Some(pcsc::Error::SharingViolation),
|
||||||
|
} = e
|
||||||
|
{
|
||||||
|
open_error = Some(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if serial == yubikey.serial() {
|
if serial == yubikey.serial() {
|
||||||
return Ok(yubikey);
|
return Ok(yubikey);
|
||||||
|
} else {
|
||||||
|
// We didn't want this YubiKey; don't reset it.
|
||||||
|
let _ = yubikey.disconnect(pcsc::Disposition::LeaveCard);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Err(if let Some(e) = open_error {
|
||||||
|
e
|
||||||
|
} else {
|
||||||
error!("no YubiKey detected with serial: {}", serial);
|
error!("no YubiKey detected with serial: {}", serial);
|
||||||
Err(Error::NotFound)
|
Error::NotFound
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reconnect to a YubiKey.
|
/// Reconnect to a YubiKey.
|
||||||
@@ -238,6 +268,38 @@ impl YubiKey {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Disconnect from the YubiKey.
|
||||||
|
///
|
||||||
|
/// In case of error, ownership of the YubiKey is returned to the caller.
|
||||||
|
///
|
||||||
|
/// # Note
|
||||||
|
///
|
||||||
|
/// `YubiKey` implements `Drop` which automatically disconnects the card using
|
||||||
|
/// `Disposition::ResetCard`; you only need to call this function if you want to
|
||||||
|
/// handle errors or use a different disposition method.
|
||||||
|
pub fn disconnect(self, disposition: Disposition) -> core::result::Result<(), (Self, Error)> {
|
||||||
|
let Self {
|
||||||
|
card,
|
||||||
|
name,
|
||||||
|
pin,
|
||||||
|
version,
|
||||||
|
serial,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
card.disconnect(disposition).map_err(|(card, e)| {
|
||||||
|
(
|
||||||
|
Self {
|
||||||
|
card,
|
||||||
|
name,
|
||||||
|
pin,
|
||||||
|
version,
|
||||||
|
serial,
|
||||||
|
},
|
||||||
|
e.into(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Begin a transaction.
|
/// Begin a transaction.
|
||||||
pub(crate) fn begin_transaction(&mut self) -> Result<Transaction<'_>> {
|
pub(crate) fn begin_transaction(&mut self) -> Result<Transaction<'_>> {
|
||||||
// TODO(tarcieri): reconnect support
|
// TODO(tarcieri): reconnect support
|
||||||
@@ -341,7 +403,7 @@ impl YubiKey {
|
|||||||
|
|
||||||
let status_words = Apdu::new(Ins::SelectApplication)
|
let status_words = Apdu::new(Ins::SelectApplication)
|
||||||
.p1(0x04)
|
.p1(0x04)
|
||||||
.data(MGMT_AID)
|
.data(mgm::APPLET_ID)
|
||||||
.transmit(&txn, 255)?
|
.transmit(&txn, 255)?
|
||||||
.status_words();
|
.status_words();
|
||||||
|
|
||||||
@@ -350,7 +412,12 @@ impl YubiKey {
|
|||||||
"Failed selecting mgmt application: {:04x}",
|
"Failed selecting mgmt application: {:04x}",
|
||||||
status_words.code()
|
status_words.code()
|
||||||
);
|
);
|
||||||
return Err(Error::GenericError);
|
return Err(match status_words {
|
||||||
|
StatusWords::NotFoundError => Error::AppletNotFound {
|
||||||
|
applet_name: mgm::APPLET_NAME,
|
||||||
|
},
|
||||||
|
_ => Error::GenericError,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -636,15 +703,30 @@ impl<'a> TryFrom<&'a Reader<'_>> for YubiKey {
|
|||||||
|
|
||||||
info!("connected to reader: {}", reader.name());
|
info!("connected to reader: {}", reader.name());
|
||||||
|
|
||||||
let (version, serial) = {
|
let mut app_version_serial = || -> Result<(Version, Serial)> {
|
||||||
let txn = Transaction::new(&mut card)?;
|
let txn = Transaction::new(&mut card)?;
|
||||||
txn.select_application()?;
|
txn.select_application()?;
|
||||||
|
|
||||||
let v = txn.get_version()?;
|
let v = txn.get_version()?;
|
||||||
let s = txn.get_serial(v)?;
|
let s = txn.get_serial(v)?;
|
||||||
(v, s)
|
Ok((v, s))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
match app_version_serial() {
|
||||||
|
Err(e) => {
|
||||||
|
error!("Could not use reader: {}", e);
|
||||||
|
|
||||||
|
// We were unable to use the card, so we've effectively only connected as
|
||||||
|
// a side-effect of determining this. Avoid disrupting its internal state
|
||||||
|
// any further (e.g. preserve the PIN cache of whatever applet is selected
|
||||||
|
// currently).
|
||||||
|
if let Err((_, e)) = card.disconnect(pcsc::Disposition::LeaveCard) {
|
||||||
|
error!("Failed to disconnect gracefully from card: {}", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(e)
|
||||||
|
}
|
||||||
|
Ok((version, serial)) => {
|
||||||
let yubikey = YubiKey {
|
let yubikey = YubiKey {
|
||||||
card,
|
card,
|
||||||
name: String::from(reader.name()),
|
name: String::from(reader.name()),
|
||||||
@@ -656,3 +738,5 @@ impl<'a> TryFrom<&'a Reader<'_>> for YubiKey {
|
|||||||
Ok(yubikey)
|
Ok(yubikey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use once_cell::sync::Lazy;
|
|||||||
use rand_core::{OsRng, RngCore};
|
use rand_core::{OsRng, RngCore};
|
||||||
use rsa::pkcs1v15;
|
use rsa::pkcs1v15;
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
use signature::{hazmat::PrehashVerifier, Signature as _};
|
use signature::hazmat::PrehashVerifier;
|
||||||
use std::{env, str::FromStr, sync::Mutex};
|
use std::{env, str::FromStr, sync::Mutex};
|
||||||
use x509::RelativeDistinguishedName;
|
use x509::RelativeDistinguishedName;
|
||||||
use yubikey::{
|
use yubikey::{
|
||||||
@@ -203,7 +203,7 @@ fn generate_self_signed_rsa_cert() {
|
|||||||
let data = cert.as_ref();
|
let data = cert.as_ref();
|
||||||
let tbs_cert_len = u16::from_be_bytes(data[6..8].try_into().unwrap()) as usize;
|
let tbs_cert_len = u16::from_be_bytes(data[6..8].try_into().unwrap()) as usize;
|
||||||
let msg = &data[4..8 + tbs_cert_len];
|
let msg = &data[4..8 + tbs_cert_len];
|
||||||
let sig = pkcs1v15::Signature::from_bytes(&data[data.len() - 128..]).unwrap();
|
let sig = pkcs1v15::Signature::try_from(&data[data.len() - 128..]).unwrap();
|
||||||
let hash = Sha256::digest(msg);
|
let hash = Sha256::digest(msg);
|
||||||
|
|
||||||
assert!(pubkey.verify_prehash(&hash, &sig).is_ok());
|
assert!(pubkey.verify_prehash(&hash, &sig).is_ok());
|
||||||
|
|||||||
Reference in New Issue
Block a user