Merge pull request #80 from str4d/cert-gen
Certificate::generate_self_signed
This commit is contained in:
Generated
+200
@@ -8,6 +8,11 @@ dependencies = [
|
|||||||
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anyhow"
|
||||||
|
version = "1.0.25"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arrayvec"
|
name = "arrayvec"
|
||||||
version = "0.4.12"
|
version = "0.4.12"
|
||||||
@@ -99,6 +104,11 @@ dependencies = [
|
|||||||
"byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bumpalo"
|
||||||
|
version = "2.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byte-tools"
|
name = "byte-tools"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
@@ -127,6 +137,16 @@ name = "cfg-if"
|
|||||||
version = "0.1.10"
|
version = "0.1.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chrono"
|
||||||
|
version = "0.4.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cloudabi"
|
name = "cloudabi"
|
||||||
version = "0.0.3"
|
version = "0.0.3"
|
||||||
@@ -135,6 +155,11 @@ dependencies = [
|
|||||||
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cookie-factory"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crypto-mac"
|
name = "crypto-mac"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
@@ -261,6 +286,14 @@ dependencies = [
|
|||||||
"syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hmac"
|
name = "hmac"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
@@ -278,6 +311,14 @@ dependencies = [
|
|||||||
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "js-sys"
|
||||||
|
version = "0.3.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"wasm-bindgen 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
@@ -326,6 +367,15 @@ name = "nodrop"
|
|||||||
version = "0.1.14"
|
version = "0.1.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom"
|
||||||
|
version = "4.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nom"
|
name = "nom"
|
||||||
version = "5.0.1"
|
version = "5.0.1"
|
||||||
@@ -344,6 +394,7 @@ dependencies = [
|
|||||||
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -541,6 +592,20 @@ name = "regex-syntax"
|
|||||||
version = "0.6.12"
|
version = "0.6.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ring"
|
||||||
|
version = "0.16.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"web-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rsa"
|
name = "rsa"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
@@ -642,6 +707,11 @@ name = "smallvec"
|
|||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sourcefile"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spin"
|
name = "spin"
|
||||||
version = "0.5.2"
|
version = "0.5.2"
|
||||||
@@ -722,11 +792,21 @@ name = "typenum"
|
|||||||
version = "1.11.2"
|
version = "1.11.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-segmentation"
|
||||||
|
version = "1.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-xid"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "untrusted"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "version_check"
|
name = "version_check"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
@@ -737,6 +817,90 @@ name = "wasi"
|
|||||||
version = "0.7.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"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen"
|
||||||
|
version = "0.2.55"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"wasm-bindgen-macro 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-backend"
|
||||||
|
version = "0.2.55"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"wasm-bindgen-shared 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro"
|
||||||
|
version = "0.2.55"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"wasm-bindgen-macro-support 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro-support"
|
||||||
|
version = "0.2.55"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"wasm-bindgen-backend 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"wasm-bindgen-shared 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-shared"
|
||||||
|
version = "0.2.55"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-webidl"
|
||||||
|
version = "0.2.55"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"wasm-bindgen-backend 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "web-sys"
|
||||||
|
version = "0.3.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"js-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"wasm-bindgen 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"wasm-bindgen-webidl 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "weedle"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.8"
|
version = "0.3.8"
|
||||||
@@ -773,6 +937,15 @@ dependencies = [
|
|||||||
"winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "x509"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cookie-factory 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "x509-parser"
|
name = "x509-parser"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
@@ -801,6 +974,8 @@ dependencies = [
|
|||||||
name = "yubikey-piv"
|
name = "yubikey-piv"
|
||||||
version = "0.0.3"
|
version = "0.0.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cookie-factory 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"der-parser 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"der-parser 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"des 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"des 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"elliptic-curve 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"elliptic-curve 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -810,13 +985,18 @@ dependencies = [
|
|||||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"nom 5.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"nom 5.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pcsc 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pcsc 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ring 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rsa 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rsa 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"secrecy 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"secrecy 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"subtle-encoding 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"subtle-encoding 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"x509 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"x509-parser 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"x509-parser 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"zeroize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"zeroize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@@ -842,6 +1022,7 @@ dependencies = [
|
|||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d"
|
"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d"
|
||||||
|
"checksum anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "9267dff192e68f3399525901e709a48c1d3982c9c072fa32f2127a0cb0babf14"
|
||||||
"checksum arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9"
|
"checksum arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9"
|
||||||
"checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90"
|
"checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90"
|
||||||
"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
|
"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
|
||||||
@@ -853,12 +1034,15 @@ dependencies = [
|
|||||||
"checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
|
"checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
|
||||||
"checksum block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774"
|
"checksum block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774"
|
||||||
"checksum block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
|
"checksum block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
|
||||||
|
"checksum bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad807f2fc2bf185eeb98ff3a901bd46dc5ad58163d0fa4577ba0d25674d71708"
|
||||||
"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
|
"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
|
||||||
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
|
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
|
||||||
"checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb"
|
"checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb"
|
||||||
"checksum cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)" = "f52a465a666ca3d838ebbf08b241383421412fe7ebb463527bba275526d89f76"
|
"checksum cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)" = "f52a465a666ca3d838ebbf08b241383421412fe7ebb463527bba275526d89f76"
|
||||||
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||||
|
"checksum chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01"
|
||||||
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||||
|
"checksum cookie-factory 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5f2b81f8a9b8f5ffa2ed91a82c53392837eab151baf682acf8322c909b6d4fe9"
|
||||||
"checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5"
|
"checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5"
|
||||||
"checksum der-parser 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "537a7d6becb8c3cae3bab31439c248a12d43267ccc0b1a0333362b7cefb61c3e"
|
"checksum der-parser 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "537a7d6becb8c3cae3bab31439c248a12d43267ccc0b1a0333362b7cefb61c3e"
|
||||||
"checksum des 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74ba5f1b5aee9772379c2670ba81306e65a93c0ee3caade7a1d22b188d88a3af"
|
"checksum des 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74ba5f1b5aee9772379c2670ba81306e65a93c0ee3caade7a1d22b188d88a3af"
|
||||||
@@ -873,8 +1057,10 @@ dependencies = [
|
|||||||
"checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407"
|
"checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407"
|
||||||
"checksum gumdrop 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee50908bc1beeac1f2902e0b4e0cd0d844e716f5ebdc6f0cfc1163fe5e10bcde"
|
"checksum gumdrop 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee50908bc1beeac1f2902e0b4e0cd0d844e716f5ebdc6f0cfc1163fe5e10bcde"
|
||||||
"checksum gumdrop_derive 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "90454ce4de40b7ca6a8968b5ef367bdab48413962588d0d2b1638d60090c35d7"
|
"checksum gumdrop_derive 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "90454ce4de40b7ca6a8968b5ef367bdab48413962588d0d2b1638d60090c35d7"
|
||||||
|
"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
|
||||||
"checksum hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695"
|
"checksum hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695"
|
||||||
"checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
|
"checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
|
||||||
|
"checksum js-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)" = "1c840fdb2167497b0bd0db43d6dfe61e91637fa72f9d061f8bd17ddc44ba6414"
|
||||||
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
"checksum lexical-core 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2304bccb228c4b020f3a4835d247df0a02a7c4686098d4167762cfbbe4c5cb14"
|
"checksum lexical-core 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2304bccb228c4b020f3a4835d247df0a02a7c4686098d4167762cfbbe4c5cb14"
|
||||||
"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
|
"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
|
||||||
@@ -882,6 +1068,7 @@ dependencies = [
|
|||||||
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
||||||
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
|
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
|
||||||
"checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
|
"checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
|
||||||
|
"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
|
||||||
"checksum nom 5.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c618b63422da4401283884e6668d39f819a106ef51f5f59b81add00075da35ca"
|
"checksum nom 5.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c618b63422da4401283884e6668d39f819a106ef51f5f59b81add00075da35ca"
|
||||||
"checksum num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f9c3f34cdd24f334cb265d9bf8bfa8a241920d026916785747a92f0e55541a1a"
|
"checksum num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f9c3f34cdd24f334cb265d9bf8bfa8a241920d026916785747a92f0e55541a1a"
|
||||||
"checksum num-bigint-dig 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3d03c330f9f7a2c19e3c0b42698e48141d0809c78cd9b6219f85bd7d7e892aa"
|
"checksum num-bigint-dig 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3d03c330f9f7a2c19e3c0b42698e48141d0809c78cd9b6219f85bd7d7e892aa"
|
||||||
@@ -907,6 +1094,7 @@ dependencies = [
|
|||||||
"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
|
"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
|
||||||
"checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd"
|
"checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd"
|
||||||
"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716"
|
"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716"
|
||||||
|
"checksum ring 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6747f8da1f2b1fabbee1aaa4eb8a11abf9adef0bf58a41cee45db5d59cecdfac"
|
||||||
"checksum rsa 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6ed8692d8e0ea3baae03f0f32ecfc13a6c6f1f85fcd6d9fdefcdf364e70f4df9"
|
"checksum rsa 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6ed8692d8e0ea3baae03f0f32ecfc13a6c6f1f85fcd6d9fdefcdf364e70f4df9"
|
||||||
"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
|
"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
|
||||||
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||||
@@ -920,6 +1108,7 @@ dependencies = [
|
|||||||
"checksum sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "23962131a91661d643c98940b20fcaffe62d776a823247be80a48fcb8b6fce68"
|
"checksum sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "23962131a91661d643c98940b20fcaffe62d776a823247be80a48fcb8b6fce68"
|
||||||
"checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d"
|
"checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d"
|
||||||
"checksum smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ecf3b85f68e8abaa7555aa5abdb1153079387e60b718283d732f03897fcfc86"
|
"checksum smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ecf3b85f68e8abaa7555aa5abdb1153079387e60b718283d732f03897fcfc86"
|
||||||
|
"checksum sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3"
|
||||||
"checksum spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
"checksum spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||||
"checksum static_assertions 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7f3eb36b47e512f8f1c9e3d10c2c1965bc992bd9cdb024fa581e2194501c83d3"
|
"checksum static_assertions 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7f3eb36b47e512f8f1c9e3d10c2c1965bc992bd9cdb024fa581e2194501c83d3"
|
||||||
"checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee"
|
"checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee"
|
||||||
@@ -931,14 +1120,25 @@ dependencies = [
|
|||||||
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
|
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
|
||||||
"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
|
"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
|
||||||
"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
|
"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
|
||||||
|
"checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
|
||||||
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
|
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
|
||||||
|
"checksum untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60369ef7a31de49bcb3f6ca728d4ba7300d9a1658f94c727d4cab8c8d9f4aece"
|
||||||
"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
|
"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
|
||||||
"checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d"
|
"checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d"
|
||||||
|
"checksum wasm-bindgen 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)" = "29ae32af33bacd663a9a28241abecf01f2be64e6a185c6139b04f18b6385c5f2"
|
||||||
|
"checksum wasm-bindgen-backend 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)" = "1845584bd3593442dc0de6e6d9f84454a59a057722f36f005e44665d6ab19d85"
|
||||||
|
"checksum wasm-bindgen-macro 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)" = "87fcc747e6b73c93d22c947a6334644d22cfec5abd8b66238484dc2b0aeb9fe4"
|
||||||
|
"checksum wasm-bindgen-macro-support 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)" = "3dc4b3f2c4078c8c4a5f363b92fcf62604c5913cbd16c6ff5aaf0f74ec03f570"
|
||||||
|
"checksum wasm-bindgen-shared 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)" = "ca0b78d6d3be8589b95d1d49cdc0794728ca734adf36d7c9f07e6459508bb53d"
|
||||||
|
"checksum wasm-bindgen-webidl 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)" = "3126356474ceb717c8fb5549ae387c9fbf4872818454f4d87708bee997214bb5"
|
||||||
|
"checksum web-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)" = "98405c0a2e722ed3db341b4c5b70eb9fe0021621f7350bab76df93b09b649bbf"
|
||||||
|
"checksum weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bb43f70885151e629e2a19ce9e50bd730fd436cfd4b666894c9ce4de9141164"
|
||||||
"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
|
"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
|
||||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9"
|
"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9"
|
||||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
"checksum wincolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "96f5016b18804d24db43cebf3c77269e7569b8954a8464501c216cc5e070eaa9"
|
"checksum wincolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "96f5016b18804d24db43cebf3c77269e7569b8954a8464501c216cc5e070eaa9"
|
||||||
|
"checksum x509 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eddce2e179aee785295bff6e72e6f36cc7dc3011e01231100270b6b25de9ec60"
|
||||||
"checksum x509-parser 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b86b92815858495482b74dab17c0b2b2399f7582b6e7ca621b87aebf8fd00e9"
|
"checksum x509-parser 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b86b92815858495482b74dab17c0b2b2399f7582b6e7ca621b87aebf8fd00e9"
|
||||||
"checksum zeroize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3cbac2ed2ba24cc90f5e06485ac8c7c1e5449fe8911aef4d8877218af021a5b8"
|
"checksum zeroize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3cbac2ed2ba24cc90f5e06485ac8c7c1e5449fe8911aef4d8877218af021a5b8"
|
||||||
"checksum zeroize_derive 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de251eec69fc7c1bc3923403d18ececb929380e016afe103da75f396704f8ca2"
|
"checksum zeroize_derive 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de251eec69fc7c1bc3923403d18ececb929380e016afe103da75f396704f8ca2"
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ members = [".", "cli"]
|
|||||||
maintenance = { status = "experimental" }
|
maintenance = { status = "experimental" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
chrono = "0.4"
|
||||||
|
cookie-factory = "0.3"
|
||||||
der-parser = "3"
|
der-parser = "3"
|
||||||
des = "0.3"
|
des = "0.3"
|
||||||
elliptic-curve = "0.2"
|
elliptic-curve = "0.2"
|
||||||
@@ -29,18 +31,23 @@ getrandom = "0.1"
|
|||||||
hmac = "0.7"
|
hmac = "0.7"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
nom = "5"
|
nom = "5"
|
||||||
|
num-bigint = { version = "0.2", features = ["rand"] }
|
||||||
pbkdf2 = "0.3"
|
pbkdf2 = "0.3"
|
||||||
pcsc = "2"
|
pcsc = "2"
|
||||||
rsa = "0.2.0"
|
rsa = "0.2.0"
|
||||||
secrecy = "0.6"
|
secrecy = "0.6"
|
||||||
sha-1 = "0.8"
|
sha-1 = "0.8"
|
||||||
|
sha2 = "0.8"
|
||||||
subtle = "2"
|
subtle = "2"
|
||||||
subtle-encoding = "0.5"
|
subtle-encoding = "0.5"
|
||||||
|
x509 = "0.1.1"
|
||||||
x509-parser = "0.6"
|
x509-parser = "0.6"
|
||||||
zeroize = "1"
|
zeroize = "1"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
env_logger = "0.7"
|
env_logger = "0.7"
|
||||||
|
rand = "0.5"
|
||||||
|
ring = "0.16.9"
|
||||||
lazy_static = "1"
|
lazy_static = "1"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|||||||
@@ -276,7 +276,6 @@ impl Response {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the raw [`StatusWords`] code for this response.
|
/// Get the raw [`StatusWords`] code for this response.
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
pub fn code(&self) -> u16 {
|
pub fn code(&self) -> u16 {
|
||||||
self.status_words.code()
|
self.status_words.code()
|
||||||
}
|
}
|
||||||
|
|||||||
+304
-9
@@ -32,24 +32,27 @@
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::Error,
|
error::Error,
|
||||||
key::{AlgorithmId, SlotId},
|
key::{sign_data, AlgorithmId, SlotId},
|
||||||
serialization::*,
|
serialization::*,
|
||||||
transaction::Transaction,
|
transaction::Transaction,
|
||||||
yubikey::YubiKey,
|
yubikey::YubiKey,
|
||||||
Buffer,
|
Buffer,
|
||||||
};
|
};
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
use elliptic_curve::weierstrass::{
|
use elliptic_curve::weierstrass::{
|
||||||
curve::{NistP256, NistP384},
|
curve::{NistP256, NistP384},
|
||||||
PublicKey as EcPublicKey,
|
PublicKey as EcPublicKey,
|
||||||
};
|
};
|
||||||
use log::error;
|
use log::error;
|
||||||
|
use num_bigint::BigUint;
|
||||||
use rsa::{PublicKey, RSAPublicKey};
|
use rsa::{PublicKey, RSAPublicKey};
|
||||||
|
use sha2::{Digest, Sha256};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::ops::DerefMut;
|
||||||
use x509_parser::{parse_x509_der, x509::SubjectPublicKeyInfo};
|
use x509_parser::{parse_x509_der, x509::SubjectPublicKeyInfo};
|
||||||
use zeroize::Zeroizing;
|
use zeroize::Zeroizing;
|
||||||
|
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
use crate::CB_OBJ_MAX;
|
use crate::CB_OBJ_MAX;
|
||||||
|
|
||||||
// TODO: Make these der_parser::oid::Oid constants when it has const fn support.
|
// TODO: Make these der_parser::oid::Oid constants when it has const fn support.
|
||||||
@@ -59,11 +62,43 @@ const OID_NIST_P256: &str = "1.2.840.10045.3.1.7";
|
|||||||
const OID_NIST_P384: &str = "1.3.132.0.34";
|
const OID_NIST_P384: &str = "1.3.132.0.34";
|
||||||
|
|
||||||
const TAG_CERT: u8 = 0x70;
|
const TAG_CERT: u8 = 0x70;
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
const TAG_CERT_COMPRESS: u8 = 0x71;
|
const TAG_CERT_COMPRESS: u8 = 0x71;
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
const TAG_CERT_LRC: u8 = 0xFE;
|
const TAG_CERT_LRC: u8 = 0xFE;
|
||||||
|
|
||||||
|
/// A serial number for a [`Certificate`].
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct Serial(BigUint);
|
||||||
|
|
||||||
|
impl From<BigUint> for Serial {
|
||||||
|
fn from(num: BigUint) -> Serial {
|
||||||
|
Serial(num)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<[u8; 20]> for Serial {
|
||||||
|
fn from(bytes: [u8; 20]) -> Serial {
|
||||||
|
Serial(BigUint::from_bytes_be(&bytes))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<&[u8]> for Serial {
|
||||||
|
type Error = ();
|
||||||
|
|
||||||
|
fn try_from(bytes: &[u8]) -> Result<Serial, ()> {
|
||||||
|
if bytes.len() <= 20 {
|
||||||
|
Ok(Serial(BigUint::from_bytes_be(&bytes)))
|
||||||
|
} else {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Serial {
|
||||||
|
fn to_bytes(&self) -> Vec<u8> {
|
||||||
|
self.0.to_bytes_be()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Information about how a [`Certificate`] is stored within a YubiKey.
|
/// Information about how a [`Certificate`] is stored within a YubiKey.
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
pub enum CertInfo {
|
pub enum CertInfo {
|
||||||
@@ -95,6 +130,40 @@ impl From<CertInfo> for u8 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl x509::AlgorithmIdentifier for AlgorithmId {
|
||||||
|
type AlgorithmOid = &'static [u64];
|
||||||
|
|
||||||
|
fn algorithm(&self) -> Self::AlgorithmOid {
|
||||||
|
match self {
|
||||||
|
// RSA encryption
|
||||||
|
AlgorithmId::Rsa1024 | AlgorithmId::Rsa2048 => &[1, 2, 840, 113_549, 1, 1, 1],
|
||||||
|
// EC Public Key
|
||||||
|
AlgorithmId::EccP256 | AlgorithmId::EccP384 => &[1, 2, 840, 10045, 2, 1],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parameters<W: std::io::Write>(
|
||||||
|
&self,
|
||||||
|
w: cookie_factory::WriteContext<W>,
|
||||||
|
) -> cookie_factory::GenResult<W> {
|
||||||
|
use x509::der::write::der_oid;
|
||||||
|
|
||||||
|
// From [RFC 5480](https://tools.ietf.org/html/rfc5480#section-2.1.1):
|
||||||
|
// ```text
|
||||||
|
// ECParameters ::= CHOICE {
|
||||||
|
// namedCurve OBJECT IDENTIFIER
|
||||||
|
// -- implicitCurve NULL
|
||||||
|
// -- specifiedCurve SpecifiedECDomain
|
||||||
|
// }
|
||||||
|
// ```
|
||||||
|
match self {
|
||||||
|
AlgorithmId::EccP256 => der_oid(&[1, 2, 840, 10045, 3, 1, 7][..])(w),
|
||||||
|
AlgorithmId::EccP384 => der_oid(&[1, 3, 132, 0, 34][..])(w),
|
||||||
|
_ => Ok(w),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Information about a public key within a [`Certificate`].
|
/// Information about a public key within a [`Certificate`].
|
||||||
#[derive(Clone, Eq, PartialEq)]
|
#[derive(Clone, Eq, PartialEq)]
|
||||||
pub enum PublicKeyInfo {
|
pub enum PublicKeyInfo {
|
||||||
@@ -161,9 +230,92 @@ impl PublicKeyInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl x509::SubjectPublicKeyInfo for PublicKeyInfo {
|
||||||
|
type AlgorithmId = AlgorithmId;
|
||||||
|
type SubjectPublicKey = Vec<u8>;
|
||||||
|
|
||||||
|
fn algorithm_id(&self) -> AlgorithmId {
|
||||||
|
self.algorithm()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn public_key(&self) -> Vec<u8> {
|
||||||
|
match self {
|
||||||
|
PublicKeyInfo::Rsa { pubkey, .. } => {
|
||||||
|
cookie_factory::gen_simple(write_pki::rsa_pubkey(pubkey), vec![])
|
||||||
|
.expect("can write to Vec")
|
||||||
|
}
|
||||||
|
PublicKeyInfo::EcP256(pubkey) => pubkey.as_bytes().to_vec(),
|
||||||
|
PublicKeyInfo::EcP384(pubkey) => pubkey.as_bytes().to_vec(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Digest algorithms.
|
||||||
|
///
|
||||||
|
/// See RFC 4055 and RFC 8017.
|
||||||
|
enum DigestId {
|
||||||
|
/// Secure Hash Algorithm 256 (SHA256)
|
||||||
|
Sha256,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl x509::AlgorithmIdentifier for DigestId {
|
||||||
|
type AlgorithmOid = &'static [u64];
|
||||||
|
|
||||||
|
fn algorithm(&self) -> Self::AlgorithmOid {
|
||||||
|
match self {
|
||||||
|
// See https://tools.ietf.org/html/rfc4055#section-2.1
|
||||||
|
DigestId::Sha256 => &[2, 16, 840, 1, 101, 3, 4, 2, 1],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parameters<W: std::io::Write>(
|
||||||
|
&self,
|
||||||
|
w: cookie_factory::WriteContext<W>,
|
||||||
|
) -> cookie_factory::GenResult<W> {
|
||||||
|
// Parameters are an explicit NULL
|
||||||
|
// See https://tools.ietf.org/html/rfc8017#appendix-A.2.4
|
||||||
|
x509::der::write::der_null()(w)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum SignatureId {
|
||||||
|
/// Public-Key Cryptography Standards (PKCS) #1 version 1.5 signature algorithm with
|
||||||
|
/// Secure Hash Algorithm 256 (SHA256) and Rivest, Shamir and Adleman (RSA) encryption
|
||||||
|
///
|
||||||
|
/// See RFC 4055 and RFC 8017.
|
||||||
|
Sha256WithRsaEncryption,
|
||||||
|
|
||||||
|
/// Elliptic Curve Digital Signature Algorithm (DSA) coupled with the Secure Hash
|
||||||
|
/// Algorithm 256 (SHA256) algorithm
|
||||||
|
///
|
||||||
|
/// See RFC 5758.
|
||||||
|
EcdsaWithSha256,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl x509::AlgorithmIdentifier for SignatureId {
|
||||||
|
type AlgorithmOid = &'static [u64];
|
||||||
|
|
||||||
|
fn algorithm(&self) -> Self::AlgorithmOid {
|
||||||
|
match self {
|
||||||
|
SignatureId::Sha256WithRsaEncryption => &[1, 2, 840, 113_549, 1, 1, 11],
|
||||||
|
SignatureId::EcdsaWithSha256 => &[1, 2, 840, 10045, 4, 3, 2],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parameters<W: std::io::Write>(
|
||||||
|
&self,
|
||||||
|
w: cookie_factory::WriteContext<W>,
|
||||||
|
) -> cookie_factory::GenResult<W> {
|
||||||
|
// No parameters for any SignatureId
|
||||||
|
Ok(w)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Certificates
|
/// Certificates
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Certificate {
|
pub struct Certificate {
|
||||||
|
serial: Serial,
|
||||||
|
issuer: String,
|
||||||
subject: String,
|
subject: String,
|
||||||
subject_pki: PublicKeyInfo,
|
subject_pki: PublicKeyInfo,
|
||||||
data: Buffer,
|
data: Buffer,
|
||||||
@@ -178,6 +330,109 @@ impl<'a> TryFrom<&'a [u8]> for Certificate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Certificate {
|
impl Certificate {
|
||||||
|
/// Creates a new self-signed certificate for the given key. Writes the resulting
|
||||||
|
/// certificate to the slot before returning it.
|
||||||
|
pub fn generate_self_signed(
|
||||||
|
yubikey: &mut YubiKey,
|
||||||
|
key: SlotId,
|
||||||
|
serial: impl Into<Serial>,
|
||||||
|
not_after: Option<DateTime<Utc>>,
|
||||||
|
subject: String,
|
||||||
|
subject_pki: PublicKeyInfo,
|
||||||
|
) -> Result<Self, Error> {
|
||||||
|
let serial = serial.into();
|
||||||
|
|
||||||
|
// Issuer and subject are the same in self-signed certificates
|
||||||
|
let issuer = subject.clone();
|
||||||
|
|
||||||
|
let mut tbs_cert = Buffer::new(Vec::with_capacity(CB_OBJ_MAX));
|
||||||
|
|
||||||
|
let signature_algorithm = match subject_pki.algorithm() {
|
||||||
|
AlgorithmId::Rsa1024 | AlgorithmId::Rsa2048 => SignatureId::Sha256WithRsaEncryption,
|
||||||
|
AlgorithmId::EccP256 | AlgorithmId::EccP384 => SignatureId::EcdsaWithSha256,
|
||||||
|
};
|
||||||
|
|
||||||
|
cookie_factory::gen(
|
||||||
|
x509::write::tbs_certificate(
|
||||||
|
&serial.to_bytes(),
|
||||||
|
&signature_algorithm,
|
||||||
|
&issuer,
|
||||||
|
Utc::now(),
|
||||||
|
not_after,
|
||||||
|
&subject,
|
||||||
|
&subject_pki,
|
||||||
|
),
|
||||||
|
tbs_cert.deref_mut(),
|
||||||
|
)
|
||||||
|
.expect("can serialize to Vec");
|
||||||
|
|
||||||
|
let signature = match signature_algorithm {
|
||||||
|
SignatureId::Sha256WithRsaEncryption => {
|
||||||
|
use cookie_factory::{combinator::slice, sequence::tuple};
|
||||||
|
use x509::{
|
||||||
|
der::write::{der_octet_string, der_sequence},
|
||||||
|
write::algorithm_identifier,
|
||||||
|
};
|
||||||
|
|
||||||
|
let em_len = if let AlgorithmId::Rsa1024 = subject_pki.algorithm() {
|
||||||
|
128
|
||||||
|
} else {
|
||||||
|
256
|
||||||
|
};
|
||||||
|
|
||||||
|
let h = Sha256::digest(&tbs_cert);
|
||||||
|
|
||||||
|
let t = cookie_factory::gen_simple(
|
||||||
|
der_sequence((
|
||||||
|
algorithm_identifier(&DigestId::Sha256),
|
||||||
|
der_octet_string(&h),
|
||||||
|
)),
|
||||||
|
vec![],
|
||||||
|
)
|
||||||
|
.expect("can serialize into Vec");
|
||||||
|
|
||||||
|
let em = cookie_factory::gen_simple(
|
||||||
|
tuple((
|
||||||
|
slice(&[0x00, 0x01]),
|
||||||
|
slice(&vec![0xff; em_len - t.len() - 3]),
|
||||||
|
slice(&[0x00]),
|
||||||
|
slice(t),
|
||||||
|
)),
|
||||||
|
vec![],
|
||||||
|
)
|
||||||
|
.expect("can serialize to Vec");
|
||||||
|
|
||||||
|
sign_data(yubikey, &em, subject_pki.algorithm(), key)
|
||||||
|
}
|
||||||
|
SignatureId::EcdsaWithSha256 => sign_data(
|
||||||
|
yubikey,
|
||||||
|
&Sha256::digest(&tbs_cert),
|
||||||
|
subject_pki.algorithm(),
|
||||||
|
key,
|
||||||
|
),
|
||||||
|
}?;
|
||||||
|
|
||||||
|
let mut data = Buffer::new(Vec::with_capacity(CB_OBJ_MAX));
|
||||||
|
|
||||||
|
cookie_factory::gen(
|
||||||
|
x509::write::certificate(&tbs_cert, &signature_algorithm, &signature),
|
||||||
|
data.deref_mut(),
|
||||||
|
)
|
||||||
|
.expect("can serialize to Vec");
|
||||||
|
|
||||||
|
let cert = Certificate {
|
||||||
|
serial,
|
||||||
|
issuer,
|
||||||
|
subject,
|
||||||
|
subject_pki,
|
||||||
|
data,
|
||||||
|
};
|
||||||
|
|
||||||
|
cert.write(yubikey, key, CertInfo::Uncompressed)?;
|
||||||
|
|
||||||
|
Ok(cert)
|
||||||
|
}
|
||||||
|
|
||||||
/// Read a certificate from the given slot in the YubiKey
|
/// Read a certificate from the given slot in the YubiKey
|
||||||
pub fn read(yubikey: &mut YubiKey, slot: SlotId) -> Result<Self, Error> {
|
pub fn read(yubikey: &mut YubiKey, slot: SlotId) -> Result<Self, Error> {
|
||||||
let txn = yubikey.begin_transaction()?;
|
let txn = yubikey.begin_transaction()?;
|
||||||
@@ -191,7 +446,6 @@ impl Certificate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Write this certificate into the YubiKey in the given slot
|
/// Write this certificate into the YubiKey in the given slot
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
pub fn write(
|
pub fn write(
|
||||||
&self,
|
&self,
|
||||||
yubikey: &mut YubiKey,
|
yubikey: &mut YubiKey,
|
||||||
@@ -223,16 +477,30 @@ impl Certificate {
|
|||||||
_ => return Err(Error::InvalidObject),
|
_ => return Err(Error::InvalidObject),
|
||||||
};
|
};
|
||||||
|
|
||||||
let subject = format!("{}", parsed_cert.tbs_certificate.subject);
|
let serial = parsed_cert.tbs_certificate.serial.into();
|
||||||
|
let issuer = parsed_cert.tbs_certificate.issuer.to_string();
|
||||||
|
let subject = parsed_cert.tbs_certificate.subject.to_string();
|
||||||
let subject_pki = PublicKeyInfo::parse(&parsed_cert.tbs_certificate.subject_pki)?;
|
let subject_pki = PublicKeyInfo::parse(&parsed_cert.tbs_certificate.subject_pki)?;
|
||||||
|
|
||||||
Ok(Certificate {
|
Ok(Certificate {
|
||||||
|
serial,
|
||||||
|
issuer,
|
||||||
subject,
|
subject,
|
||||||
subject_pki,
|
subject_pki,
|
||||||
data: cert,
|
data: cert,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the serial number of the certificate.
|
||||||
|
pub fn serial(&self) -> &Serial {
|
||||||
|
&self.serial
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the Issuer field of the certificate.
|
||||||
|
pub fn issuer(&self) -> &str {
|
||||||
|
&self.subject
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the SubjectName field of the certificate.
|
/// Returns the SubjectName field of the certificate.
|
||||||
pub fn subject(&self) -> &str {
|
pub fn subject(&self) -> &str {
|
||||||
&self.subject
|
&self.subject
|
||||||
@@ -279,7 +547,6 @@ pub(crate) fn read_certificate(txn: &Transaction<'_>, slot: SlotId) -> Result<Bu
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Write certificate
|
/// Write certificate
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
pub(crate) fn write_certificate(
|
pub(crate) fn write_certificate(
|
||||||
txn: &Transaction<'_>,
|
txn: &Transaction<'_>,
|
||||||
slot: SlotId,
|
slot: SlotId,
|
||||||
@@ -298,8 +565,8 @@ pub(crate) fn write_certificate(
|
|||||||
let mut offset = Tlv::write(&mut buf, TAG_CERT, data)?;
|
let mut offset = Tlv::write(&mut buf, TAG_CERT, data)?;
|
||||||
|
|
||||||
// write compression info and LRC trailer
|
// write compression info and LRC trailer
|
||||||
offset += Tlv::write(&mut buf, TAG_CERT_COMPRESS, &[certinfo.into()])?;
|
offset += Tlv::write(&mut buf[offset..], TAG_CERT_COMPRESS, &[certinfo.into()])?;
|
||||||
offset += Tlv::write(&mut buf, TAG_CERT_LRC, &[])?;
|
offset += Tlv::write(&mut buf[offset..], TAG_CERT_LRC, &[])?;
|
||||||
|
|
||||||
txn.save_object(object_id, &buf[..offset])
|
txn.save_object(object_id, &buf[..offset])
|
||||||
}
|
}
|
||||||
@@ -378,3 +645,31 @@ mod read_pki {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod write_pki {
|
||||||
|
use cookie_factory::{SerializeFn, WriteContext};
|
||||||
|
use rsa::{BigUint, PublicKey, RSAPublicKey};
|
||||||
|
use std::io::Write;
|
||||||
|
use x509::der::write::{der_integer, der_sequence};
|
||||||
|
|
||||||
|
/// Encodes a usize as an ASN.1 integer using DER.
|
||||||
|
fn der_integer_biguint<'a, W: Write + 'a>(num: &'a BigUint) -> impl SerializeFn<W> + 'a {
|
||||||
|
move |w: WriteContext<W>| der_integer(&num.to_bytes_be())(w)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// From [RFC 8017](https://tools.ietf.org/html/rfc8017#appendix-A.1.1):
|
||||||
|
/// ```text
|
||||||
|
/// RSAPublicKey ::= SEQUENCE {
|
||||||
|
/// modulus INTEGER, -- n
|
||||||
|
/// publicExponent INTEGER -- e
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub(super) fn rsa_pubkey<'a, W: Write + 'a>(
|
||||||
|
pubkey: &'a RSAPublicKey,
|
||||||
|
) -> impl SerializeFn<W> + 'a {
|
||||||
|
der_sequence((
|
||||||
|
der_integer_biguint(pubkey.n()),
|
||||||
|
der_integer_biguint(pubkey.e()),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+5
-14
@@ -38,8 +38,11 @@
|
|||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
apdu::{Ins, StatusWords},
|
||||||
certificate::{self, Certificate},
|
certificate::{self, Certificate},
|
||||||
error::Error,
|
error::Error,
|
||||||
|
serialization::*,
|
||||||
|
settings,
|
||||||
yubikey::YubiKey,
|
yubikey::YubiKey,
|
||||||
ObjectId,
|
ObjectId,
|
||||||
};
|
};
|
||||||
@@ -47,32 +50,23 @@ use log::debug;
|
|||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
#[cfg(feature = "untested")]
|
#[cfg(feature = "untested")]
|
||||||
|
use crate::CB_OBJ_MAX;
|
||||||
use crate::{
|
use crate::{
|
||||||
apdu::{Ins, StatusWords},
|
|
||||||
certificate::PublicKeyInfo,
|
certificate::PublicKeyInfo,
|
||||||
policy::{PinPolicy, TouchPolicy},
|
policy::{PinPolicy, TouchPolicy},
|
||||||
serialization::*,
|
Buffer,
|
||||||
settings, Buffer, CB_OBJ_MAX,
|
|
||||||
};
|
};
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
use elliptic_curve::weierstrass::PublicKey as EcPublicKey;
|
use elliptic_curve::weierstrass::PublicKey as EcPublicKey;
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
use log::{error, warn};
|
use log::{error, warn};
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
use rsa::{BigUint, RSAPublicKey};
|
use rsa::{BigUint, RSAPublicKey};
|
||||||
#[cfg(feature = "untested")]
|
#[cfg(feature = "untested")]
|
||||||
use zeroize::Zeroizing;
|
use zeroize::Zeroizing;
|
||||||
|
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
const CB_ECC_POINTP256: usize = 65;
|
const CB_ECC_POINTP256: usize = 65;
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
const CB_ECC_POINTP384: usize = 97;
|
const CB_ECC_POINTP384: usize = 97;
|
||||||
|
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
const TAG_RSA_MODULUS: u8 = 0x81;
|
const TAG_RSA_MODULUS: u8 = 0x81;
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
const TAG_RSA_EXP: u8 = 0x82;
|
const TAG_RSA_EXP: u8 = 0x82;
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
const TAG_ECC_POINT: u8 = 0x86;
|
const TAG_ECC_POINT: u8 = 0x86;
|
||||||
|
|
||||||
/// Slot identifiers.
|
/// Slot identifiers.
|
||||||
@@ -381,7 +375,6 @@ impl From<AlgorithmId> for u8 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
impl AlgorithmId {
|
impl AlgorithmId {
|
||||||
/// Writes the `AlgorithmId` in the format the YubiKey expects during key generation.
|
/// Writes the `AlgorithmId` in the format the YubiKey expects during key generation.
|
||||||
pub(crate) fn write(self, buf: &mut [u8]) -> Result<usize, Error> {
|
pub(crate) fn write(self, buf: &mut [u8]) -> Result<usize, Error> {
|
||||||
@@ -435,7 +428,6 @@ impl Key {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Generate key
|
/// Generate key
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
#[allow(clippy::cognitive_complexity)]
|
#[allow(clippy::cognitive_complexity)]
|
||||||
pub fn generate(
|
pub fn generate(
|
||||||
yubikey: &mut YubiKey,
|
yubikey: &mut YubiKey,
|
||||||
@@ -758,7 +750,6 @@ pub fn attest(yubikey: &mut YubiKey, key: SlotId) -> Result<Buffer, Error> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Sign data using a PIV key
|
/// Sign data using a PIV key
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
pub fn sign_data(
|
pub fn sign_data(
|
||||||
yubikey: &mut YubiKey,
|
yubikey: &mut YubiKey,
|
||||||
raw_in: &[u8],
|
raw_in: &[u8],
|
||||||
|
|||||||
@@ -151,7 +151,6 @@ pub mod msroots;
|
|||||||
pub mod policy;
|
pub mod policy;
|
||||||
pub mod readers;
|
pub mod readers;
|
||||||
mod serialization;
|
mod serialization;
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
pub mod settings;
|
pub mod settings;
|
||||||
mod transaction;
|
mod transaction;
|
||||||
pub mod yubikey;
|
pub mod yubikey;
|
||||||
@@ -174,7 +173,6 @@ pub(crate) type Buffer = zeroize::Zeroizing<Vec<u8>>;
|
|||||||
pub(crate) const CB_BUF_MAX: usize = 3072;
|
pub(crate) const CB_BUF_MAX: usize = 3072;
|
||||||
|
|
||||||
/// YubiKey max object size
|
/// YubiKey max object size
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
pub(crate) const CB_OBJ_MAX: usize = CB_BUF_MAX - 9;
|
pub(crate) const CB_OBJ_MAX: usize = CB_BUF_MAX - 9;
|
||||||
pub(crate) const CB_OBJ_TAG_MIN: usize = 2; // 1 byte tag + 1 byte len
|
pub(crate) const CB_OBJ_TAG_MIN: usize = 2; // 1 byte tag + 1 byte len
|
||||||
#[cfg(feature = "untested")]
|
#[cfg(feature = "untested")]
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ use crate::{
|
|||||||
metadata, yubikey::YubiKey, CB_BUF_MAX, CB_OBJ_MAX, TAG_ADMIN, TAG_ADMIN_FLAGS_1,
|
metadata, yubikey::YubiKey, CB_BUF_MAX, CB_OBJ_MAX, TAG_ADMIN, TAG_ADMIN_FLAGS_1,
|
||||||
TAG_ADMIN_SALT, TAG_PROTECTED, TAG_PROTECTED_MGM,
|
TAG_ADMIN_SALT, TAG_PROTECTED, TAG_PROTECTED_MGM,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
use des::{
|
use des::{
|
||||||
block_cipher_trait::{generic_array::GenericArray, BlockCipher},
|
block_cipher_trait::{generic_array::GenericArray, BlockCipher},
|
||||||
TdesEde3,
|
TdesEde3,
|
||||||
@@ -282,7 +281,6 @@ impl MgmKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Encrypt with 3DES key
|
/// Encrypt with 3DES key
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
#[allow(clippy::trivially_copy_pass_by_ref)]
|
#[allow(clippy::trivially_copy_pass_by_ref)]
|
||||||
pub(crate) fn encrypt(&self, input: &[u8; DES_LEN_DES]) -> [u8; DES_LEN_DES] {
|
pub(crate) fn encrypt(&self, input: &[u8; DES_LEN_DES]) -> [u8; DES_LEN_DES] {
|
||||||
let mut output = input.to_owned();
|
let mut output = input.to_owned();
|
||||||
@@ -292,7 +290,6 @@ impl MgmKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Decrypt with 3DES key
|
/// Decrypt with 3DES key
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
#[allow(clippy::trivially_copy_pass_by_ref)]
|
#[allow(clippy::trivially_copy_pass_by_ref)]
|
||||||
pub(crate) fn decrypt(&self, input: &[u8; DES_LEN_DES]) -> [u8; DES_LEN_DES] {
|
pub(crate) fn decrypt(&self, input: &[u8; DES_LEN_DES]) -> [u8; DES_LEN_DES] {
|
||||||
let mut output = input.to_owned();
|
let mut output = input.to_owned();
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
//! Enums representing key policies.
|
//! Enums representing key policies.
|
||||||
|
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
use crate::{error::Error, serialization::Tlv};
|
use crate::{error::Error, serialization::Tlv};
|
||||||
|
|
||||||
/// Specifies how often the PIN needs to be entered for access to the credential in a
|
/// Specifies how often the PIN needs to be entered for access to the credential in a
|
||||||
@@ -38,7 +37,6 @@ impl From<PinPolicy> for u8 {
|
|||||||
impl PinPolicy {
|
impl PinPolicy {
|
||||||
/// Writes the `PinPolicy` in the format the YubiKey expects during key generation or
|
/// Writes the `PinPolicy` in the format the YubiKey expects during key generation or
|
||||||
/// importation.
|
/// importation.
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
pub(crate) fn write(self, buf: &mut [u8]) -> Result<usize, Error> {
|
pub(crate) fn write(self, buf: &mut [u8]) -> Result<usize, Error> {
|
||||||
match self {
|
match self {
|
||||||
PinPolicy::Default => Ok(0),
|
PinPolicy::Default => Ok(0),
|
||||||
@@ -83,7 +81,6 @@ impl From<TouchPolicy> for u8 {
|
|||||||
impl TouchPolicy {
|
impl TouchPolicy {
|
||||||
/// Writes the `TouchPolicy` in the format the YubiKey expects during key generation
|
/// Writes the `TouchPolicy` in the format the YubiKey expects during key generation
|
||||||
/// or importation.
|
/// or importation.
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
pub(crate) fn write(self, buf: &mut [u8]) -> Result<usize, Error> {
|
pub(crate) fn write(self, buf: &mut [u8]) -> Result<usize, Error> {
|
||||||
match self {
|
match self {
|
||||||
TouchPolicy::Default => Ok(0),
|
TouchPolicy::Default => Ok(0),
|
||||||
|
|||||||
@@ -79,7 +79,6 @@ impl<'a> Tlv<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Writes a TLV to the given buffer.
|
/// Writes a TLV to the given buffer.
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
pub(crate) fn write(buffer: &mut [u8], tag: u8, value: &[u8]) -> Result<usize, Error> {
|
pub(crate) fn write(buffer: &mut [u8], tag: u8, value: &[u8]) -> Result<usize, Error> {
|
||||||
if buffer.len() < CB_OBJ_TAG_MIN {
|
if buffer.len() < CB_OBJ_TAG_MIN {
|
||||||
return Err(Error::SizeError);
|
return Err(Error::SizeError);
|
||||||
@@ -99,7 +98,6 @@ impl<'a> Tlv<'a> {
|
|||||||
/// Writes a TLV to the given buffer.
|
/// Writes a TLV to the given buffer.
|
||||||
///
|
///
|
||||||
/// `value` is guaranteed to be called with a mutable slice of length `length`.
|
/// `value` is guaranteed to be called with a mutable slice of length `length`.
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
pub(crate) fn write_as<Gen>(
|
pub(crate) fn write_as<Gen>(
|
||||||
buffer: &mut [u8],
|
buffer: &mut [u8],
|
||||||
tag: u8,
|
tag: u8,
|
||||||
@@ -126,7 +124,6 @@ impl<'a> Tlv<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Set length
|
/// Set length
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
pub(crate) fn set_length(buffer: &mut [u8], length: usize) -> Result<usize, Error> {
|
pub(crate) fn set_length(buffer: &mut [u8], length: usize) -> Result<usize, Error> {
|
||||||
if length < 0x80 {
|
if length < 0x80 {
|
||||||
if buffer.is_empty() {
|
if buffer.is_empty() {
|
||||||
|
|||||||
+3
-8
@@ -4,20 +4,17 @@ use crate::{
|
|||||||
apdu::Response,
|
apdu::Response,
|
||||||
apdu::{Ins, StatusWords, APDU},
|
apdu::{Ins, StatusWords, APDU},
|
||||||
error::Error,
|
error::Error,
|
||||||
|
key::{AlgorithmId, SlotId},
|
||||||
serialization::*,
|
serialization::*,
|
||||||
yubikey::*,
|
yubikey::*,
|
||||||
Buffer, ObjectId, CB_BUF_MAX, PIV_AID, YK_AID,
|
Buffer, ObjectId, CB_BUF_MAX, CB_OBJ_MAX, PIV_AID, YK_AID,
|
||||||
};
|
};
|
||||||
use log::{error, trace};
|
use log::{error, trace};
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use zeroize::Zeroizing;
|
use zeroize::Zeroizing;
|
||||||
|
|
||||||
#[cfg(feature = "untested")]
|
#[cfg(feature = "untested")]
|
||||||
use crate::{
|
use crate::mgm::{MgmKey, DES_LEN_3DES};
|
||||||
key::{AlgorithmId, SlotId},
|
|
||||||
mgm::{MgmKey, DES_LEN_3DES},
|
|
||||||
CB_OBJ_MAX,
|
|
||||||
};
|
|
||||||
|
|
||||||
const CB_PIN_MAX: usize = 8;
|
const CB_PIN_MAX: usize = 8;
|
||||||
|
|
||||||
@@ -252,7 +249,6 @@ impl<'tx> Transaction<'tx> {
|
|||||||
/// This is the common backend for all public key encryption and signing
|
/// This is the common backend for all public key encryption and signing
|
||||||
/// operations.
|
/// operations.
|
||||||
// TODO(tarcieri): refactor this to be less gross/coupled.
|
// TODO(tarcieri): refactor this to be less gross/coupled.
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub(crate) fn authenticated_command(
|
pub(crate) fn authenticated_command(
|
||||||
&self,
|
&self,
|
||||||
@@ -472,7 +468,6 @@ impl<'tx> Transaction<'tx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Save an object.
|
/// Save an object.
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
pub fn save_object(&self, object_id: ObjectId, indata: &[u8]) -> Result<(), Error> {
|
pub fn save_object(&self, object_id: ObjectId, indata: &[u8]) -> Result<(), Error> {
|
||||||
let templ = [0, Ins::PutData.code(), 0x3f, 0xff];
|
let templ = [0, Ins::PutData.code(), 0x3f, 0xff];
|
||||||
|
|
||||||
|
|||||||
+6
-15
@@ -31,48 +31,41 @@
|
|||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
apdu::{Ins, APDU},
|
||||||
cccid::CCC,
|
cccid::CCC,
|
||||||
chuid::CHUID,
|
chuid::CHUID,
|
||||||
config::Config,
|
config::Config,
|
||||||
error::Error,
|
error::Error,
|
||||||
|
mgm::MgmKey,
|
||||||
readers::{Reader, Readers},
|
readers::{Reader, Readers},
|
||||||
transaction::Transaction,
|
transaction::Transaction,
|
||||||
};
|
};
|
||||||
use log::{error, info};
|
use log::{error, info};
|
||||||
use pcsc::Card;
|
use pcsc::Card;
|
||||||
use std::{
|
use std::{
|
||||||
convert::TryFrom,
|
convert::{TryFrom, TryInto},
|
||||||
fmt::{self, Display},
|
fmt::{self, Display},
|
||||||
str::FromStr,
|
str::FromStr,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "untested")]
|
#[cfg(feature = "untested")]
|
||||||
use crate::{
|
use crate::{
|
||||||
apdu::{Ins, StatusWords, APDU},
|
apdu::StatusWords, metadata, Buffer, ObjectId, CB_BUF_MAX, CB_OBJ_MAX, MGMT_AID, TAG_ADMIN,
|
||||||
metadata,
|
TAG_ADMIN_FLAGS_1, TAG_ADMIN_TIMESTAMP,
|
||||||
mgm::MgmKey,
|
|
||||||
Buffer, ObjectId, CB_BUF_MAX, CB_OBJ_MAX, MGMT_AID, TAG_ADMIN, TAG_ADMIN_FLAGS_1,
|
|
||||||
TAG_ADMIN_TIMESTAMP,
|
|
||||||
};
|
};
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
use getrandom::getrandom;
|
use getrandom::getrandom;
|
||||||
#[cfg(feature = "untested")]
|
#[cfg(feature = "untested")]
|
||||||
use secrecy::ExposeSecret;
|
use secrecy::ExposeSecret;
|
||||||
#[cfg(feature = "untested")]
|
#[cfg(feature = "untested")]
|
||||||
use std::{
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
convert::TryInto,
|
|
||||||
time::{SystemTime, UNIX_EPOCH},
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Flag for PUK blocked
|
/// Flag for PUK blocked
|
||||||
pub(crate) const ADMIN_FLAGS_1_PUK_BLOCKED: u8 = 0x01;
|
pub(crate) const ADMIN_FLAGS_1_PUK_BLOCKED: u8 = 0x01;
|
||||||
|
|
||||||
/// 3DES authentication
|
/// 3DES authentication
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
pub(crate) const ALGO_3DES: u8 = 0x03;
|
pub(crate) const ALGO_3DES: u8 = 0x03;
|
||||||
|
|
||||||
/// Card management key
|
/// Card management key
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
pub(crate) const KEY_CARDMGM: u8 = 0x9b;
|
pub(crate) const KEY_CARDMGM: u8 = 0x9b;
|
||||||
|
|
||||||
#[cfg(feature = "untested")]
|
#[cfg(feature = "untested")]
|
||||||
@@ -82,7 +75,6 @@ pub(crate) const CHREF_ACT_UNBLOCK_PIN: i32 = 1;
|
|||||||
#[cfg(feature = "untested")]
|
#[cfg(feature = "untested")]
|
||||||
pub(crate) const CHREF_ACT_CHANGE_PUK: i32 = 2;
|
pub(crate) const CHREF_ACT_CHANGE_PUK: i32 = 2;
|
||||||
|
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
const TAG_DYN_AUTH: u8 = 0x7c;
|
const TAG_DYN_AUTH: u8 = 0x7c;
|
||||||
|
|
||||||
/// Cached YubiKey PIN
|
/// Cached YubiKey PIN
|
||||||
@@ -274,7 +266,6 @@ impl YubiKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Authenticate to the card using the provided management key (MGM).
|
/// Authenticate to the card using the provided management key (MGM).
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
pub fn authenticate(&mut self, mgm_key: MgmKey) -> Result<(), Error> {
|
pub fn authenticate(&mut self, mgm_key: MgmKey) -> Result<(), Error> {
|
||||||
let txn = self.begin_transaction()?;
|
let txn = self.begin_transaction()?;
|
||||||
|
|
||||||
|
|||||||
+103
-1
@@ -5,8 +5,18 @@
|
|||||||
|
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use log::trace;
|
use log::trace;
|
||||||
|
use num_bigint::RandBigInt;
|
||||||
|
use rand::rngs::OsRng;
|
||||||
|
use rsa::{hash::Hashes::SHA2_256, PaddingScheme, PublicKey};
|
||||||
|
use sha2::{Digest, Sha256};
|
||||||
|
use std::convert::TryInto;
|
||||||
use std::{env, sync::Mutex};
|
use std::{env, sync::Mutex};
|
||||||
use yubikey_piv::{key::Key, Error, YubiKey};
|
use yubikey_piv::{
|
||||||
|
certificate::{Certificate, PublicKeyInfo},
|
||||||
|
key::{self, AlgorithmId, Key, RetiredSlotId, SlotId},
|
||||||
|
policy::{PinPolicy, TouchPolicy},
|
||||||
|
Error, MgmKey, YubiKey,
|
||||||
|
};
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
/// Provide thread-safe access to a YubiKey
|
/// Provide thread-safe access to a YubiKey
|
||||||
@@ -96,3 +106,95 @@ fn test_verify_pin() {
|
|||||||
assert!(yubikey.verify_pin(b"000000").is_err());
|
assert!(yubikey.verify_pin(b"000000").is_err());
|
||||||
assert!(yubikey.verify_pin(b"123456").is_ok());
|
assert!(yubikey.verify_pin(b"123456").is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Certificate support
|
||||||
|
//
|
||||||
|
|
||||||
|
fn generate_self_signed_cert(algorithm: AlgorithmId) -> Certificate {
|
||||||
|
let mut yubikey = YUBIKEY.lock().unwrap();
|
||||||
|
|
||||||
|
assert!(yubikey.verify_pin(b"123456").is_ok());
|
||||||
|
assert!(yubikey.authenticate(MgmKey::default()).is_ok());
|
||||||
|
|
||||||
|
let slot = SlotId::Retired(RetiredSlotId::R1);
|
||||||
|
|
||||||
|
// Generate a new key in the selected slot.
|
||||||
|
let generated = key::generate(
|
||||||
|
&mut yubikey,
|
||||||
|
slot,
|
||||||
|
algorithm,
|
||||||
|
PinPolicy::Default,
|
||||||
|
TouchPolicy::Default,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut rng = OsRng::new().unwrap();
|
||||||
|
|
||||||
|
// Generate a self-signed certificate for the new key.
|
||||||
|
let cert_result = Certificate::generate_self_signed(
|
||||||
|
&mut yubikey,
|
||||||
|
slot,
|
||||||
|
rng.gen_biguint(20 * 8),
|
||||||
|
None,
|
||||||
|
"testSubject".to_owned(),
|
||||||
|
generated,
|
||||||
|
);
|
||||||
|
|
||||||
|
assert!(cert_result.is_ok());
|
||||||
|
let cert = cert_result.unwrap();
|
||||||
|
trace!("cert: {:?}", cert);
|
||||||
|
cert
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
|
fn generate_self_signed_rsa_cert() {
|
||||||
|
let cert = generate_self_signed_cert(AlgorithmId::Rsa1024);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Verify that the certificate is signed correctly
|
||||||
|
//
|
||||||
|
|
||||||
|
let pubkey = match cert.subject_pki() {
|
||||||
|
PublicKeyInfo::Rsa { pubkey, .. } => pubkey,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let data = cert.as_ref();
|
||||||
|
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 sig = &data[data.len() - 128..];
|
||||||
|
|
||||||
|
let hash = Sha256::digest(msg);
|
||||||
|
|
||||||
|
assert!(pubkey
|
||||||
|
.verify(PaddingScheme::PKCS1v15, Some(&SHA2_256), &hash, sig)
|
||||||
|
.is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
|
fn generate_self_signed_ec_cert() {
|
||||||
|
let cert = generate_self_signed_cert(AlgorithmId::EccP256);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Verify that the certificate is signed correctly
|
||||||
|
//
|
||||||
|
|
||||||
|
let pubkey = match cert.subject_pki() {
|
||||||
|
PublicKeyInfo::EcP256(pubkey) => pubkey,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let data = cert.as_ref();
|
||||||
|
let tbs_cert_len = data[6] as usize;
|
||||||
|
let sig_algo_len = data[7 + tbs_cert_len + 1] as usize;
|
||||||
|
let sig_start = 7 + tbs_cert_len + 2 + sig_algo_len + 3;
|
||||||
|
let msg = &data[4..7 + tbs_cert_len];
|
||||||
|
let sig = &data[sig_start..];
|
||||||
|
|
||||||
|
use ring::signature::{UnparsedPublicKey, ECDSA_P256_SHA256_ASN1};
|
||||||
|
let ring_pk = UnparsedPublicKey::new(&ECDSA_P256_SHA256_ASN1, pubkey.as_bytes());
|
||||||
|
assert!(ring_pk.verify(msg, sig).is_ok());
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user