From e34d02e6227cb16ea8780a5218640a54fe9f3f95 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Sun, 3 Apr 2022 12:57:05 +0800 Subject: [PATCH] v1.1.0, update openpgp-card versions --- Cargo.lock | 567 ++++++++++++++++++++++++++++++++++---- Cargo.toml | 6 +- src/cmd_pgpcardadmin.rs | 26 +- src/cmd_pgpcarddecrypt.rs | 13 +- src/cmd_pgpcardlist.rs | 131 ++++++--- src/cmd_pgpcardsign.rs | 19 +- src/pgpcardutil.rs | 42 +-- 7 files changed, 651 insertions(+), 153 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aee0154..61c241c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,7 +23,7 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "cipher", "cpufeatures", "opaque-debug", @@ -125,7 +125,7 @@ checksum = "5e121dee8023ce33ab248d9ce1493df03c3b38a659b240096fcbd7048ff9c31f" dependencies = [ "addr2line", "cc", - "cfg-if", + "cfg-if 1.0.0", "libc", "miniz_oxide", "object", @@ -202,6 +202,17 @@ dependencies = [ "wyz", ] +[[package]] +name = "blanket" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b04ce3d2372d05d1ef4ea3fdf427da6ae3c17ca06d688a107b5344836276bc3" +dependencies = [ + "proc-macro2", + "quote 1.0.17", + "syn", +] + [[package]] name = "block-buffer" version = "0.9.0" @@ -269,6 +280,12 @@ dependencies = [ "iovec", ] +[[package]] +name = "bytes" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" + [[package]] name = "bzip2" version = "0.4.3" @@ -290,9 +307,36 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "capnp" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e76a319e55a4ef27c8c383215fa3160167bd8a883e8d27c0ecd57ed81bca2af" + +[[package]] +name = "capnp-futures" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc7bd6f6a6240f4f0a39b89c731916b15eefa26d31f90dffc1d232b7981d09a3" +dependencies = [ + "capnp", + "futures", +] + +[[package]] +name = "capnp-rpc" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37998522d42bbe4a1d266f418b1a053b679a338e904e55afd5ff22333df0e09e" +dependencies = [ + "capnp", + "capnp-futures", + "futures", +] + [[package]] name = "card-cli" -version = "1.0.2" +version = "1.1.0" dependencies = [ "authenticator", "base64 0.13.0", @@ -301,6 +345,8 @@ dependencies = [ "digest", "hex", "openpgp-card", + "openpgp-card-pcsc", + "openpgp-card-sequoia", "openssl", "pem", "rand 0.8.5", @@ -334,6 +380,12 @@ dependencies = [ "nom 5.1.2", ] +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + [[package]] name = "cfg-if" version = "1.0.0" @@ -433,7 +485,7 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", ] [[package]] @@ -464,6 +516,16 @@ dependencies = [ "subtle", ] +[[package]] +name = "ctor" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f877be4f7c9f246b183111634f75baa039715e3f46ce860677d3b19a69fb229c" +dependencies = [ + "quote 1.0.17", + "syn", +] + [[package]] name = "data-encoding" version = "2.3.2" @@ -566,16 +628,37 @@ dependencies = [ "generic-array", ] +[[package]] +name = "dirs" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" +dependencies = [ + "cfg-if 0.1.10", + "dirs-sys", +] + [[package]] name = "dirs-next" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "dirs-sys-next", ] +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + [[package]] name = "dirs-sys-next" version = "0.1.2" @@ -680,7 +763,7 @@ version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "crc32fast", "libc", "miniz_oxide", @@ -701,12 +784,111 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +[[package]] +name = "fs2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "funty" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" +[[package]] +name = "futures" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" + +[[package]] +name = "futures-executor" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" + +[[package]] +name = "futures-macro" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" +dependencies = [ + "proc-macro2", + "quote 1.0.17", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" + +[[package]] +name = "futures-task" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" + +[[package]] +name = "futures-util" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + [[package]] name = "generic-array" version = "0.14.5" @@ -723,7 +905,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "js-sys", "libc", "wasi 0.9.0+wasi-snapshot-preview1", @@ -732,11 +914,11 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d39cd93900197114fa1fcb7ae84ca742095eed9442088988ae74fa744e930e77" +checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "js-sys", "libc", "wasi 0.10.0+wasi-snapshot-preview1", @@ -793,6 +975,12 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +[[package]] +name = "hex-slice" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5491a308e0214554f07a81d8944abe45f552871c12e3c3c6e7e5d354039a6c4c" + [[package]] name = "hmac" version = "0.11.0" @@ -828,9 +1016,9 @@ checksum = "0cfe9645a18782869361d9c8732246be7b410ad4e919d3609ebabdac00ba12c3" [[package]] name = "indexmap" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" +checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" dependencies = [ "autocfg 1.1.0", "hashbrown", @@ -842,7 +1030,7 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", ] [[package]] @@ -854,6 +1042,15 @@ dependencies = [ "libc", ] +[[package]] +name = "iso7816-tlv" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "395d8e0ae63eb5016fbcf4a72864155880e34bce0158206fcfa7218efdd52e82" +dependencies = [ + "untrusted 0.9.0", +] + [[package]] name = "itertools" version = "0.10.3" @@ -939,7 +1136,7 @@ checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" dependencies = [ "arrayvec 0.5.2", "bitflags", - "cfg-if", + "cfg-if 1.0.0", "ryu", "static_assertions", ] @@ -956,7 +1153,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "winapi", ] @@ -1000,10 +1197,11 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b" +checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" dependencies = [ + "autocfg 1.1.0", "scopeguard", ] @@ -1013,7 +1211,7 @@ version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", ] [[package]] @@ -1050,13 +1248,36 @@ dependencies = [ "autocfg 1.1.0", ] +[[package]] +name = "mio" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9" +dependencies = [ + "libc", + "log", + "miow", + "ntapi", + "wasi 0.11.0+wasi-snapshot-preview1", + "winapi", +] + +[[package]] +name = "miow" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" +dependencies = [ + "winapi", +] + [[package]] name = "nettle" version = "7.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c511dff9452c522101505be4b5bbe07afd4f4565c65ca7d8118d4b804bd6a199" dependencies = [ - "getrandom 0.2.5", + "getrandom 0.2.6", "libc", "nettle-sys", "thiserror", @@ -1128,6 +1349,15 @@ dependencies = [ "nom 7.1.1", ] +[[package]] +name = "ntapi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" +dependencies = [ + "winapi", +] + [[package]] name = "num-bigint" version = "0.4.3" @@ -1189,6 +1419,16 @@ dependencies = [ "libm", ] +[[package]] +name = "num_cpus" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +dependencies = [ + "hermit-abi", + "libc", +] + [[package]] name = "object" version = "0.27.1" @@ -1230,17 +1470,61 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openpgp-card" -version = "0.0.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15d5a670b7f712a5b9a85308aad074f09405412cee07d59501658229052ea53" +checksum = "179ebbe98f931b4fbdf612c6abc15f440b6d8aa8f87a9b5c1f5d05f6e2592aa7" +dependencies = [ + "blanket", + "chrono", + "hex-literal", + "hex-slice", + "log", + "nom 6.1.2", + "thiserror", +] + +[[package]] +name = "openpgp-card-pcsc" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ced2ca281675f58341162043963f9fe2067381b23ca934cfa7e2b1fa36d721a" +dependencies = [ + "iso7816-tlv", + "log", + "openpgp-card", + "pcsc", +] + +[[package]] +name = "openpgp-card-scdc" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e65178cc0251816d244004177f958a914579dd25150153829be47c87360d5550" +dependencies = [ + "futures", + "hex", + "lazy_static", + "log", + "openpgp-card", + "sequoia-ipc", + "tokio", +] + +[[package]] +name = "openpgp-card-sequoia" +version = "0.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "856dbc92cdba917f60153efa5253094fe2b71009a89e3b3a748bf5685889e876" dependencies = [ "anyhow", "chrono", "env_logger", - "hex-literal", "log", - "nom 6.1.2", - "pcsc", + "nettle", + "openpgp-card", + "openpgp-card-pcsc", + "openpgp-card-scdc", + "sequoia-openpgp", "thiserror", ] @@ -1251,7 +1535,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95" dependencies = [ "bitflags", - "cfg-if", + "cfg-if 1.0.0", "foreign-types", "libc", "once_cell", @@ -1293,27 +1577,25 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.11.2" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58" dependencies = [ - "instant", "lock_api", "parking_lot_core", ] [[package]] name = "parking_lot_core" -version = "0.8.5" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +checksum = "995f667a6c822200b0433ac218e05582f0e2efa1b922a3fd2fbaadc5f87bab37" dependencies = [ - "cfg-if", - "instant", + "cfg-if 1.0.0", "libc", "redox_syscall", "smallvec", - "winapi", + "windows-sys", ] [[package]] @@ -1395,6 +1677,18 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db8bcd96cb740d03149cbad5518db9fd87126a10ab519c011893b1754134c468" +[[package]] +name = "pin-project-lite" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "pkcs1" version = "0.2.4" @@ -1421,9 +1715,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" +checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" [[package]] name = "ppv-lite86" @@ -1547,7 +1841,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ - "getrandom 0.2.5", + "getrandom 0.2.6", ] [[package]] @@ -1561,20 +1855,20 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae183fc1b06c149f0c1793e1eb447c8b04bfe46d48e9e48bfb8d2d7ed64ecf0" +checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" dependencies = [ "bitflags", ] [[package]] name = "redox_users" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7776223e2696f1aa4c6b0170e83212f47296a00424305117d013dfe86fb0fe55" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ - "getrandom 0.2.5", + "getrandom 0.2.6", "redox_syscall", "thiserror", ] @@ -1615,7 +1909,7 @@ dependencies = [ "libc", "once_cell", "spin", - "untrusted", + "untrusted 0.7.1", "web-sys", "winapi", ] @@ -1726,6 +2020,34 @@ dependencies = [ "zeroize", ] +[[package]] +name = "sequoia-ipc" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e5b1e086f01d0cf6f916369c2927cbd6b85c913dfdfaed53a2499b34fe5517d" +dependencies = [ + "anyhow", + "buffered-reader", + "capnp-rpc", + "ctor", + "dirs", + "fs2", + "futures", + "lalrpop", + "lalrpop-util", + "lazy_static", + "libc", + "memsec", + "rand 0.7.3", + "sequoia-openpgp", + "socket2 0.3.19", + "tempfile", + "thiserror", + "tokio", + "tokio-util", + "winapi", +] + [[package]] name = "sequoia-openpgp" version = "1.8.0" @@ -1740,7 +2062,7 @@ dependencies = [ "chrono", "dyn-clone", "flate2", - "getrandom 0.2.5", + "getrandom 0.2.6", "idna", "lalrpop", "lalrpop-util", @@ -1794,7 +2116,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" dependencies = [ "block-buffer", - "cfg-if", + "cfg-if 1.0.0", "cpufeatures", "digest", "opaque-debug", @@ -1832,7 +2154,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" dependencies = [ "block-buffer", - "cfg-if", + "cfg-if 1.0.0", "cpufeatures", "digest", "opaque-debug", @@ -1844,6 +2166,15 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" +[[package]] +name = "signal-hook-registry" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +dependencies = [ + "libc", +] + [[package]] name = "signature" version = "1.3.2" @@ -1870,12 +2201,39 @@ version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" +[[package]] +name = "slab" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" + [[package]] name = "smallvec" version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" +[[package]] +name = "socket2" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "spin" version = "0.5.2" @@ -1899,12 +2257,12 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "string_cache" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33994d0838dc2d152d17a62adf608a869b5e846b65b389af7f3dbc1de45c5b26" +checksum = "213494b7a2b503146286049378ce02b482200519accc31872ee8be91fa820a08" dependencies = [ - "lazy_static", "new_debug_unreachable", + "once_cell", "parking_lot", "phf_shared", "precomputed-hash", @@ -1954,9 +2312,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.89" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea297be220d52398dcc07ce15a209fce436d361735ac1db700cab3b6cdfb9f54" +checksum = "704df27628939572cd88d33f171cd6f896f4eaca85252c6e0a72d8d8287ee86f" dependencies = [ "proc-macro2", "quote 1.0.17", @@ -1987,7 +2345,7 @@ version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "fastrand", "libc", "redox_syscall", @@ -2089,6 +2447,52 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +[[package]] +name = "tokio" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2af73ac49756f3f7c01172e34a23e5d0216f6c32333757c2c61feb2bbff5a5ee" +dependencies = [ + "bytes 1.1.0", + "libc", + "memchr", + "mio", + "num_cpus", + "once_cell", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.4.4", + "tokio-macros", + "winapi", +] + +[[package]] +name = "tokio-macros" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" +dependencies = [ + "proc-macro2", + "quote 1.0.17", + "syn", +] + +[[package]] +name = "tokio-util" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0" +dependencies = [ + "bytes 1.1.0", + "futures-core", + "futures-io", + "futures-sink", + "log", + "pin-project-lite", + "tokio", +] + [[package]] name = "typenum" version = "1.15.0" @@ -2103,7 +2507,7 @@ checksum = "e2f285392366190c4d46823458f4543ac0f35174759c78e80c5baa39e1f7aa4f" dependencies = [ "base64 0.11.0", "byteorder", - "bytes", + "bytes 0.4.12", "chrono", "openssl", "serde", @@ -2145,13 +2549,19 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "uuid" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" dependencies = [ - "getrandom 0.2.5", + "getrandom 0.2.6", ] [[package]] @@ -2184,13 +2594,19 @@ version = "0.10.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "wasm-bindgen" version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25f1af7423d8588a3d840681122e72e6a24ddbcb3f0ec385cac0d12d24256c06" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "wasm-bindgen-macro", ] @@ -2279,6 +2695,49 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5acdd78cb4ba54c0045ac14f62d8f94a03d10047904ae2a40afa1e99d8f70825" +dependencies = [ + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_msvc" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d" + +[[package]] +name = "windows_i686_gnu" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed" + +[[package]] +name = "windows_i686_msvc" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9" + [[package]] name = "wyz" version = "0.2.0" diff --git a/Cargo.toml b/Cargo.toml index 167a45b..34372b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "card-cli" -version = "1.0.2" +version = "1.1.0" authors = ["Hatter Jiang "] edition = "2018" @@ -16,7 +16,9 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" hex = "0.4" u2f = "0.2" -openpgp-card = "0.0.1" +openpgp-card = "0.2" +openpgp-card-pcsc = "0.2" +openpgp-card-sequoia = "0.0.8" sequoia-openpgp = "1.3.0" chrono = "0.4.19" simpledateformat = "0.1.2" diff --git a/src/cmd_pgpcardadmin.rs b/src/cmd_pgpcardadmin.rs index 0ac65cf..4b76b0e 100644 --- a/src/cmd_pgpcardadmin.rs +++ b/src/cmd_pgpcardadmin.rs @@ -1,5 +1,6 @@ use clap::{App, Arg, ArgMatches, SubCommand}; -use openpgp_card::Sex; +use openpgp_card::{OpenPgp}; +use openpgp_card::card_do::{Lang, Sex}; use rust_util::util_clap::{Command, CommandError}; pub struct CommandImpl; @@ -22,25 +23,30 @@ impl Command for CommandImpl { let pin = opt_value_result!(pin_opt, "Pass must be assigned"); if pin.len() < 8 { return simple_error!("Admin pin length:{}, must >= 8!", pin.len()); } - let card_admin = crate::pgpcardutil::get_card_admin(pin)?; + let mut card = crate::pgpcardutil::get_card()?; + let mut pgp = OpenPgp::new(&mut card); + let mut trans = opt_result!(pgp.transaction(), "Open card failed: {}"); + + opt_result!(trans.verify_pw3(pin.as_ref()), "Admin pin verify failed: {}"); success!("Admin pin verify success!"); if let Some(name) = sub_arg_matches.value_of("name") { information!("Set name to: {}", name); - let response = opt_result!(card_admin.set_name(name), "Set name failed: {}"); - success!("Set name success: {:?}", response); + opt_result!(trans.set_name(name.as_bytes()), "Set name failed: {}"); + success!("Set name success"); } if let Some(url) = sub_arg_matches.value_of("url") { information!("Set URL to: {}", url); - let response = opt_result!(card_admin.set_url(url), "Set URL failed: {}"); - success!("Set URL success: {:?}", response); + opt_result!(trans.set_url(url.as_bytes()), "Set URL failed: {}"); + success!("Set URL success"); } if let Some(lang) = sub_arg_matches.value_of("lang") { information!("Set lang to: {}", lang); - let response = opt_result!(card_admin.set_lang(lang), "Set lang failed: {}"); - success!("Set lang success: {:?}", response); + let lang_bytes = lang.as_bytes(); + opt_result!(trans.set_lang(&vec![Lang::Value([lang_bytes[0], lang_bytes[1]])]), "Set lang failed: {}"); + success!("Set lang success"); } if let Some(sex) = sub_arg_matches.value_of("sex") { @@ -55,8 +61,8 @@ impl Command for CommandImpl { }; if let Some(s) = s { information!("Set sex to: {:?}", s); - let response = opt_result!(card_admin.set_sex(s), "Set sex failed: {}"); - success!("Set sex success: {:?}", response); + opt_result!(trans.set_sex(s), "Set lang failed: {}"); + success!("Set sex success"); } } diff --git a/src/cmd_pgpcarddecrypt.rs b/src/cmd_pgpcarddecrypt.rs index 57a8165..51b76bc 100644 --- a/src/cmd_pgpcarddecrypt.rs +++ b/src/cmd_pgpcarddecrypt.rs @@ -1,7 +1,8 @@ use std::collections::BTreeMap; use clap::{App, Arg, ArgMatches, SubCommand}; -use openpgp_card::DecryptMe; +use openpgp_card::OpenPgp; +use openpgp_card::crypto_data::Cryptogram; use rust_util::util_clap::{Command, CommandError}; pub struct CommandImpl; @@ -37,8 +38,14 @@ impl Command for CommandImpl { return simple_error!("cipher or cipher-base64 must assign one"); }; - let user = crate::pgpcardutil::get_card_user_sw1_82(pin)?; - let text = user.decrypt(DecryptMe::RSA(&cipher_bytes))?; + let mut card = crate::pgpcardutil::get_card()?; + let mut pgp = OpenPgp::new(&mut card); + let mut trans = opt_result!(pgp.transaction(), "Open card failed: {}"); + + opt_result!(trans.verify_pw1_user(pin.as_ref()), "User pin verify failed: {}"); + success!("User pin verify success!"); + + let text = trans.decipher(Cryptogram::RSA(&cipher_bytes))?; success!("Clear text HEX: {}", hex::encode(&text)); success!("Clear text base64: {}", base64::encode(&text)); success!("Clear text UTF-8: {}", String::from_utf8_lossy(&text)); diff --git a/src/cmd_pgpcardlist.rs b/src/cmd_pgpcardlist.rs index 05b2cdf..2f97524 100644 --- a/src/cmd_pgpcardlist.rs +++ b/src/cmd_pgpcardlist.rs @@ -1,7 +1,8 @@ use std::collections::BTreeMap; use clap::{App, Arg, ArgMatches, SubCommand}; -use openpgp_card::{KeyType, OpenPGPCard}; +use openpgp_card::{KeyType, OpenPgp}; +use openpgp_card_pcsc::PcscBackend; use rust_util::util_clap::{Command, CommandError}; pub struct CommandImpl; @@ -19,50 +20,102 @@ impl Command for CommandImpl { if json_output { rust_util::util_msg::set_logger_std_out(false); } let mut json = BTreeMap::new(); - let cards = opt_result!(OpenPGPCard::list_cards(), "Failed to list OpenPGP cards: {}"); + let cards = opt_result!(PcscBackend::cards(None), "Failed to list OpenPGP cards: {}"); information!("Found {} card(s)", cards.len()); - for (i, card) in cards.iter().enumerate() { - success!("Found card #{}: {:?}", i, card.get_aid()); - debugging!("Historical: {:?}", card.get_historical()); - debugging!("Extended length information{:?}", card.get_extended_length_information()); - debugging!("Extended capabilities{:?}", card.get_extended_capabilities()); - debugging!("Security support template{:?}", card.get_security_support_template()); - if let Ok(url) = card.get_url() { - information!("URL: {}", iff!(url.is_empty(), "", &url)); - } - if let Ok(card_holder) = card.get_cardholder_related_data() { - information!("Card holder: {:?}", card_holder); - } - if let Ok(supported_algo) = card.list_supported_algo() { - information!("Supported algo: {:?}", supported_algo); - } - if let Ok(fingerprints) = card.get_fingerprints() { - if let Some(a) = fingerprints.authentication() { - if let Ok(algo) = card.get_algorithm_attributes(KeyType::Authentication) { - information!("Authentication algo: {:?}", algo); - } - information!("Authentication fingerprint: {}", a); - if json_output { - json.insert("authentication_fingerprint", a.to_string()); + for (i, mut card) in cards.into_iter().enumerate() { + let mut pgp = OpenPgp::new(&mut card); + let mut trans = opt_result!(pgp.transaction(), "Open card failed: {}"); + if let Ok(application_related_data) = trans.application_related_data() { + success!("Found card #{}: {:?}", i, application_related_data.application_id()); + debugging!("Historical: {:?}", application_related_data.historical_bytes()); + debugging!("Extended length information: {:?}", application_related_data.extended_length_information()); + debugging!("Extended capabilities: {:?}", application_related_data.extended_capabilities()); + debugging!("Key generation times: {:?}", application_related_data.key_generation_times()); + debugging!("PW status bytes: {:?}", application_related_data.pw_status_bytes()); + debugging!(r#"Algorithm attributes: +- Signing: {:?} +- Decryption: {:?} +- Authentication: {:?} +- Attestation: {:?}"#, + application_related_data.algorithm_attributes(KeyType::Signing), + application_related_data.algorithm_attributes(KeyType::Decryption), + application_related_data.algorithm_attributes(KeyType::Authentication), + application_related_data.algorithm_attributes(KeyType::Attestation)); + debugging!("Fingerprints: {:?}", application_related_data.fingerprints()); + if json_output { + if let Ok(application_identifier) = application_related_data.application_id() { + json.insert("application", format!("{}", application_identifier.application())); + json.insert("version", format!("{}", application_identifier.version())); + json.insert("serial", format!("{}", application_identifier.serial())); + json.insert("manufacturer", format!("{}", application_identifier.manufacturer())); + json.insert("ident", application_identifier.ident()); } } - if let Some(d) = fingerprints.decryption() { - if let Ok(algo) = card.get_algorithm_attributes(KeyType::Decryption) { - information!("Encryption algo: {:?}", algo); - } - information!("Encryption fingerprint: {}", d); - if json_output { - json.insert("encryption_fingerprint", d.to_string()); - } + } + information!("Feature pin pad, verify: {}, modify: {}", + trans.feature_pinpad_verify(), trans.feature_pinpad_modify()); + if json_output { + json.insert("feature_pinpad_verify", format!("{}", trans.feature_pinpad_verify())); + json.insert("feature_pinpad_modify", format!("{}", trans.feature_pinpad_modify())); + } + + if let Ok(security_supported_template) = trans.security_support_template() { + debugging!("Security support template: {:?}", security_supported_template); + } + if let Ok(cardholder_certificate) = trans.cardholder_certificate() { + debugging!("Cardholder certificate: {:?}", cardholder_certificate); + } + // debugging!("Security support template: {:?}", trans.security_support_template()); + // debugging!("Security support template: {:?}", trans.cardholder_certificate()); + if let Ok(url) = trans.url() { + information!("URL: {}", iff!(url.is_empty(), "".to_string(), String::from_utf8_lossy(&url).to_string())); + } + if let Ok(card_holder) = trans.cardholder_related_data() { + debugging!("Card holder: {:?}", card_holder); + let mut card_holder_outputs = vec![]; + if let Some(name) = card_holder.name() { + card_holder_outputs.push(format!("name: {}", String::from_utf8_lossy(name))); } - if let Some(s) = fingerprints.signature() { - if let Ok(algo) = card.get_algorithm_attributes(KeyType::Signing) { - information!("Signature algo: {:?}", algo); + if let Some(lang) = card_holder.lang() { + card_holder_outputs.push(format!( + "lang: {}", + lang.iter().map(|l| l.to_string()).collect::>().join(" "))); + } + if let Some(sex) = card_holder.sex() { + card_holder_outputs.push(format!("sex: {:?}", sex)); + } + information!("Card holder, {}", + iff!(card_holder_outputs.is_empty(), "".to_string(), card_holder_outputs.join(", "))); + } + if let Ok(application_related_data) = trans.application_related_data() { + if let Ok(fingerprints) = application_related_data.fingerprints() { + if let Some(a) = fingerprints.authentication() { + if let Ok(algo) = application_related_data.algorithm_attributes(KeyType::Authentication) { + information!("Authentication algo: {:?}", algo); + } + information!("Authentication fingerprint: {}", a); + if json_output { + json.insert("authentication_fingerprint", a.to_string()); + } } - information!("Signature fingerprint: {}", s); - if json_output { - json.insert("signature_fingerprint", s.to_string()); + if let Some(d) = fingerprints.decryption() { + if let Ok(algo) = application_related_data.algorithm_attributes(KeyType::Decryption) { + information!("Encryption algo: {:?}", algo); + } + information!("Encryption fingerprint: {}", d); + if json_output { + json.insert("encryption_fingerprint", d.to_string()); + } + } + if let Some(s) = fingerprints.signature() { + if let Ok(algo) = application_related_data.algorithm_attributes(KeyType::Signing) { + information!("Signature algo: {:?}", algo); + } + information!("Signature fingerprint: {}", s); + if json_output { + json.insert("signature_fingerprint", s.to_string()); + } } } } diff --git a/src/cmd_pgpcardsign.rs b/src/cmd_pgpcardsign.rs index 19a55e2..4bffc2c 100644 --- a/src/cmd_pgpcardsign.rs +++ b/src/cmd_pgpcardsign.rs @@ -1,12 +1,11 @@ use std::collections::BTreeMap; use clap::{App, Arg, ArgMatches, SubCommand}; -use openpgp_card::Hash; +use openpgp_card::crypto_data::Hash; +use openpgp_card::OpenPgp; use rust_util::util_clap::{Command, CommandError}; use rust_util::XResult; -use crate::pgpcardutil; - pub struct CommandImpl; impl Command for CommandImpl { @@ -37,13 +36,19 @@ impl Command for CommandImpl { if sha256.is_none() && sha384.is_none() && sha512.is_none() { return simple_error!("SHA256, SHA384 or SHA512 must assign at least one"); } - let user = opt_result!(pgpcardutil::get_card_user_sw1_81(pin), "Verify user pin failed: {}"); + + let mut card = crate::pgpcardutil::get_card()?; + let mut pgp = OpenPgp::new(&mut card); + let mut trans = opt_result!(pgp.transaction(), "Open card failed: {}"); + + opt_result!(trans.verify_pw1_sign(pin.as_ref()), "User sign pin verify failed: {}"); + success!("User sign pin verify success!"); let mut json = BTreeMap::new(); if let Some(sha256) = sha256 { let sha256_hex = opt_result!(hex::decode(sha256.trim()), "Decode sha256 failed: {}"); let sha256_hex = copy_sha256(&sha256_hex)?; - let sig = user.signature_for_hash(Hash::SHA256(sha256_hex))?; + let sig = trans.signature_for_hash(Hash::SHA256(sha256_hex))?; success!("SHA256 signature HEX: {}", hex::encode(&sig)); success!("SHA256 signature base64: {}", base64::encode(&sig)); if json_output { @@ -56,7 +61,7 @@ impl Command for CommandImpl { if let Some(sha384) = sha384 { let sha384_hex = opt_result!(hex::decode(sha384.trim()), "Decode sha384 failed: {}"); let sha384_hex = copy_sha384(&sha384_hex)?; - let sig = user.signature_for_hash(Hash::SHA384(sha384_hex))?; + let sig = trans.signature_for_hash(Hash::SHA384(sha384_hex))?; success!("SHA384 signature HEX: {}", hex::encode(&sig)); success!("SHA384 signature base64: {}", base64::encode(&sig)); if json_output { @@ -69,7 +74,7 @@ impl Command for CommandImpl { if let Some(sha512) = sha512 { let sha512_hex = opt_result!(hex::decode(sha512.trim()), "Decode sha512 failed: {}"); let sha512_hex = copy_sha512(&sha512_hex)?; - let sig = user.signature_for_hash(Hash::SHA512(sha512_hex))?; + let sig = trans.signature_for_hash(Hash::SHA512(sha512_hex))?; success!("SHA512 signature HEX: {}", hex::encode(&sig)); success!("SHA512 signature base64: {}", base64::encode(&sig)); if json_output { diff --git a/src/pgpcardutil.rs b/src/pgpcardutil.rs index 833aac7..3a91f7e 100644 --- a/src/pgpcardutil.rs +++ b/src/pgpcardutil.rs @@ -1,47 +1,13 @@ -use openpgp_card::{OpenPGPCard, OpenPGPCardAdmin, OpenPGPCardUser}; +use openpgp_card_pcsc::PcscBackend; use rust_util::XResult; -pub fn get_card_user_sw1_81(pin: &str) -> XResult { - // pw1_81 for signature - // openssl dgst -sha256 -verify aa -signature sig LICENSE - get_card_user(|open_pgp_card: OpenPGPCard| open_pgp_card.verify_pw1_81(pin), "pw1_81") -} - -pub fn get_card_user_sw1_82(pin: &str) -> XResult { - // pw1_82 for decrypt - // PKCSv1.5 - get_card_user(|open_pgp_card: OpenPGPCard| open_pgp_card.verify_pw1_82(pin), "pw1_82") -} - -pub fn get_card_admin(pin: &str) -> XResult { - let card = get_card()?; - match card.verify_pw3(pin) { - Result::Ok(admin) => Ok(admin), - Result::Err(_) => simple_error!("Verify pw3 OpenPGP card failed"), - } -} - -fn get_card_user(process_fn: impl Fn(OpenPGPCard) -> Result, tag: &str) -> XResult { - let card = get_card()?; - match process_fn(card) { - Result::Ok(user) => Ok(user), - Result::Err(_) => simple_error!("Verify {} OpenPGP card failed", tag), - } -} - -fn get_card() -> XResult { - let card_list = opt_result!(OpenPGPCard::list_cards(), - "Read OpenPGP card list failed: {}"); +pub fn get_card() -> XResult { + let card_list = opt_result!(PcscBackend::cards(None), "Read OpenPGP card list failed: {}"); if card_list.is_empty() { return simple_error!("Cannot find any card"); } if card_list.len() > 1 { warning!("Find {} OpenPGP cards, will use first card", card_list.len()); } - let card = card_list.into_iter().next(); - card.as_ref().map(|card| - card.get_aid().map(|card| - success!("Found card: {:?}", card))); - Ok(opt_value_result!(card, "Get first card failed")) + Ok(opt_value_result!(card_list.into_iter().next(), "SHOULD NOT HAPPEN, CANNOT FIND ANY CARD")) } -