sequoia-keystore-backend-0.7.0/.cargo_vcs_info.json0000644000000001450000000000100157360ustar { "git": { "sha1": "038af70df88b2774fc9bcd7d59f4dcbe3f549f0b" }, "path_in_vcs": "backend" }sequoia-keystore-backend-0.7.0/Cargo.lock0000644000001535110000000000100137170ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 3 [[package]] name = "addr2line" version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" dependencies = [ "gimli", ] [[package]] name = "adler" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aead" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" dependencies = [ "crypto-common", "generic-array 0.14.7", ] [[package]] name = "aes" version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher", "cpufeatures", ] [[package]] name = "aes-gcm" version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" dependencies = [ "aead", "aes", "cipher", "ctr", "ghash", "subtle", ] [[package]] name = "aho-corasick" version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] [[package]] name = "android-tzdata" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" [[package]] name = "android_system_properties" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" dependencies = [ "libc", ] [[package]] name = "anstream" version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", "windows-sys 0.52.0", ] [[package]] name = "anyhow" version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59d2a3357dde987206219e78ecfbbb6e8dad06cbb65292758d3270e6254f7355" [[package]] name = "argon2" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072" dependencies = [ "base64ct", "blake2", "cpufeatures", "password-hash", ] [[package]] name = "ascii-canvas" version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6" dependencies = [ "term", ] [[package]] name = "async-trait" version = "0.1.81" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "autocfg" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" version = "0.3.73" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" dependencies = [ "addr2line", "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", ] [[package]] name = "base64" version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64ct" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bindgen" version = "0.68.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "726e4313eb6ec35d2730258ad4e15b547ee75d6afaa1361a922e78e59b7d8078" dependencies = [ "bitflags", "cexpr", "clang-sys", "lazy_static", "lazycell", "peeking_take_while", "proc-macro2", "quote", "regex", "rustc-hash", "shlex", "syn", ] [[package]] name = "bit-set" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" dependencies = [ "bit-vec", ] [[package]] name = "bit-vec" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" [[package]] name = "bitflags" version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "blake2" version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" dependencies = [ "digest", ] [[package]] name = "block-buffer" version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array 0.14.7", ] [[package]] name = "block-padding" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" dependencies = [ "generic-array 0.14.7", ] [[package]] name = "buffered-reader" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db26bf1f092fd5e05b5ab3be2f290915aeb6f3f20c4e9f86ce0f07f336c2412f" dependencies = [ "libc", ] [[package]] name = "bumpalo" version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "byteorder" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" [[package]] name = "cc" version = "1.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57b6a275aa2903740dc87da01c62040406b8812552e97129a63ea8850a17c6e6" dependencies = [ "shlex", ] [[package]] name = "cexpr" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" dependencies = [ "nom", ] [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "wasm-bindgen", "windows-targets", ] [[package]] name = "cipher" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ "crypto-common", "inout", "zeroize", ] [[package]] name = "clang-sys" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" dependencies = [ "glob", "libc", "libloading", ] [[package]] name = "cmac" version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8543454e3c3f5126effff9cd44d562af4e31fb8ce1cc0d3dcd8f084515dbc1aa" dependencies = [ "cipher", "dbl", "digest", ] [[package]] name = "colorchoice" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" [[package]] name = "const-oid" version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "core-foundation-sys" version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" dependencies = [ "libc", ] [[package]] name = "crunchy" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-common" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array 0.14.7", "rand_core", "typenum", ] [[package]] name = "ctr" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" dependencies = [ "cipher", ] [[package]] name = "curve25519-dalek" version = "4.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" dependencies = [ "cfg-if", "cpufeatures", "curve25519-dalek-derive", "digest", "fiat-crypto", "rustc_version", "subtle", "zeroize", ] [[package]] name = "curve25519-dalek-derive" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "dbl" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd2735a791158376708f9347fe8faba9667589d82427ef3aed6794a8981de3d9" dependencies = [ "generic-array 0.14.7", ] [[package]] name = "der" version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", "zeroize", ] [[package]] name = "digest" version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", "const-oid", "crypto-common", "subtle", ] [[package]] name = "dirs-next" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" dependencies = [ "cfg-if", "dirs-sys-next", ] [[package]] name = "dirs-sys-next" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" dependencies = [ "libc", "redox_users", "winapi", ] [[package]] name = "displaydoc" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "doc-comment" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" [[package]] name = "dyn-clone" version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" [[package]] name = "eax" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9954fabd903b82b9d7a68f65f97dc96dd9ad368e40ccc907a7c19d53e6bfac28" dependencies = [ "aead", "cipher", "cmac", "ctr", "subtle", ] [[package]] name = "ed25519" version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ "pkcs8", "signature", ] [[package]] name = "ed25519-dalek" version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" dependencies = [ "curve25519-dalek", "ed25519", "rand_core", "serde", "sha2", "subtle", "zeroize", ] [[package]] name = "either" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "ena" version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5" dependencies = [ "log", ] [[package]] name = "env_filter" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab" dependencies = [ "log", "regex", ] [[package]] name = "env_logger" version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" dependencies = [ "anstream", "anstyle", "env_filter", "humantime", "log", ] [[package]] name = "equivalent" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", ] [[package]] name = "fastrand" version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "fiat-crypto" version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "fixedbitset" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "futures" version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", "futures-executor", "futures-io", "futures-sink", "futures-task", "futures-util", ] [[package]] name = "futures-channel" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", ] [[package]] name = "futures-core" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ "futures-core", "futures-task", "futures-util", ] [[package]] name = "futures-io" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "futures-sink" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 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.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", ] [[package]] name = "generic-array" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96512db27971c2c3eece70a1e106fbe6c87760234e31e8f7e5634912fe52794a" dependencies = [ "typenum", ] [[package]] name = "getrandom" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "js-sys", "libc", "wasi", "wasm-bindgen", ] [[package]] name = "ghash" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" dependencies = [ "opaque-debug", "polyval", ] [[package]] name = "gimli" version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "glob" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "hermit-abi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hkdf" version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" dependencies = [ "hmac", ] [[package]] name = "hmac" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ "digest", ] [[package]] name = "humantime" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "iana-time-zone" version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", "windows-core", ] [[package]] name = "iana-time-zone-haiku" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ "cc", ] [[package]] name = "icu_collections" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" dependencies = [ "displaydoc", "yoke", "zerofrom", "zerovec", ] [[package]] name = "icu_locid" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" dependencies = [ "displaydoc", "litemap", "tinystr", "writeable", "zerovec", ] [[package]] name = "icu_locid_transform" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" dependencies = [ "displaydoc", "icu_locid", "icu_locid_transform_data", "icu_provider", "tinystr", "zerovec", ] [[package]] name = "icu_locid_transform_data" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" [[package]] name = "icu_normalizer" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" dependencies = [ "displaydoc", "icu_collections", "icu_normalizer_data", "icu_properties", "icu_provider", "smallvec", "utf16_iter", "utf8_iter", "write16", "zerovec", ] [[package]] name = "icu_normalizer_data" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" [[package]] name = "icu_properties" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" dependencies = [ "displaydoc", "icu_collections", "icu_locid_transform", "icu_properties_data", "icu_provider", "tinystr", "zerovec", ] [[package]] name = "icu_properties_data" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" [[package]] name = "icu_provider" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" dependencies = [ "displaydoc", "icu_locid", "icu_provider_macros", "stable_deref_trait", "tinystr", "writeable", "yoke", "zerofrom", "zerovec", ] [[package]] name = "icu_provider_macros" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "idna" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ "idna_adapter", "smallvec", "utf8_iter", ] [[package]] name = "idna_adapter" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" dependencies = [ "icu_normalizer", "icu_properties", ] [[package]] name = "indexmap" version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" dependencies = [ "equivalent", "hashbrown", ] [[package]] name = "inout" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" dependencies = [ "block-padding", "generic-array 0.14.7", ] [[package]] name = "is_terminal_polyfill" version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itertools" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" dependencies = [ "either", ] [[package]] name = "js-sys" version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" dependencies = [ "wasm-bindgen", ] [[package]] name = "lalrpop" version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55cb077ad656299f160924eb2912aa147d7339ea7d69e1b5517326fdcec3c1ca" dependencies = [ "ascii-canvas", "bit-set", "ena", "itertools", "lalrpop-util", "petgraph", "regex", "regex-syntax", "string_cache", "term", "tiny-keccak", "unicode-xid", "walkdir", ] [[package]] name = "lalrpop-util" version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553" dependencies = [ "regex-automata", ] [[package]] name = "lazy_static" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" dependencies = [ "spin", ] [[package]] name = "lazycell" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" [[package]] name = "libloading" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", "windows-targets", ] [[package]] name = "libm" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "libredox" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ "bitflags", "libc", ] [[package]] name = "linux-raw-sys" version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "litemap" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" [[package]] name = "lock_api" version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", ] [[package]] name = "log" version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "memchr" version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memsec" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c797b9d6bb23aab2fc369c65f871be49214f5c759af65bde26ffaaa2b646b492" [[package]] name = "minimal-lexical" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", ] [[package]] name = "mio" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ "hermit-abi", "libc", "wasi", "windows-sys 0.52.0", ] [[package]] name = "nettle" version = "7.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44e6ff4a94e5d34a1fd5abbd39418074646e2fa51b257198701330f22fcd6936" dependencies = [ "getrandom", "libc", "nettle-sys", "thiserror", "typenum", ] [[package]] name = "nettle-sys" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b495053a10a19a80e3a26bf1212e92e29350797b5f5bdc58268c3f3f818e66ec" dependencies = [ "bindgen", "cc", "libc", "pkg-config", "tempfile", "vcpkg", ] [[package]] name = "new_debug_unreachable" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" [[package]] name = "nom" version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" dependencies = [ "memchr", "minimal-lexical", ] [[package]] name = "num-bigint-dig" version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" dependencies = [ "byteorder", "lazy_static", "libm", "num-integer", "num-iter", "num-traits", "smallvec", ] [[package]] name = "num-integer" version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ "num-traits", ] [[package]] name = "num-iter" version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" dependencies = [ "autocfg", "num-integer", "num-traits", ] [[package]] name = "num-traits" version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "object" version = "0.36.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" dependencies = [ "memchr", ] [[package]] name = "ocb3" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c196e0276c471c843dd5777e7543a36a298a4be942a2a688d8111cd43390dedb" dependencies = [ "aead", "cipher", "ctr", "subtle", ] [[package]] name = "once_cell" version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "opaque-debug" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "parking_lot" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", ] [[package]] name = "parking_lot_core" version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", "windows-targets", ] [[package]] name = "password-hash" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" dependencies = [ "base64ct", "rand_core", "subtle", ] [[package]] name = "peeking_take_while" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" [[package]] name = "petgraph" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", "indexmap", ] [[package]] name = "phf_shared" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" dependencies = [ "siphasher", ] [[package]] name = "pin-project-lite" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkcs8" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der", "spki", ] [[package]] name = "pkg-config" version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "polyval" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" dependencies = [ "cfg-if", "cpufeatures", "opaque-debug", "universal-hash", ] [[package]] name = "precomputed-hash" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "proc-macro2" version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] [[package]] name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom", ] [[package]] name = "redox_syscall" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" dependencies = [ "bitflags", ] [[package]] name = "redox_users" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom", "libredox", "thiserror", ] [[package]] name = "regex" version = "1.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" dependencies = [ "aho-corasick", "memchr", "regex-automata", "regex-syntax", ] [[package]] name = "regex-automata" version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", "regex-syntax", ] [[package]] name = "regex-syntax" version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "rustc-demangle" version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc_version" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ "semver", ] [[package]] name = "rustix" version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ "bitflags", "errno", "libc", "linux-raw-sys", "windows-sys 0.52.0", ] [[package]] name = "rustversion" version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "same-file" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" dependencies = [ "winapi-util", ] [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "semver" version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "sequoia-keystore-backend" version = "0.7.0" dependencies = [ "anyhow", "async-trait", "env_logger", "futures", "log", "sequoia-openpgp", "tempfile", "thiserror", "tokio", ] [[package]] name = "sequoia-openpgp" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "015e5fc3d023418b9db98ca9a7f3e90b305872eeafe5ca45c5c32b5eb335c1e8" dependencies = [ "aes-gcm", "anyhow", "argon2", "base64", "buffered-reader", "chrono", "cipher", "dyn-clone", "eax", "ed25519", "ed25519-dalek", "getrandom", "hkdf", "idna", "lalrpop", "lalrpop-util", "libc", "memsec", "nettle", "num-bigint-dig", "ocb3", "rand_core", "regex", "regex-syntax", "sha1collisiondetection", "sha2", "thiserror", "win-crypto-ng", "winapi", "xxhash-rust", ] [[package]] name = "serde" version = "1.0.209" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" version = "1.0.209" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "sha1collisiondetection" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f606421e4a6012877e893c399822a4ed4b089164c5969424e1b9d1e66e6964b" dependencies = [ "digest", "generic-array 1.1.0", ] [[package]] name = "sha2" version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", "digest", ] [[package]] name = "shlex" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signature" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "rand_core", ] [[package]] name = "siphasher" version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" [[package]] name = "slab" version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] [[package]] name = "smallvec" version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", "windows-sys 0.52.0", ] [[package]] name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" [[package]] name = "spki" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", "der", ] [[package]] name = "stable_deref_trait" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "string_cache" version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" dependencies = [ "new_debug_unreachable", "once_cell", "parking_lot", "phf_shared", "precomputed-hash", ] [[package]] name = "subtle" version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" version = "2.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "578e081a14e0cefc3279b0472138c513f37b41a08d5a3cca9b6e4e8ceb6cd525" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "synstructure" version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "tempfile" version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" dependencies = [ "cfg-if", "fastrand", "once_cell", "rustix", "windows-sys 0.59.0", ] [[package]] name = "term" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" dependencies = [ "dirs-next", "rustversion", "winapi", ] [[package]] name = "thiserror" version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "tiny-keccak" version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" dependencies = [ "crunchy", ] [[package]] name = "tinystr" version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" dependencies = [ "displaydoc", "zerovec", ] [[package]] name = "tokio" version = "1.39.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9babc99b9923bfa4804bd74722ff02c0381021eafa4db9949217e3be8e84fff5" dependencies = [ "backtrace", "bytes", "libc", "mio", "pin-project-lite", "socket2", "tokio-macros", "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "typenum" version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-xid" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a" [[package]] name = "universal-hash" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ "crypto-common", "subtle", ] [[package]] name = "utf16_iter" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" [[package]] name = "utf8_iter" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "utf8parse" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "vcpkg" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version_check" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "walkdir" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", ] [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" dependencies = [ "cfg-if", "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" dependencies = [ "quote", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" [[package]] name = "win-crypto-ng" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99abfb435a71e54ab2971d8d8c32f1a7e006cdbf527f71743b1d45b93517bb92" dependencies = [ "cipher", "doc-comment", "rand_core", "winapi", "zeroize", ] [[package]] name = "winapi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ "winapi-i686-pc-windows-gnu", "winapi-x86_64-pc-windows-gnu", ] [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ "windows-sys 0.59.0", ] [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-core" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ "windows-targets", ] [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ "windows-targets", ] [[package]] name = "windows-sys" version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ "windows-targets", ] [[package]] name = "windows-targets" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", "windows_i686_gnullvm", "windows_i686_msvc", "windows_x86_64_gnu", "windows_x86_64_gnullvm", "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "write16" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" [[package]] name = "writeable" version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" [[package]] name = "xxhash-rust" version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a5cbf750400958819fb6178eaa83bee5cd9c29a26a40cc241df8c70fdd46984" [[package]] name = "yoke" version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" dependencies = [ "serde", "stable_deref_trait", "yoke-derive", "zerofrom", ] [[package]] name = "yoke-derive" version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" dependencies = [ "proc-macro2", "quote", "syn", "synstructure", ] [[package]] name = "zerofrom" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" dependencies = [ "proc-macro2", "quote", "syn", "synstructure", ] [[package]] name = "zeroize" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" [[package]] name = "zerovec" version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" dependencies = [ "yoke", "zerofrom", "zerovec-derive", ] [[package]] name = "zerovec-derive" version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", "syn", ] sequoia-keystore-backend-0.7.0/Cargo.toml0000644000000040250000000000100137350ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2021" rust-version = "1.79" name = "sequoia-keystore-backend" version = "0.7.0" authors = ["Neal H. Walfield "] build = "build.rs" autolib = false autobins = false autoexamples = false autotests = false autobenches = false description = "Traits for private key store backends." homepage = "https://sequoia-pgp.org/" readme = "README.md" keywords = [ "cryptography", "openpgp", ] categories = ["cryptography"] license = "LGPL-2.0-or-later" repository = "https://gitlab.com/sequoia-pgp/sequoia-keystore" [package.metadata.docs.rs] features = ["sequoia-openpgp/default"] [badges.maintenance] status = "actively-developed" [lib] name = "sequoia_keystore_backend" path = "src/lib.rs" [dependencies.anyhow] version = "1.0.18" [dependencies.async-trait] version = "0.1" [dependencies.env_logger] version = ">=0.10, <0.12" [dependencies.futures] version = "0.3" features = ["executor"] [dependencies.log] version = "0.4.17" [dependencies.sequoia-openpgp] version = "2" default-features = false [dependencies.tempfile] version = "3" [dependencies.thiserror] version = ">=1, <3" [dependencies.tokio] version = "1.19" features = [ "rt-multi-thread", "io-util", "net", "macros", ] [target."cfg(not(windows))".dev-dependencies.sequoia-openpgp] version = "2" features = [ "crypto-nettle", "__implicit-crypto-backend-for-tests", ] default-features = false [target."cfg(windows)".dev-dependencies.sequoia-openpgp] version = "2" features = [ "crypto-cng", "__implicit-crypto-backend-for-tests", ] default-features = false sequoia-keystore-backend-0.7.0/Cargo.toml.orig000064400000000000000000000025771046102023000174300ustar 00000000000000[package] name = "sequoia-keystore-backend" description = "Traits for private key store backends." version = "0.7.0" authors = ["Neal H. Walfield "] homepage = "https://sequoia-pgp.org/" repository = "https://gitlab.com/sequoia-pgp/sequoia-keystore" readme = "README.md" keywords = ["cryptography", "openpgp" ] categories = ["cryptography"] license = "LGPL-2.0-or-later" edition = "2021" rust-version = "1.79" build = "build.rs" [badges] maintenance = { status = "actively-developed" } [dependencies] anyhow = "1.0.18" async-trait = "0.1" env_logger = ">=0.10, <0.12" futures = { version = "0.3", features = ["executor"] } log = "0.4.17" sequoia-openpgp = { version = "2", default-features = false } thiserror = ">=1, <3" tempfile = "3" tokio = { version = "1.19", features = [ "rt-multi-thread", "io-util", "net", "macros" ] } [target.'cfg(not(windows))'.dev-dependencies] # Enables a crypto backend for the tests: sequoia-openpgp = { version = "2", default-features = false, features = ["crypto-nettle", "__implicit-crypto-backend-for-tests"] } [target.'cfg(windows)'.dev-dependencies] # Enables a crypto backend for the tests: sequoia-openpgp = { version = "2", default-features = false, features = ["crypto-cng", "__implicit-crypto-backend-for-tests"] } # Enables a crypto backend for the docs.rs generation: [package.metadata.docs.rs] features = ["sequoia-openpgp/default"] sequoia-keystore-backend-0.7.0/LICENSE.txt000064400000000000000000000627341046102023000163650ustar 00000000000000Sequoia PGP is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Sequoia PGP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. --- GNU LIBRARY GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library, or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights. Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library. Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license. The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such. Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better. However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. GNU LIBRARY GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Library General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! sequoia-keystore-backend-0.7.0/README.md000064400000000000000000000005651046102023000160130ustar 00000000000000The `sequoia-keystore` crate implements a server that manages secret key material. Secret key material can be stored in files, on hardware devices like smartcards, or accessed via the network. `sequoia-keystore` doesn't implement these access methods. This is taken care of by various backends. The backends implement a common interface, which is defined by this crate. sequoia-keystore-backend-0.7.0/build.rs000064400000000000000000000023071046102023000161750ustar 00000000000000use std::env; use std::fs; use std::io::{self, Write}; use std::path::PathBuf; /// Builds the index of the test data for use with the `::tests` /// module. fn include_test_data() -> io::Result<()> { let cwd = env::current_dir()?; let mut sink = fs::File::create( PathBuf::from(env::var_os("OUT_DIR").unwrap()) .join("tests.index.rs.inc")).unwrap(); writeln!(&mut sink, "{{")?; let mut dirs = vec![PathBuf::from("tests/data")]; while let Some(dir) = dirs.pop() { println!("rerun-if-changed={}", dir.to_str().unwrap()); for entry in fs::read_dir(dir).unwrap() { let entry = entry?; let path = entry.path(); if path.is_file() { writeln!( &mut sink, " add!({:?}, {:?});", path.components().skip(2) .map(|c| c.as_os_str().to_str().expect("valid UTF-8")) .collect::>().join("/"), cwd.join(path))?; } else if path.is_dir() { dirs.push(path.clone()); } } } writeln!(&mut sink, "}}")?; Ok(()) } fn main() { include_test_data().unwrap(); } sequoia-keystore-backend-0.7.0/src/lib.rs000064400000000000000000000757021046102023000164440ustar 00000000000000//! Defines the traits that keystore backends need to implement. //! //! Sequoia's keystore is a service, which manages and multiplexes //! access to secret key material. Conceptually, keys live on //! devices, and devices are managed by backends. A device may be as //! simple as an on-disk file, it may be a smartcard, or it could be //! another keystore server that is accessed over the network. //! //! A backend implements the traits defined in this crate. The traits //! abstract away the details of the various devices. They are mostly //! concerned with enumerating keys, and executing the low-level //! decrypt and sign operations. The backend interfaces are different //! from, and more low level than the general-purpose interface //! exposed to applications. //! //! The following figure illustrates the architecture. The squares //! represent different address spaces. //! //! ```text //! +---------------+ +---------------+ //! | Application | | Application | //! +---------------+ +---------------+ //! \ / //! +----------------------------------------------+ //! | Keystore | //! | / \ | //! | soft key openpgp card | //! | backend backend | //! +----------------------------------------------+ //! ``` //! //! The keystore does not have to run as a server; it is also possible //! to co-locate the keystore in an application, as shown here: //! //! ```text //! +----------------------------------------------+ //! | Application | //! | | | //! | Keystore | //! | / \ | //! | soft key openpgp card | //! +----------------------------------------------+ //! ``` //! //! Using a daemon instead of a library or a sub-process, which is //! spawned once per application and is terminated when the //! application terminates, offers several advantages. //! //! The main user-visible advantage is that the daemon is able to hold //! state. In the case of soft keys, the daemon can cache an //! unencrypted key in memory so that the user doesn't have to unlock //! the key as frequently. This is particularly helpful when a //! command-line tool like `sq` is executed multiple times in a row //! and each time accesses the same password-protected key. Likewise, //! a daemon can cache a PIN needed to access an HSM. It can also //! keep the HSM open thereby avoiding the initialization overhead. //! This also applies to remote keys: an ssh tunnel, for instance, can //! be held open, and reused as required. //! //! A separate daemon also simplifies an important non-functional security //! property: process separation. Since soft keys aren't managed by the //! application, but by the daemon, an attacker is not able to use a //! [heartbleed]-style attack to exfiltrate secret key material. //! //! [heartbleed]: https://heartbleed.com/ //! //! The traits model backends as collections of devices each of which //! contains zero or more keys. The following figure illustrates a //! possible configuration. The keystore uses two backends, the //! softkey backend, and the openpgp card backend, and each backend //! has two devices. The softkey backend models certificates as //! devices; the openpgp card backend has one device for each physical //! device. Each device contains between 1 and 3 keys. The interface //! does not impose a limit on the number of devices per backend, or //! the number of keys per device. As such, a TPM managing thousands //! of keys is conceivable, and in scope. //! //! ```text //! +----------------------------------------------------+ //! | Keystore | //! | / \ | //! | soft key openpgp card | //! | / \ / \ | //! | 0x1234 0xABCE Gnuk Nitro Key | //! | / \ | #123456 #234567 | //! | 0x10 0x23 0x34 / | \ / | \ | //! | 0x31 0x49 0x5A 0x64 0x71 0x88 | //! +----------------------------------------------------+ //! ``` //! //! The different devices may or may not be connected at any given //! time. For instance, the user may remove a smartcard, but if the //! backend has recorded the configuration, the keystore still knows //! about the //! //! When the keystore starts, it eagerly initializes the various //! backends that it knows about. At this time, backends are //! statically linked to the keystore, and have to be explicitly //! listed in the keystore initialization function. //! //! When a backend is initialized, the initialization function is //! passed a directory. The backend should read any required state //! from a subdirectory, which is named after the backend. For //! instance, the soft keys backend uses the "softkeys" subdirectory. //! //! A backend must be extremely careful when using state stored //! somewhere else. If a user selects a different home directory, //! then they usually want a different configuration, which is //! isolated from the main configuration. This is not entirely //! possible in the case where a backend uses a physical resource, for //! example. //! //! # Keys and Devices //! //! At its simplest, a device contains zero or more OpenPGP keys. A //! device may also be locked or unlocked, registered or not //! registered, and available or unavailable. //! //! If a device is locked, it first has to be unlocked before it can //! be used. Sometimes a device can be unlocked by supplying a //! password via the [`DeviceHandle::unlock`] interface. Other times, //! the device has to be manually unlocked by the user. If a device //! is locked, it may or may not be possible to enumerate the keys //! stored on the device. //! //! If a device is registered, then the device's configuration has //! been cached locally. In this case, the keys on the device can be //! enumerated even if the device is not connected to the host. For //! instance, when an OpenPGP card is registered, the OpenPGP card //! backend records the serial number of device, the list of keys that //! are stored on the smartcard, and their attributes. When the user //! enumerates the keys managed by the key store, these keys are //! returned, even if the smartcard is not attached. The user cannot, //! of course, use the keys. //! //! If a device is registered, but is not attached to the system, then //! it is considered unavailable. If the user attempts to use a key //! on an unavailable device, then an error is returned. In this //! case, the application could normally prompt the user to make the //! corresponding device available. //! //! These states are documented in more detail in the documentation //! for [`DeviceHandle`]. //! //! Whether a key is registered or available is purely a function of //! the device. If a device contains multiple keys, and they can be //! registered, or available independent of the other keys, then the //! backend must model the keys as separate devices. use sequoia_openpgp as openpgp; use openpgp::Fingerprint; use openpgp::KeyID; use openpgp::Result; use openpgp::Cert; use openpgp::crypto::Password; use openpgp::crypto::SessionKey; use openpgp::crypto::mpi; use openpgp::packet::PKESK; use openpgp::types::HashAlgorithm; use openpgp::types::PublicKeyAlgorithm; use openpgp::types::SymmetricAlgorithm; /// A testing framework for backends that implement this interface. /// /// Define a couple of functions and then use /// [`sequoia_keystore_backend::generate_tests!`] to generate a number /// of standard tests. pub mod test_framework; pub mod utils; mod protection; pub use protection::Protection; mod password_source; pub use password_source::PasswordSource; /// Errors used in this crate. /// /// Note: This enum cannot be exhaustively matched to allow for future /// extensions. #[non_exhaustive] #[derive(thiserror::Error, Debug)] pub enum Error { /// Invalid argument. #[error("Invalid argument: {0}")] InvalidArgument(String), /// Not found. #[error("Not found: {0}")] NotFound(String), /// Operation not supported. #[error("Operation not supported: {0}")] OperationNotSupported(String), /// The device or key is locked. /// /// A device is locked when a pin, password, or some other /// interaction is needed to unlock the device. /// /// When this error is received, the caller should prompt the user /// for the password, unlock the object, and then retry the /// operation. #[error("Object is locked: {0}")] Locked(String), /// The device or key is not available. /// /// When this error is received, the caller may prompt the user to /// insert the device, and then retry the operation. #[error("Object is not available: {0}")] Unavailable(String), /// The device is not registered. #[error("Device is not registered: {0}")] Unregistered(String), /// The device is not configured. /// /// The device may contain keys, but it first needs to be /// configured before it can be used. #[error("Device needs to be configured: {0}")] Unconfigured(String), /// The device or key is already unlocked. /// /// Returned by [`DeviceHandle::unlock`] and [`KeyHandle::unlock`] /// if a device or key is already unlocked or doesn't need to be /// unlocked. #[error("Device is already unlocked: {0}")] AlreadyUnlocked(String), /// The backend doesn't support importing keys using this interface. /// /// This error is returned by [`Backend::import`] if the backend /// requires backend-specific information in order to import a /// key, which is not provided via this interface. For instance, /// when importing a key to a smartcard, the user needs to specify /// the smartcard, and the slot to use on the smartcard. Rather /// than try and model these parameters using this generic /// interface, backends should just have their own tools. The /// text should be a hint that is displayed to the user describing /// how to find the tool. #[error("Can't import keys into the backend: {}", .0.as_deref().unwrap_or("use another tool to import keys \ into this backend"))] ExternalImportRequired(Option), /// The key doesn't support inline passwords. /// /// Password entry is taken care of by the device managing the /// key. For instance, the password may be obtained using an /// external PIN pad. #[error("Can't unlock using an inline password{}{}", .0.as_ref().map(|_| ": ").unwrap_or(""), .0.as_deref().map(|msg| msg).unwrap_or(""))] NoInlinePassword(Option), /// The key doesn't support getting passwords. /// /// The password must be provided inline. The password cannot be /// obtained using something like an external PIN pad. #[error("External password entry is not supported{}{}", .0.as_ref().map(|_| ": ").unwrap_or(""), .0.as_deref().map(|msg| msg).unwrap_or(""))] NoExternalPassword(Option), } /// The result of an import operation. /// /// This is returned by [`Backend::import`]. #[derive(Debug, Clone, PartialEq, Eq)] pub enum ImportStatus { /// The imported object is new. New, /// The imported object updated an existing object. Updated, /// The object already existed, and is unchanged. Unchanged, } /// The backend interface for the sequoia key store. /// /// This is the the interface that each device driver needs to /// implement. #[async_trait::async_trait] pub trait Backend: Send { /// Returns the backend's identifier. /// /// This should be an identifier that uniquely identifies the /// device driver, is human readable, and is stable across /// restarts. fn id(&self) -> String; /// Causes the backend to look for devices. /// /// This function should perform a lightweight scan. In /// particular, it should: /// /// - Read in the configuration of any devices that have been /// registered. /// /// - Look for locally connected devices with OpenPGP keys, /// e.g., smartcards, TPMs, etc. /// /// This function should not search for devices that may take a /// long time to find. For instance, it should not scan the /// network, or prompt the user for a password. Instead, a /// separate utility should be used to discover and register those /// devices. /// /// The backend should cache information about any devices that it /// finds in memory, but it should not register them. /// /// This function should not initialize registered devices for /// use, e.g., the ssh tunnel needed to access a remote key should /// not be brought up. /// /// In the terminology of [`DeviceHandle`], this should look for /// devices that are available or registered. async fn scan(&mut self) -> Result<()> { Err(Error::OperationNotSupported("Backend::scan".into()).into()) } /// Lists all devices that are available or registered. /// /// This does not actively perform a scan. It simply returns the /// devices that were available or registered as of the last scan. /// /// In the terminology of [`DeviceHandle`], it returns devices /// that are available or are registered. async fn list<'a>(&'a self) -> Box> + Send + Sync + 'a>; /// Returns a handle for the specified device. /// /// id is a string as returned by [`DeviceHandle::id`]. /// /// If the device is not available or not registered, then this /// should return [`Error::NotFound`]. async fn find_device<'a>(&self, id: &str) -> Result>; /// Returns a handle for the specified key. /// /// `id` is a string as returned by [`KeyHandle::id`]. /// /// If the key is not available or not registered, then this /// should return [`Error::NotFound`]. async fn find_key<'a>(&self, id: &str) -> Result>; /// Imports the keys in the cert. /// /// `cert` is a TSK. Any keys without secret key material are /// silently ignored. /// /// Returns each key's import status, and a capability to the key. /// /// If the TSK doesn't include any secret keys, then an empty list /// is returned. /// /// Some backends require additional information to import a key. /// These backends should [`Error::ExternalImportRequired`], and /// indicate how a user might import a key to this backend. async fn import<'a>(&self, cert: Cert) -> Result)>>; } /// A device that contains zero or more keys. /// /// # Device Properties /// /// A device has three properties: it can be available or not, /// configured or not, and registered or not. /// /// ## Available /// /// A device is available if the secret key material can be used. /// (This is independent of whether the secret key material is /// locked.) A smart card, for instance, is available when it is /// inserted, and it is not available when it is not inserted. /// Devices that are available are always returned by /// [`Backend::list`]. /// /// ## Configured /// /// A device is configured if it can be used without further /// configuration. (This is independent of whether the secret key /// material is locked.) To use the secret key material on a /// smartcard or a TPM, the user may first need to load the OpenPGP /// certificate corresponding to the secret keys. Most devices, /// however, are already configured, or are able to configure /// themselves without the user's intervention. For instance, OpenPGP /// smartcards don't normally contain the OpenPGP certificate /// corresponding to the secret keys, but they do contain the keys' /// OpenPGP fingerprints, and an OpenPGP card backend could fetch /// the certificate's without user intervention. /// /// Devices that are available, but not configured should still be /// returned by [`Backend::list`]. However, because the keys may not /// be known, the keys may not be enumerable or not usable. In this /// case, [`DeviceHandle::list`] should return /// [`Error::Unconfigured`]. /// /// If a device contains multiple keys, and some can be configured /// while others aren't, then each key should be exposed as a separate /// device; this API assumes that either no key or all keys on a given /// device are configured. /// /// ## Registered /// /// A device that is registered is a device whose meta-data has been /// saved locally. Devices that are registered are returned by /// [`Backend::list`] even if they are not available. Likewise, the /// keys on a registered device are returned by [`DeviceHandle::list`] /// even when the device is not available. When the key store /// attempts to decrypt a message, it may prompt the user to insert an /// unavailable, registered device. /// /// When a backend scans for devices, it should not automatically /// register devices. Once a device has been successfully used, /// however, a backend may register the device. For instance, a smart /// card that is discovered by a scan should not automatically be /// registered. However, when the smart card is successfully used to /// create a signature or decrypt a message, then it may be registered /// without further intervention from the user. /// /// ## Alternate View /// /// Another, less precise view, is that a device may be in one of the /// following states: /// /// - Ready: The device is available and configured. /// /// The device can be used immediately. For instance, a soft key, /// or a smartcard that is inserted. /// /// A device that is ready may still need to be unlocked. /// /// - Disconnected: A device that was registered, but is not /// available. /// /// The device is not available, but the user may be prompted to /// make it available. For instance, if a key needed to decrypt a /// message is on a smartcard that is unavailable, the user may be /// prompted to insert the smartcard. Similarly, if a key is /// accessible via an ssh tunnel, but the ssh tunnel cannot be /// established, the user may be prompted to connect to the /// network. /// /// The backend should still expose all of an unavailable device's /// keys (insofar as they are known), however, the decrypt and /// sign operations should fail with [`Error::Unavailable`]. /// /// - Unusable: A device that was discovered, but that cannot be /// used without some additional configuration. For instance, a /// smartcard or a TPM key may need the corresponding certificate /// before it can be used. /// /// - Unknown: A device that is not available, and not registered. /// /// The aforementioned three properties map onto these states as /// follows: /// /// ```text /// Available, Configured, Registered: Ready /// Available, Configured, Not Registered: Ready /// Available, Not Configured, Registered: Unusable /// Available, Not Configured, Not Registered: Unusable /// Not Available, Configured, Registered: Disconnected /// Not Available, Configured, Not Registered: Unknown /// Not Available, Not Configured, Registered: Disconnected /// Not Available, Not Configured, Not Registered: Unknown /// ``` /// /// A device is only ever instantiated if it is available or registered. #[async_trait::async_trait] pub trait DeviceHandle { /// Returns the device's id. /// /// The id is a globally unique, stable, and mostly human readable /// identifier. fn id(&self) -> String; /// Returns the device's description. /// /// The description is a human readable string, e.g., "GnuK with /// certificate FINGERPRINT". async fn description(&self) -> String { self.id() } /// Sets the device's human readable description. /// /// This should fail if the device is not registered. async fn set_description(&self, _description: String) -> Result<()> { Err(Error::Unregistered(self.id()).into()) } /// Returns whether the device is available. /// /// A device is available if it is plugged-in. async fn available(&self) -> bool; /// Returns whether the device is configured. /// /// A device is configured if the keys can be used without further /// configuration. async fn configured(&self) -> bool; /// Returns whether the device is registered. /// /// A device is registered if the device is locally memorized. In /// this case, the user may be prompted to insert the device. async fn registered(&self) -> bool; /// Registers the device. /// /// This explicitly registers the device. The backend should /// memorize the device and should return it during a scan even if /// it is not available. If the device is already registered, /// this should silently succeed. async fn register(&mut self) -> Result<()> { Err(Error::OperationNotSupported("DeviceHandle::register".into()).into()) } /// Unregisters the device from the backend. /// /// This should not destroy any secret key material stored on the /// device. It should just remove any cached state about the /// device. For instance, if the device is an ssh tunnel, then /// the ssh tunnel's configuration should be forgotten. If the /// device is a smart card, then the smart card should be /// forgotten. Note: if the smart card is inserted, it is still /// available and thus still usable. /// /// Note: devices that are not available can only be registered /// using a backend-specific tool. For instance, a device /// accessible via an ssh tunnel is never available. async fn unregister(&mut self) -> Result<()> { Err(Error::OperationNotSupported("DeviceHandle::unregister".into()).into()) } /// Connects to and unlocks the device. /// /// Some devices need to be initialized. For instance, to access /// a remote key, it may be necessary to create an ssh tunnel. /// Some devices need to be unlocked before the keys can be /// enumerated. For instance, if soft keys are stored in a /// database and the database is encrypted, it may be necessary to /// supply a password to decrypt the database. async fn unlock(&mut self, _password: &Password) -> Result<()> { Err(Error::AlreadyUnlocked("DeviceHandle::unlock".into()).into()) } /// Locks the device and any keys in contains. /// /// Locks the device if it has been previously unlocked as well as /// any keys managed by the device. If the device is locked or /// can't be locked, this is a noop. If the device needs to be /// deinitialized, it MAY be deinitialized lazily if doing so /// cannot result in a user-visible error. For instance, if the /// device uses an ssh tunnel, the ssh tunnel may be closed later. async fn lock(&mut self) -> Result<()> { Ok(()) } /// Lists keys on the device. /// /// Returns the keys on the device. If the device is not usable, /// then this should return [`Error::Unconfigured`]. async fn list<'a>(&'a self) -> Box> + Send + Sync + 'a>; } /// A Key on a Device. /// /// A key may or may not be available. This is a function of the /// device. #[async_trait::async_trait] pub trait KeyHandle { /// Returns the key's id. /// /// The id is a globally unique, stable, and mostly human readable /// identifier. An example of a good id is the concatenation of /// the the key's fingerprint, and the device's serial number, /// e.g., "Key 8F17777118A33DDA9BA48E62AACB3243630052D9 on Yubikey /// 5 #217813388320." fn id(&self) -> String; /// Returns the key's handle. fn key_handle(&self) -> openpgp::KeyHandle { self.fingerprint().into() } /// Returns the key's fingerprint. fn fingerprint(&self) -> Fingerprint; /// Returns the key's key ID. fn keyid(&self) -> KeyID { KeyID::from(self.fingerprint()) } /// Returns the key's device. async fn device<'a>(&self) -> Box; /// Returns whether the key is available. async fn available(&self) -> bool; /// Returns whether the key is locked. async fn locked(&self) -> Protection; /// Returns how the password is obtained. /// /// This is similar to, but not identical to /// [`KeyHandle::locked`]. This function indicates how the /// password must be provided independency of the current /// protection. async fn password_source(&self) -> PasswordSource; /// Returns whether the key is decryption capable. async fn decryption_capable(&self) -> bool; /// Returns whether the key is signing capable. async fn signing_capable(&self) -> bool; /// Unlocks a key. /// /// A key is typically unlocked by providing a password or pin. /// Not all keys are locked. If the key is not available, this /// should attempt to connect to the device. If the device is not /// available or cannot be initialized, then this should fail. /// /// If `password` is `Some` and [`KeyHandle::password_source`] /// indicates that the password cannot be provided inline, then /// the backend must return [`Error::NoInlinePassword`]. Likewise, /// if `password` is `None`, and [`KeyHandle::password_source`] /// does not indicate that the user can be prompted for the /// password ([`PasswordSource::ExternalOnDemand`]), then the /// backend must return [`Error::NoExternalPassword`]. /// /// If the key is already unlocked, this returns /// [`Error::AlreadyUnlocked`]. async fn unlock(&mut self, _password: Option<&Password>) -> Result<()> { Err(Error::AlreadyUnlocked("KeyHandle::unlock".into()).into()) } /// Lock a key. /// /// Relocks the key. This usually causes the backend to forget the /// key's password. async fn lock(&mut self) -> Result<()> { Ok(()) } /// Returns the corresponding public key. /// /// The backend SHOULD ensure that the secret key material is /// removed. async fn public_key(&self) -> openpgp::packet::Key; /// Decrypts a PKESK. /// async fn decrypt_pkesk(&mut self, pkesk: &PKESK) -> Option<(Option, SessionKey)> { // We want to use `PKESK::decrypt`. For that, we need // something that implements the `Decryptor` interface. We // could implement `Decryptor` for `KeyHandle`, but then that // is part of our public API. Instead, we do a bit of // acrobatics here. struct Decryptor<'a, T> where T: KeyHandle + ?Sized { slf: &'a mut T, pk: openpgp::packet::Key< openpgp::packet::key::PublicParts, openpgp::packet::key::UnspecifiedRole>, } impl<'a, T> openpgp::crypto::Decryptor for Decryptor<'a, T> where T: KeyHandle + ?Sized + Send { fn public(&self) -> &openpgp::packet::Key< openpgp::packet::key::PublicParts, openpgp::packet::key::UnspecifiedRole> { &self.pk } fn decrypt(&mut self, ciphertext: &mpi::Ciphertext, plaintext_len: Option) -> Result { // We know that pkesk.decrypt is running on a separate // thread. So it is safe to create a new runtime on // this thread. let rt = tokio::runtime::Runtime::new()?; rt.block_on(async { self.slf.decrypt_ciphertext(ciphertext, plaintext_len).await }) } } let pk = self.public_key(); let pk = pk.await; let mut decryptor = Decryptor { slf: self, pk: pk, }; // To avoid blocking the current thread, we run the sync // function `pkesk.decrypt` on a separate thread. When it is // done, it results the result via a one shot channel, which // we can asynchronously wait on. let (sender, receiver) = futures::channel::oneshot::channel::<_>(); std::thread::scope(|s| { s.spawn(move || { sender.send(pkesk.decrypt(&mut decryptor, None)) }); }); match receiver.await { Ok(Some(result)) => Some(result), Ok(None) => None, Err(_) => None, } } /// Decrypts a ciphertext. /// /// This method has the same semantics as /// [`sequoia_openpgp::crypto::Decryptor::decrypt`]. /// /// Returns the session key. async fn decrypt_ciphertext(&mut self, ciphertext: &mpi::Ciphertext, plaintext_len: Option) -> Result; /// Signs a message. /// /// `text` is the message to sign. async fn sign(&mut self, hash_algo: HashAlgorithm, text: &[u8]) -> Result<(PublicKeyAlgorithm, mpi::Signature)>; /// Exports the secret key material. async fn export(&mut self) -> Result>; /// Changes the key's password. /// /// Changes the password. Before calling this function, you /// should call [`KeyHandle::password_source`] to determine if you /// need to unlock the key, and whether you need to provide the /// new password directly, or if that is obtained externally. /// /// If `new_password` is `Some` and [`KeyHandle::password_source`] /// indicates that the password cannot be provided inline, then /// the backend must return [`Error::NoInlinePassword`]. Likewise, /// if `new_password` is `None`, and /// [`KeyHandle::password_source`] does not indicate that the user /// can be prompted for the password, then the backend must return /// [`Error::NoExternalPassword`]. async fn change_password(&mut self, new_password: Option<&Password>) -> Result<()>; /// Deletes the key. /// /// This destroys the key's secret key material. /// /// If the key has to be unlocked, and the key is locked, the /// backend should return an error. /// /// If the device managing the key does not support deleting keys, /// then it should return [`Error::OperationNotSupported`]. async fn delete_secret_key_material(&mut self) -> Result<()>; } sequoia-keystore-backend-0.7.0/src/password_source.rs000064400000000000000000000054141046102023000211110ustar 00000000000000#[cfg(doc)] use crate::KeyHandle; /// How the password is obtained. #[derive(Debug)] pub enum PasswordSource { // keystore_protocol.capnp PasswordSource: /// The application must provide the password to unlock the key. /// /// This means that if a key is locked, then before executing a /// private key operation, the key must be unlocked using /// [`KeyHandle::unlock`]. Inline, /// The application must provide the password to unlock the key, /// but operations must be confirmed externally. /// /// This means that if a key is locked, then before executing a /// private key operation, the key must be unlocked using /// [`KeyHandle::unlock`]. These operations may require the user /// externally confirm the operation. InlineWithConfirmation, /// The user must provide the password out of band. /// /// The user provides the password using an external pinpad, or /// via a trusted user interface so as to not reveal the password /// to the application or system. /// /// This means if the key is locked, the user will be prompted to /// unlock it as a side effect of a private key operation. /// /// The application can use [`KeyHandle::unlock`] to proactively /// cause the user to be prompted to unlock the key. ExternalOnDemand, /// The user must provide the password out of band as a side /// effect of an operation. /// /// The user provides the password using an external pinpad, or /// via a trusted user interface so as to not reveal the password /// to the application or system. /// /// This means if the key is locked, the user will be prompted to /// unlock it as a side effect of a private key operation. /// /// The application cannot proactively cause the user to be /// prompted to unlock the key; the prompt is only a side effect /// of a private key operation. That is, the key cannot be /// unlocked using [`KeyHandle::unlock`]. ExternalSideEffect, } impl PasswordSource { /// Returns whether the password needs to be provided inline. /// /// Returns whether this is [`PasswordSource::Inline`] or /// [`PasswordSource::InlineWithConfirmation`]. pub fn is_inline(&self) -> bool { match self { PasswordSource::Inline => true, PasswordSource::InlineWithConfirmation => true, PasswordSource::ExternalSideEffect => false, PasswordSource::ExternalOnDemand => false, } } /// Returns whether the password will be provided externally. /// /// Returns whether this is [`PasswordSource::ExternalSideEffect`] /// or [`PasswordSource::ExternalOnDemand`]. pub fn is_external_source(&self) -> bool { ! self.is_inline() } } sequoia-keystore-backend-0.7.0/src/protection.rs000064400000000000000000000036651046102023000200630ustar 00000000000000/// How secret key material is protected. #[derive(Debug)] pub enum Protection { // keystore_protocol.capnp Protection: /// The secret key material is unlocked. Unlocked, /// The key store is not able to determine if the secret key /// material is protected. /// /// It is, however, safe to try a secret key operation (e.g., the /// retry counter will not be decremented). Trying an operation /// may trigger an external event, like a system pin entry dialog. UnknownProtection(Option), /// The secret key material is protected by a password. It can /// be unlocked using the unlock interface. /// /// The string is an optional hint for the user. Password(Option), /// The secret key material is protected, and can only be unlocked /// using an external terminal. /// /// The string is an optional hint for the user. /// /// Note: some devices don't provide a mechanism to determine if /// the secret key material is currently locked. For instance, /// some smart cards can be configured to require the user to /// enter a pin on an external keypad before their first use, but /// not require it as long as the smart card remains attached to /// the host, and also not provide a mechanism for the host to /// determine the current policy. Such devices should still /// report `Protection::ExternalPassword`, and should phrase the /// hint appropriately. ExternalPassword(Option), /// The secret key material is protected, and can only be unlocked /// if the user touches the device. /// /// The string is an optional hint for the user. ExternalTouch(Option), /// The secret key material is protected, and can only be unlocked /// externally. /// /// The string is an optional hint for the user, e.g., "Please connect /// to the VPN." ExternalOther(Option), } sequoia-keystore-backend-0.7.0/src/test_framework/data.rs000064400000000000000000000034631046102023000216360ustar 00000000000000//! Test data. //! //! Includes the test data from `tests/data` in a structured way. use std::collections::BTreeMap; /// Returns the content of the given file below `tests/data`. pub fn file(name: &str) -> &'static [u8] { try_file(name).unwrap_or_else(|| panic!("No such file {:?}", name)) } /// Returns the content of the given file below `tests/data`, fallible /// version. pub fn try_file(name: &str) -> Option<&'static [u8]> { use std::sync::OnceLock; static FILES: OnceLock> = OnceLock::new(); FILES.get_or_init(|| { let mut m: BTreeMap<&'static str, &'static [u8]> = Default::default(); macro_rules! add { ( $key: expr, $path: expr ) => { m.insert($key, include_bytes!($path)) } } include!(concat!(env!("OUT_DIR"), "/tests.index.rs.inc")); // Sanity checks. assert!(m.contains_key("keys/no-password.asc")); assert!(m.contains_key("messages/no-password.asc")); m }).get(name).cloned() } /// Returns the content of the given file below `tests/data/keys`. pub fn key(name: &str) -> &'static [u8] { try_key(name).unwrap_or_else(|| panic!("No such key {:?}", name)) } /// Returns the content of the given file below `tests/data/keys`, /// fallible version. pub fn try_key(name: &str) -> Option<&'static [u8]> { try_file(&format!("keys/{}", name)) } /// Returns the content of the given file below `tests/data/messages`. pub fn message(name: &str) -> &'static [u8] { try_message(name).unwrap_or_else(|| panic!("No such message {:?}", name)) } /// Returns the content of the given file below `tests/data/messages`, /// fallible version. pub fn try_message(name: &str) -> Option<&'static [u8]> { try_file(&format!("messages/{}", name)) } sequoia-keystore-backend-0.7.0/src/test_framework.rs000064400000000000000000001323431046102023000207250ustar 00000000000000use std::io::Read; use sequoia_openpgp as openpgp; use openpgp::Cert; use openpgp::Fingerprint; use openpgp::Result; use openpgp::crypto::Password; use openpgp::crypto::mpi; use openpgp::crypto; use openpgp::packet::Key; use openpgp::packet::Packet; use openpgp::packet::key::PublicParts; use openpgp::packet::key::UnspecifiedRole; use openpgp::packet::signature::SignatureBuilder; use openpgp::parse::PacketParser; use openpgp::parse::PacketParserResult; use openpgp::parse::Parse; use openpgp::parse::stream::GoodChecksum; use openpgp::parse::stream::MessageLayer; use openpgp::parse::stream::MessageStructure; use openpgp::parse::stream::VerificationHelper; use openpgp::parse::stream::VerifierBuilder; use openpgp::serialize::stream::LiteralWriter; use openpgp::serialize::stream::Message; use openpgp::serialize::stream::Signer; use openpgp::types::HashAlgorithm; use openpgp::types::SignatureType; use anyhow::Context; /// Test data. pub mod data; use crate as backend; use crate::Backend; use crate::utils::run_async; // A wrapper for KeyHandle, which implements crypto::Signer. pub struct TestSigner( Box, Key); impl From> for TestSigner { fn from(kh: Box) -> Self { let key = run_async(async { kh.public_key().await }).expect("ok"); // XXX: don't unwrap Self(kh, key) } } impl crypto::Signer for TestSigner { fn public(&self) -> &Key { &self.1 } fn sign(&mut self, hash_algo: HashAlgorithm, digest: &[u8]) -> Result { run_async(async { self.0.sign(hash_algo, digest).await.map(|(_pk_algo, sig)| sig) })? } } pub struct VerifyHelper { // The certificates. pub keyring: Vec, // The good signatures. pub signers: Vec, } impl VerifyHelper { pub fn new(keyring: &[ Cert ]) -> Self { Self { keyring: keyring.to_vec(), signers: Vec::new(), } } } impl VerificationHelper for &mut VerifyHelper { fn get_certs(&mut self, ids: &[openpgp::KeyHandle]) -> Result> { Ok(self.keyring .iter() .filter(|cert| { cert.keys().any(|k| { ids.iter().any(|id| { id.aliases(openpgp::KeyHandle::from(k.key().fingerprint())) }) }) }) .cloned() .collect::>()) } fn check(&mut self, structure: MessageStructure) -> Result<()> { for (i, layer) in structure.into_iter().enumerate() { match layer { MessageLayer::Encryption { .. } if i == 0 => (), MessageLayer::Compression { .. } if i == 1 => (), MessageLayer::SignatureGroup { ref results } => { for r in results { if let Ok(GoodChecksum { ka, .. }) = r { self.signers.push(ka.key().fingerprint()); } else { log::info!("Bad signature: {:?}", r); } } } _ => return Err(anyhow::anyhow!( "Unexpected message structure")), } } Ok(()) } } /// Sign a message and verify that the signature is good. /// /// If signing_keys is None, this is expected to fail. pub fn sign_verify(signers: Vec, keyring: Vec, signing_keys: Option<&[ Fingerprint ]>) -> Result<()> { let p = &openpgp::policy::StandardPolicy::new(); let mut output = Vec::new(); let message = Message::new(&mut output); let builder = SignatureBuilder::new(SignatureType::Binary); let mut signers = signers.into_iter(); let mut signer = Signer::with_template( message, signers.next().expect("a signer"), builder)?; for s in signers { signer = signer.add_signer(s)?; } let signer = signer.build().context("Failed to create signer")?; let mut writer = LiteralWriter::new(signer).build() .context("Failed to create literal writer")?; std::io::copy(&mut std::io::Cursor::new(b"hello"), &mut writer) .context("Failed to sign")?; if let Err(err) = writer.finalize().context("Failed to sign") { if signing_keys.is_none() { // Expected failure. return Ok(()); } else { panic!("Failed to finalize writer: {}", err); } } let mut h = VerifyHelper::new(&keyring); let mut v = VerifierBuilder::from_bytes(&output[..])? .with_policy(p, None, &mut h)?; let mut message = Vec::new(); let r = v.read_to_end(&mut message); if let Some(signing_keys) = signing_keys { assert!(r.is_ok()); assert_eq!(message, b"hello"); assert_eq!(&h.signers, signing_keys); } else { assert!(r.is_err()); } Ok(()) } /// Try to decrypt a message. /// /// `ciphertext` is the well-formed encrypted message. /// plaintext is the expected plaintext. If it is not `None`, /// then it must match what is decrypted. /// /// `password` is an optional password. If supplied, then it /// must be used to unlock the key. /// /// This function tries to decrypt all of the keys with the password. pub async fn try_decrypt(backend: &mut B, ciphertext: &[u8], plaintext: Option<&[u8]>, recipient: openpgp::KeyHandle, password: Option) -> Result<()> where B: Backend { let mut good = false; let mut session_key = None; let mut ppr = PacketParser::from_bytes(ciphertext)?; while let PacketParserResult::Some(mut pp) = ppr { match pp.packet { Packet::PKESK(ref pkesk) if pkesk.recipient().as_ref() == Some(&recipient) => { // Manual search. log::debug!("Considering PKESK for {}", pkesk.recipient().unwrap()); 'done: for device in backend.list().await { for mut key in device.list().await { log::debug!("Considering key {}", key.fingerprint()); let key_handle = openpgp::KeyHandle::from(key.fingerprint()); if pkesk.recipient() .map(|r| ! r.aliases(&key_handle)) .unwrap_or(false) { log::debug!("Wrong key for PKESK {}", key.fingerprint()); continue; } if let Some(password) = password.as_ref() { // Relock, just in case. key.lock().await?; if let Err(e) = key.unlock(Some(password)).await { eprintln!("Failed to unlock key: {}", e); // There may be another key that we // can unlock with this password. continue; } } if let Some((algo, sk)) = key.decrypt_pkesk(&pkesk).await { session_key = Some((algo, sk)); break 'done; } } if session_key.is_none() { return Err(anyhow::anyhow!( "Decryption failed".to_string())); } } } Packet::PKESK(ref pkesk) => { // Catch-all for packets that failed the manual search. log::debug!("Ignoring PKESK for {:?}", pkesk.recipient()); } Packet::SEIP(_) => { if let Some(session_key) = session_key.take() { let (algo, sk) = session_key; log::debug!("Decrypting PKESK"); pp.decrypt(algo, &sk)?; log::debug!("Decrypting PKESK succeeded"); } else { return Err(anyhow::anyhow!( "Could not decrypt a PKESK".to_string())); } } Packet::Literal(_) => { pp.buffer_unread_content()?; if let Packet::Literal(l) = &pp.packet { if let Some(plaintext) = plaintext { if plaintext != l.body() { return Err(anyhow::anyhow!(format!( "Plaintext does not match:\n\ got: {:?},\n\ expected: {:?}", l.body(), plaintext))); } } good = true; } } _ => (), } let (_packet, next_ppr) = pp.recurse()?; ppr = next_ppr; } if let PacketParserResult::EOF(ppr) = ppr { assert!(ppr.is_message().is_ok()); // A possible reason this may fail is if the message uses // compression, but compression support is not enabled. assert!(good); } Ok(()) } /// Preinit is a function that is called at the start of every /// test. If it returns `true`, the test should be run. If it /// returns `false`, then the test should be skipped. This is useful /// when the required test infrastructure is not detected. /// /// `$serialize_tests` is whether to serialize the tests for this /// backend. If `false`, the tests are run concurrently. /// /// `$import_cert` imports a certificate into the backend. /// /// `$can_import_encrypted_secret_key_material` is whether /// `$import_cert` can import encrypted secret key material. /// /// If `$key_sets` is `Some`, then the backend can only load standard /// keys consisting of (up to) an encrypt key, a signing key and an /// authentication key. The integer indicates the number of key sets /// that the backend can load simultaneously. If `$key_sets` is /// `None`, then the backend can load an infinite number of keys. /// /// Some backends always protect keys by default. If /// `$default_password` is `Some` that's the password for keys when /// they are imported. #[macro_export] macro_rules! generate_tests { ($preinit: expr, $serialize_tests: expr, $backend: ty, $init_backend: expr, $import_cert: expr, $can_import_encrypted_secret_key_material: expr, $key_sets: expr, $default_password: expr, $can_export: expr, $can_change_password: expr, $can_delete: expr) => { static SERIALIZE: std::sync::Mutex<()> = std::sync::Mutex::new(()); fn serialize_maybe() -> Option> { let serialize_tests: bool = $serialize_tests; if serialize_tests { loop { match SERIALIZE.lock() { Ok(guard) => return Some(guard), Err(_err) => { // Another test panicked. Don't let that // stop us. SERIALIZE.clear_poison(); } } } } else { None } } /// strip the primary key's secret key material, if any. /// /// This is useful when `$key_sets` is `Some` and the backend /// doesn't have space for the primary key. fn strip_primary_secret(cert: Cert) -> Cert { if cert.primary_key().key().has_secret() { let mut pk = cert.primary_key().key().clone(); pk.steal_secret(); let cert = cert.insert_packets(pk).expect("can merge").0; assert!(! cert.primary_key().key().has_secret()); cert } else { cert } } // Make sure $import_cert works. #[tokio::test] pub async fn import_cert_helper() -> Result<()> { let _ = env_logger::Builder::from_default_env().try_init(); let _serialized = serialize_maybe(); if ! $preinit() { eprintln!("preinit returned false, skipping test."); return Ok(()); } // A simple test: import a certificate. Make sure the // keys are actually imported. let mut backend = $init_backend().await; let mut cert = Cert::from_bytes( $crate::test_framework::data::key("no-password.asc")) .expect("valid cert"); let key_sets: Option = $key_sets; if key_sets.is_some() { cert = strip_primary_secret(cert); } $import_cert(&mut backend, &cert).await; let mut imported_keys = Vec::new(); for device in backend.list().await { for key in device.list().await { imported_keys.push(key.fingerprint()); } } imported_keys.sort(); let mut expected_keys = Vec::new(); for ka in cert.keys().secret() { expected_keys.push(ka.key().fingerprint()); } expected_keys.sort(); if imported_keys != expected_keys { eprintln!( "Imported keys:{}", imported_keys.iter() .map(|fpr| fpr.to_string()) .collect::>() .join("\n ")); eprintln!( "Expected keys:{}", expected_keys.iter() .map(|fpr| fpr.to_string()) .collect::>() .join("\n ")); panic!("Importing keys is broken"); } Ok(()) } // Check backend.import_cert. #[tokio::test] pub async fn backend_import_cert() -> Result<()> { let _ = env_logger::Builder::from_default_env().try_init(); let _serialized = serialize_maybe(); if ! $preinit() { eprintln!("preinit returned false, skipping test."); return Ok(()); } // A simple test: import a certificate. Make sure the // keys are actually imported. let mut backend = $init_backend().await; let cert = Cert::from_bytes( $crate::test_framework::data::key("carol-subkeys-a.asc")) .expect("valid cert"); let mut expected_keys = Vec::new(); for ka in cert.keys().secret() { expected_keys.push(ka.key().fingerprint()); } expected_keys.sort(); for expected_status in [ImportStatus::New, ImportStatus::Unchanged] { eprintln!("expected_status: {:?}", expected_status); match backend.import(cert.clone()).await { Err(err) => { if let Some(Error::ExternalImportRequired(_)) = err.downcast_ref() { // The backend does not support import_cert. // That's okay. Skip the test. return Ok(()); } else { return Err(err); } } Ok(results) => { let mut imported_keys = results .into_iter() .map(|(import_status, key)| { assert_eq!(import_status, expected_status); key.fingerprint() }) .collect::>(); imported_keys.sort(); if imported_keys != expected_keys { eprintln!( "Imported keys:{}", imported_keys.iter() .map(|fpr| fpr.to_string()) .collect::>() .join("\n ")); eprintln!( "Expected keys:{}", expected_keys.iter() .map(|fpr| fpr.to_string()) .collect::>() .join("\n ")); panic!("Importing keys is broken"); } let mut listed_keys = Vec::new(); for device in backend.list().await { for key in device.list().await { listed_keys.push(key.fingerprint()); } } listed_keys.sort(); if listed_keys != expected_keys { eprintln!( "Listed keys:{}", listed_keys.iter() .map(|fpr| fpr.to_string()) .collect::>() .join("\n ")); eprintln!( "Expected keys:{}", expected_keys.iter() .map(|fpr| fpr.to_string()) .collect::>() .join("\n ")); panic!("Listing keys is broken"); } } } } Ok(()) } #[tokio::test] pub async fn decrypt_simple() -> Result<()> { let _ = env_logger::Builder::from_default_env().try_init(); let _serialized = serialize_maybe(); if ! $preinit() { eprintln!("preinit returned false, skipping test."); return Ok(()); } // A simple test: given a secret key and a message encrypted to // the key, can we use the backend to decrypt it? let mut backend = $init_backend().await; let cert = Cert::from_bytes( $crate::test_framework::data::key("no-password.asc")) .expect("valid cert"); $import_cert(&mut backend, &cert).await; let msg: &[u8] = $crate::test_framework::data::message("no-password.asc"); let keyid = KeyHandle::KeyID("AA5BFAC1E4A121A0".parse()?); let default_password: Option<&str> = $default_password; let default_password: Option = default_password.map(|p| Password::from(p)); if let Err(err) = $crate::test_framework::try_decrypt( &mut backend, msg, Some(b"foo\n"), keyid, default_password).await { eprintln!("Decrypting: {}", err); Err(err) } else { Ok(()) } } #[tokio::test] pub async fn decrypt_missing_password() -> Result<()> { let _ = env_logger::Builder::from_default_env().try_init(); let can_import_encrypted_secret_key_material: bool = $can_import_encrypted_secret_key_material; if ! can_import_encrypted_secret_key_material { log::debug!("Backend doesn't support importing encrypt secret \ material. Skipping test."); return Ok(()); } let _serialized = serialize_maybe(); if ! $preinit() { eprintln!("preinit returned false, skipping test."); return Ok(()); } // Load a few variants of a certificate: one where the // keys are encrypted with the password "bob", one where // they are encrypted with the password "smithy", and one // that is not encrypted. let mut backend = $init_backend().await; let cert = Cert::from_bytes( $crate::test_framework::data::key("bob-password-bob.asc")) .expect("valid cert"); $import_cert(&mut backend, &cert).await; let cert = Cert::from_bytes( $crate::test_framework::data::key("bob-password-smithy.asc")) .expect("valid cert"); $import_cert(&mut backend, &cert).await; let msg: &[u8] = $crate::test_framework::data::message("bob.asc"); let keyid = KeyHandle::KeyID("0A4BA2249168D779".parse()?); assert!( $crate::test_framework::try_decrypt( &mut backend, msg, Some(b"hi bob\n"), keyid, None) .await.is_err()); Ok(()) } #[tokio::test] pub async fn decrypt_with_password() -> Result<()> { let _ = env_logger::Builder::from_default_env().try_init(); let can_import_encrypted_secret_key_material: bool = $can_import_encrypted_secret_key_material; if ! can_import_encrypted_secret_key_material { log::debug!("Backend doesn't support importing encrypt secret \ material. Skipping test."); return Ok(()); } let _serialized = serialize_maybe(); if ! $preinit() { eprintln!("preinit returned false, skipping test."); return Ok(()); } // Load a certificate where the keys are encrypted with // the password "bob". Make sure we can decrypt the // message. Load a variant of the certificate where the // passwords have been changed. Make sure we can decrypt // the message with the new password. Finally, load a // variant of the certificate where the keys are not // encrypted. let mut backend = $init_backend().await; let msg: &[u8] = $crate::test_framework::data::message("bob.asc"); let keyid = KeyHandle::KeyID("0A4BA2249168D779".parse()?); // Import Bob's certificate. The keys are password // protected. Make sure we can use them with the right // password, and can't with the wrong one. log::info!("Importing certificate variant #1"); let cert = Cert::from_bytes( $crate::test_framework::data::key("bob-password-bob.asc")) .expect("valid cert"); $import_cert(&mut backend, &cert).await; log::info!("Decrypting with wrong password:"); assert!( $crate::test_framework::try_decrypt( &mut backend, msg, Some(b"hi bob\n"), keyid.clone(), Some(Password::from("sup3r s3cur3"))) .await.is_err()); log::info!("Decrypting with right password:"); $crate::test_framework::try_decrypt( &mut backend, msg, Some(b"hi bob\n"), keyid.clone(), Some(Password::from("bob"))).await.unwrap(); // Import a new version of Bob's certificate in which the // keys are still encrypted, but with a different // password. log::info!("Importing certificate variant #2"); let cert2 = Cert::from_bytes( $crate::test_framework::data::key("bob-password-smithy.asc")) .expect("valid cert"); assert_eq!(cert.fingerprint(), cert2.fingerprint()); $import_cert(&mut backend, &cert2).await; log::info!("Decrypting with wrong password:"); assert!($crate::test_framework::try_decrypt( &mut backend, msg, Some(b"hi bob\n"), keyid.clone(), Some(Password::from("sup3r s3cur3"))).await.is_err()); log::info!("Decrypting with right password:"); $crate::test_framework::try_decrypt( &mut backend, msg, Some(b"hi bob\n"), keyid.clone(), Some(Password::from("smithy"))).await.unwrap(); // Import a third version of Bob's certificate in which // the keys are not encrypt. log::info!("Importing certificate variant #3"); let cert3 = Cert::from_bytes( $crate::test_framework::data::key("bob-no-password.asc")) .expect("valid cert"); assert_eq!(cert.fingerprint(), cert3.fingerprint()); $import_cert(&mut backend, &cert3).await; // Note: using the wrong password does not always fail // with a key that is not password protected. For // instance, the gpg-agent backend only provides the // cached password on demand. Since the key is not // password protected, it won't ask for a password. log::info!("Decrypting with right password:"); $crate::test_framework::try_decrypt( &mut backend, msg, Some(b"hi bob\n"), keyid.clone(), None).await.unwrap(); Ok(()) } #[tokio::test] pub async fn verify() -> Result<()> { let _ = env_logger::Builder::from_default_env().try_init(); let _serialized = serialize_maybe(); if ! $preinit() { eprintln!("preinit returned false, skipping test."); return Ok(()); } async fn test(filename: &str, signing_key: &str, password: Option<&str>, success: bool) -> Result<()> { let mut backend = $init_backend().await; let cert = Cert::from_bytes( $crate::test_framework::data::key(filename)) .expect("valid cert"); $import_cert(&mut backend, &cert).await; let mut signer = backend.find_key(&signing_key).await?; if let Some(password) = password { if let Err(err) = signer.unlock(Some(&password.into())).await { log::warn!("Failed to unlock key: {}", err); } } else { // Use the default password (if configured). let default_password: Option<&str> = $default_password; if let Some(default_password) = default_password { let default_password = Password::from(default_password); if let Err(err) = signer.unlock(Some(&default_password)).await { log::warn!("Failed to unlock key: {}", err); } } } let signing_fpr = Fingerprint::from_hex(signing_key) .expect("valid"); let expected_signers_; let expected_signers: Option<&[ Fingerprint ]> = if success { expected_signers_ = vec![ signing_fpr ]; Some(&expected_signers_[..]) } else { None }; $crate::test_framework::sign_verify( vec![ signer.into() ], vec![ cert.clone() ], expected_signers)?; Ok(()) } // A simple test: sign a message using a key with no password. test("no-password.asc", "8D46B2975890A615AF4109CB6BA1BF391DF802C8", None, true).await.expect("should pass"); let can_import_encrypted_secret_key_material: bool = $can_import_encrypted_secret_key_material; if ! can_import_encrypted_secret_key_material { log::debug!("Backend doesn't support importing encrypt secret \ material. Skipping the rest of the test."); return Ok(()); } // Sign a message using a key that is password protected, // but don't provide the password. Make sure it fails. test("bob-password-bob.asc", "9410E96E68643821794608269CB5006116833EE7", None, false).await.expect("should pass"); // Now provide the password. test("bob-password-bob.asc", "9410E96E68643821794608269CB5006116833EE7", Some("bob"), true).await.expect("should pass"); // And now provide the wrong password. test("bob-password-bob.asc", "9410E96E68643821794608269CB5006116833EE7", Some("wrong password"), false).await.expect("should pass"); Ok(()) } #[tokio::test] pub async fn list_keys() -> Result<()> { let _ = env_logger::Builder::from_default_env().try_init(); let _serialized = serialize_maybe(); if ! $preinit() { eprintln!("preinit returned false, skipping test."); return Ok(()); } let key_sets: Option = $key_sets; let _ = env_logger::Builder::from_default_env().try_init(); // We first make sure that we can list the empty backend. { let mut backend = init_backend().await; let mut got = Vec::new(); for device in backend.list().await { for mut key in device.list().await { got.push(key.fingerprint().to_string()); } } assert!(got.is_empty()); } // We have two variants of a certificate with disjoint // subkeys. When we load both certificates, make sure both // sets of variants appear. let keyring_a: &[u8] = $crate::test_framework::data::key( "carol-subkeys-a.asc"); let mut cert_a = Cert::from_bytes(keyring_a) .expect("valid cert"); if key_sets.is_some() { // Strip the primary. cert_a = strip_primary_secret(cert_a); } let keys_a = cert_a.keys().secret().map(|k| k.key().fingerprint()) .collect::>(); let keyring_b: &[u8] = $crate::test_framework::data::key( "carol-subkeys-b.asc"); let mut cert_b = Cert::from_bytes(keyring_b) .expect("valid cert"); if key_sets.is_some() { // Strip the primary. cert_b = strip_primary_secret(cert_b); } let keys_b = cert_b.keys().secret().map(|k| k.key().fingerprint()) .collect::>(); // We expect the same certificate, but with different // subkeys. assert_eq!(cert_a.fingerprint(), cert_b.fingerprint()); assert_ne!(keys_a, keys_b); let mut all_keys = keys_a.clone(); all_keys.extend_from_slice(&keys_b); all_keys.sort(); all_keys.dedup(); // Try with just a, then just b, then both variants. for (a, b) in [(true, false), (false, true), (true, true)].iter() { if *a && *b { eprintln!("Loading a and b: {:?} {:?}", keys_a, keys_b); } else if *a { eprintln!("Loading a: {:?}", keys_a); } else if *b { eprintln!("Loading b: {:?}", keys_b); } let mut keyring: Vec<&Cert> = Vec::new(); let mut keys: Vec = Vec::new(); if *a { keyring.push(&cert_a); keys.extend_from_slice(&keys_a); } if *b { keyring.push(&cert_b); keys.extend_from_slice(&keys_b); } let mut backend = init_backend().await; for cert in keyring { $import_cert(&mut backend, cert).await; } // Check that we can find the cert by iterating. let mut got = Vec::new(); for device in backend.list().await { for mut key in device.list().await { got.push(key.fingerprint()); } } got.sort(); keys.sort(); keys.dedup(); assert_eq!(keys, got, "Expected: {:?}\nGot: {:?}", keys, got); // Check that Backend::find_key returns all of the keys. for k in all_keys.iter() { let expected = keys.contains(k); eprintln!("Checking find_key({}) => {}", k.to_string(), expected); match (expected, backend.find_key(&k.to_string()).await) { (true, Ok(_)) => { } (true, Err(err)) => { panic!("Didn't find {}, but should have. \ Error message is: {}", k, err); } (false, Ok(_)) => { panic!("Found {}, but shouldn't have", k); } (false, Err(_err)) => { } } } } Ok(()) } #[tokio::test] pub async fn list_only_returns_secret_keys() -> Result<()> { let _ = env_logger::Builder::from_default_env().try_init(); let _serialized = serialize_maybe(); if ! $preinit() { eprintln!("preinit returned false, skipping test."); return Ok(()); } // Make sure only keys with secret key material are returned. let cert_bytes: &[u8] = test_framework::data::key( "dave-not-all-keys-have-secrets.asc"); let cert = Cert::from_bytes(cert_bytes) .expect("valid cert"); let (keys, public_keys): (Vec<(Fingerprint, bool)> , _) = cert .keys() .map(|k| (k.key().fingerprint(), k.key().has_secret())) .partition(|(_fpr, has_secret)| *has_secret); let keys = keys.into_iter().map(|(fpr, _)| fpr) .collect::>(); let public_keys = public_keys.into_iter().map(|(fpr, _)| fpr) .collect::>(); assert!(! keys.is_empty()); assert!(! public_keys.is_empty()); let mut backend = init_backend().await; $import_cert(&mut backend, &cert).await; // List the keys. let mut got = Vec::new(); for device in backend.list().await { for key in device.list().await { got.push(key.fingerprint()); } } got.sort(); assert_eq!(keys, got); // Check that Backend::find_key returns all of the keys. for k in keys.iter() { assert!(backend.find_key(&k.to_string()).await.is_ok()); } // And doesn't return the public keys. for k in public_keys.iter() { assert!(backend.find_key(&k.to_string()).await.is_err()); } Ok(()) } // Check key.export #[tokio::test] pub async fn key_export() -> Result<()> { let _ = env_logger::Builder::from_default_env().try_init(); let can_export: bool = $can_export; if ! can_export { log::debug!("Backend doesn't support exporting secret key \ material. Skipping test."); return Ok(()); } let _serialized = serialize_maybe(); if ! $preinit() { eprintln!("preinit returned false, skipping test."); return Ok(()); } // A simple test: import a certificate. Make sure the // keys are actually imported. let mut backend = $init_backend().await; let cert = Cert::from_bytes( $crate::test_framework::data::key("carol-subkeys-a.asc")) .expect("valid cert"); $import_cert(&mut backend, &cert).await; let mut count = 0; for key in cert.keys().secret() { count += 1; let mut found = false; 'find: for mut d in backend.list().await { for mut k in d.list().await { if k.fingerprint() == key.key().fingerprint() { let exported_key = k.export().await.expect("can export"); assert_eq!(&exported_key, key.key()); found = true; break 'find; } } } assert!(found, "{} was not imported", key.key().fingerprint()); } // Make sure we tested something. assert!(count > 0); Ok(()) } #[tokio::test] pub async fn change_password() -> Result<()> { let _ = env_logger::Builder::from_default_env().try_init(); let can_change_password: bool = $can_change_password; if ! can_change_password { log::debug!("Backend doesn't support changing passwords. \ Skipping test."); return Ok(()); } let _serialized = serialize_maybe(); if ! $preinit() { eprintln!("preinit returned false, skipping test."); return Ok(()); } // Load a certificate where the keys are encrypted with // the password "bob". Make sure we can use it to decrypt // a message. Change the key's password, and relock it. // Make sure we can't decrypt the message with the old // password, but can decrypt it with the new password. let mut backend = $init_backend().await; let msg: &[u8] = $crate::test_framework::data::message("bob.asc"); let fpr_str = "86353DE523CB334DC0B1F0F00A4BA2249168D779"; let fpr: sequoia_openpgp::Fingerprint = fpr_str.parse().expect("valid"); let keyid = KeyHandle::KeyID(fpr.into()); // Import Bob's certificate. They keys are password // protected. Make sure we can use them with the right // password, and can't with the wrong one. log::info!("Importing certificate variant #1"); let cert = Cert::from_bytes( $crate::test_framework::data::key("bob-password-bob.asc")) .expect("valid cert"); $import_cert(&mut backend, &cert).await; log::info!("Decrypting with wrong password:"); assert!( $crate::test_framework::try_decrypt( &mut backend, msg, Some(b"hi bob\n"), keyid.clone(), Some(Password::from("sup3r s3cur3"))) .await.is_err()); log::info!("Decrypting with right password:"); $crate::test_framework::try_decrypt( &mut backend, msg, Some(b"hi bob\n"), keyid.clone(), Some(Password::from("bob"))).await.unwrap(); // Change the password. let mut key = backend.find_key(fpr_str) .await.expect("key is present"); if let Err(err) = key.change_password(Some(&"new password".into())).await { if let Some($crate::Error::NoInlinePassword(msg)) = err.downcast_ref() { eprintln!("Changing passwords not supported by \ backend: {:?}", msg); return Ok(()); } else { panic!("Failed to change password"); } } // Relock the key. key.lock().await.expect("can lock key"); log::info!("Decrypting with wrong password:"); assert!($crate::test_framework::try_decrypt( &mut backend, msg, Some(b"hi bob\n"), keyid.clone(), Some(Password::from("sup3r s3cur3"))).await.is_err()); log::info!("Decrypting with old password:"); assert!($crate::test_framework::try_decrypt( &mut backend, msg, Some(b"hi bob\n"), keyid.clone(), Some(Password::from("smithy"))).await.is_err()); log::info!("Decrypting with new password:"); $crate::test_framework::try_decrypt( &mut backend, msg, Some(b"hi bob\n"), keyid.clone(), Some(Password::from("new password"))).await.unwrap(); Ok(()) } #[tokio::test] pub async fn delete_secret_key_material() -> Result<()> { let _ = env_logger::Builder::from_default_env().try_init(); let can_delete: bool = $can_delete; if ! can_delete { log::debug!("Backend doesn't support deleting secret key \ material. Skipping test."); return Ok(()); } let _serialized = serialize_maybe(); if ! $preinit() { eprintln!("preinit returned false, skipping test."); return Ok(()); } // Load a certificate where the keys are encrypted with // the password "bob". Make sure we can use it to decrypt // a message. Delete the primary key. Make sure we can // still decrypt the message. Delete the decryption key. // Make sure we can't decrypt the message anymore. let mut backend = $init_backend().await; let msg: &[u8] = $crate::test_framework::data::message("bob.asc"); let fpr_str = "86353DE523CB334DC0B1F0F00A4BA2249168D779"; let fpr: sequoia_openpgp::Fingerprint = fpr_str.parse().expect("valid"); let keyid = KeyHandle::KeyID(fpr.into()); // Import Bob's certificate. They keys are password // protected. Make sure we can use them with the right // password, and can't with the wrong one. log::info!("Importing certificate variant #1"); let cert = Cert::from_bytes( $crate::test_framework::data::key("bob-password-bob.asc")) .expect("valid cert"); $import_cert(&mut backend, &cert).await; log::info!("Decrypting with wrong password:"); assert!( $crate::test_framework::try_decrypt( &mut backend, msg, Some(b"hi bob\n"), keyid.clone(), Some(Password::from("sup3r s3cur3"))) .await.is_err()); log::info!("Decrypting with right password:"); $crate::test_framework::try_decrypt( &mut backend, msg, Some(b"hi bob\n"), keyid.clone(), Some(Password::from("bob"))).await.unwrap(); // Delete the primary key. log::info!("Deleting primary key:"); let primary = cert.fingerprint().to_string(); let mut key = backend.find_key(&primary) .await.expect("key is present"); if key.password_source().await.is_external_source() { eprintln!("Skipping test: backend requires that the user \ confirm key deletion"); return Ok(()); } if let Err(err) = key.delete_secret_key_material().await { panic!("Failed to delete {}", primary); } // Make sure we can't find the primary key any more. assert!(backend.find_key(&primary).await.is_err()); log::info!("Decrypting with right password:"); $crate::test_framework::try_decrypt( &mut backend, msg, Some(b"hi bob\n"), keyid.clone(), Some(Password::from("bob"))).await.unwrap(); log::info!("Deleting decryption key:"); let mut key = backend.find_key(&fpr_str) .await.expect("key is present"); if let Err(err) = key.delete_secret_key_material().await { panic!("Failed to delete {}", primary); } assert!( $crate::test_framework::try_decrypt( &mut backend, msg, Some(b"hi bob\n"), keyid.clone(), Some(Password::from("bob"))) .await.is_err()); // Make sure we can't find the decryption key any more. assert!(backend.find_key(&fpr_str).await.is_err()); Ok(()) } }; } sequoia-keystore-backend-0.7.0/src/utils.rs000064400000000000000000000076131046102023000170320ustar 00000000000000use std::ops::Deref; use std::path::Path; use std::path::PathBuf; use std::sync::Arc; use crate::Result; /// A directory, which is possibly self-destructing. /// /// References a directory. The directory may be a permanent /// directory, or a temporary directory, which is automatically /// cleaned up when the data structure is dropped. #[derive(Clone, Debug)] pub enum Directory { Directory(PathBuf), TempDir(Arc), } impl Deref for Directory { type Target = Path; fn deref(&self) -> &Path { match self { Directory::Directory(d) => d.as_path(), Directory::TempDir(d) => d.path(), } } } impl From for Directory { fn from(pathbuf: PathBuf) -> Directory { Directory::Directory(pathbuf) } } impl From<&Path> for Directory { fn from(path: &Path) -> Directory { Directory::Directory(path.to_path_buf()) } } impl From for Directory { fn from(tempdir: tempfile::TempDir) -> Directory { Directory::TempDir(Arc::new(tempdir)) } } impl AsRef for Directory { fn as_ref(&self) -> &Path { self.deref() } } impl Directory { /// Returns an ephemeral home directory. /// /// An ephmeral home directory is a temporary directory that is /// removed when `self` goes out of scope. pub fn ephemeral() -> Result { Ok(Directory::from( tempfile::Builder::new().prefix("sq-keystore").tempdir()?)) } /// Returns the home directory in a `PathBuf`. pub fn to_path_buf(&self) -> PathBuf { self.as_ref().to_path_buf() } } /// Maps a panic of a worker thread to an error. /// /// Unfortunately, there is nothing useful to do with the error, but /// returning a generic error is better than panicking. fn map_panic(_: Box) -> anyhow::Error { anyhow::anyhow!("worker thread panicked") } /// A helper function to run an asynchronous task in a sync context. /// /// If we are in a sync context, we can't use any async functions /// without creating a new async runtime. Although it is possible to /// get a handle to an existing runtime using /// [`tokio::runtime::Handle::try_current`](https://docs.rs/tokio/latest/tokio/runtime/struct.Handle.html#method.try_current), /// we can't actually use it to run a sync function. Specifically, if /// we do: /// /// ```text /// if let Ok(rt) = tokio::runtime::Handle::try_current() { /// Ok(rt.block_on(f)) /// } /// ``` /// /// then Tokio will panic: /// /// ```text /// thread 'tests::verify' panicked at 'Cannot start a runtime from within a runtime. This happens because a function (like `block_on`) attempted to block the current thread while the thread is being used to drive asynchronous tasks.', backend/src/utils.rs:97:15 /// ``` /// /// Instead, we check if there is an async runtime, if *not*, then we /// create an async runtime using Tokio, run the async function, and /// return. If there is an async runtime, we start a new thread, /// create a new runtime there, and execute the function using that /// runtime. pub fn run_async(f: F) -> Result where F::Output: Send { use tokio::runtime::{Handle, Runtime}; // See if the current thread is managed by a tokio // runtime. if Handle::try_current().is_err() { // Doesn't seem to be the case, so it is safe // to create a new runtime and block. let rt = Runtime::new()?; Ok(rt.block_on(f)) } else { // It is! We must not create a second runtime // on this thread, but instead we will // delegate this to a new thread. let r: Result = std::thread::scope(|s| { s.spawn(move || -> Result { let rt = Runtime::new()?; Ok(rt.block_on(f)) }).join() }).map_err(map_panic)?; r } } sequoia-keystore-backend-0.7.0/tests/data/keys/bob-no-password.asc000064400000000000000000000116761046102023000232730ustar 00000000000000-----BEGIN PGP PRIVATE KEY BLOCK----- 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 fzQN8q5RgBSxhpDadEHdfxVZ+Hmteng= =Jx0X -----END PGP PRIVATE KEY BLOCK----- sequoia-keystore-backend-0.7.0/tests/data/keys/bob-password-bob.asc000064400000000000000000000120741046102023000234120ustar 00000000000000-----BEGIN PGP PRIVATE KEY BLOCK----- lQWGBGKnCkQBDADs8Lgrt3MQR5DwVztKhPVOiofTibgMTEl3s3+obkmpH4EaQJ+a NH9D3aVGOtMuC322hqEqoB36LMRFytQWX/NSqMTmCFtLsDMaBgwUChQwcX9cYW+Q kazSHdcx84M8aCkJRbhBfMkFExWtwVIuQALg8C2/Bf35UcnMvQleIGYpLqHqTtZF cBl5EdAMZaM1I2H8HssfDtYrMNUkJRhUxzYgTeAjdLTDubS6wTQocO2l4XzoD5qd PAedu5ti2bIH5mqbRLUl9X26BlPvQTwjWgLlpuMcv4MYLcThAmMOYR4dJJ1L/rCc 2pfUV40Bfhci3aoBxh23q/0j8EHLnZff1WPyWclrFpRjkmCAhM6gsEUUDk49Gj/V uJ9tzjoIFOW0/aCKDwJadRte2R1CxFzWPGCPBAI/NR9RPLh/Pt4O0wCkHaUCnkxf UvZWw8ORBGODenjPxRokKhX9ekWhOrvhlq9fUq7/2OK62DNMhOtFE8btLKoYpyfe WrLV7v1kyjCpVQEAEQEAAf4HAwIPyeMbgY3TRv9O6e9cBDAqLl/jgNzGbSEKUW9t 2OlMPagVejv0lnxKAtL9xVqXse0OwlNFzUS15YNKjj0JF2bXbeZOt3hJHBKdS9tJ 8nUjMsGfNMD8I4DjfYZuU3QikQdkSYKQUPmeB63zHyuQybLLNHLtbbNGPNeku1Zj 17Iez4XNNBki7Lzr3mZeuW8JfrZq+xA2wVlWGTNkFhZ2bo/1jECTUZuGxc+T5XKk ycpYxA8QuvTcBwKz6tzXfQohKtdeAAhLN/CDBgy+kBOZxTt0drtvQqhnLP+1Tmjs QCgqIvgxZlVzjWQIH0Hqw3lD6it4Wy3rSnFnz7W18kVc1mYRRuZQtVrXZfdKuNCw ur/JVtevQCWitfmXjFqpSGmEuJ+kSy7Ytw5WBEaEFC9HSe6t4psxDtg76Jvq1KBj iN990pNxKwQkreJZv8Lp1T1gfr/sRAMY0ZXWGPq9aTPZ1xOOFH/o273x6fV7MmAj kckdJRbFZi7ltMrM0WjIfgZTU6rRywGYQP1MjVQX+d0KXMON7A8RXI6ro/U6Wg8L DYdA9bJkxIwzcgSO4TC+ucmTNwlddmKguAMw+//vopXIm0uLxL+MWdqixbA1Qycg 1TUxvGNkrHQ3sb2FGCm+F3nVyeS55WXaantFLVa1HfP/UdYOhNaQUnfCiV2LsHoZ BSyqdO/PjELbtWif49f3guKrtiUdk1Gs+5NUlUXcROJ3Zt/38j2miioJdA8a8xrw P0mji2MbwrKIJPjfh0yx3CtUCU53t27szHf3vnwVjGs6cXaK+GcZWowzq8S1iwSg fYH5vPMuvDx5cpeaqLa+unKbm91OXNQ76y/up/QP1/kZYMh4Jw8HOx9OswSi53Hg sV/ThtwfswaLC753nvvNmmZeFNIsbvfK4llcqInrhBnnPfXKFbIBIBeZuwCexdoP DTCRwfMKsCM7411MDs47X0EmdDV09jmxcJ25VzcDnMJTKL7vnuTyQT8bG9t861tQ unMk8WazckAbC4UF06h0TRK8aRQUVwDwOq7w1d+uQv8H6QVev/xaEs9nQfBYZ4yq Ueuv/LX9qnSA/EhFBIgeI9whSOaeb4mggwD1zc14vLMdA+xCTtwe6zsRhvc4akGj ueYp7YLnEdBGCMJJUA+Z/stqqxCmM1/OzWpu3WNsw4C51dvlwR97iq+sbZa3Ts5f jn+Ca5UG8VHKnXmwhyINUBwWyVEsRQpHs3vKzF98jgPuEoMiRjY9wqS6x74ARoHQ z0G3dllIOO50XvBz3q9RdNsZGbd8NuXO6S7CyZ44ah9K4uvM3G6CeqU59/VFROra 1qrroQTs+hTol6G+5t7gYIA7LqkOSHwZZbQVQm9iIDxib2JAZXhhbXBsZS5vcmc+ iQHOBBMBCgA4FiEElBDpbmhkOCF5RggmnLUAYRaDPucFAmKnCkQCGwMFCwkIBwIG FQoJCAsCBBYCAwECHgECF4AACgkQnLUAYRaDPuftAAv/fSoVzUl0AOtkv8o+r6e9 L9N2MHdx/utPzCU/EJxzArAPDjG1yz5K1yV6/gWibrjDvtBBBvJW+nj1oKSiRjPh pLnK2UsrrsDuMR/0BQQywbbCPwAhBRA9i4PUQuWkhijf5oOaXkyy+N3PlwEgqxzt xHB5KzKgd4Sf58ud7m0fsOy6V7Vc2VlSraoCSWe+aY6ZNBMb2p6LSC3FgLLCAyVG xshjJmQsn9XzopvHeQ8vxM26ERZ+3u5ejyl0dou9bohsfqlMzX9mGr5IxRgyU9VS SZQH4nSon14/tdckHUL7WYGF+/Wcfy7FfHedWhvB3G83lV0GqD0szetY0SuTl/ru q8qZG6KZfWyeN0Aw5K890pIUnVlytFJj2YCefalU1w9LJn7XmWSNWeYazAtUhrRL pLfpRx8+Zn1c2UBbix6fLlo9pyLlr2f3CbVy4AkZjZgzUi4eg9XgW4/T4MoHTwGD UhFY0X0xVsEvMEg8dIsd0apylLs+3kmLMBdEzUx9DE6dnQWGBGKnCkQBDADG07SC b8mnzrjmie8m7RpQuHfJRwYHg0QaALlcoKHrzebIBYSBc0ZqyV9wjqUMH1JRMlUn 94mludk59Ouyqg196112pZ9Kpla35CWD0LVC6kxbWZd58h9WMWILE4r7MFV2/xrk kd63k3KmpTwqBxGkwULajXyh3Yq0hj8Shrb+SewVB/WoUKhr1hchrEvzo94Slk5p QGHl1CExKwJr3ZBadJ17+Xzc1eaVbUI0Ne/hb94rePOx2B3v1xVc5/lBOKPaOUQT XNS2hLQE/VWtjU9oxSZ9cFLpAPn4fYujiCSL6jlkVJQWm209P1b1F3b++oRay5lv +sJ3VtqDHitHi8YaWHPb139/T13zNla/HERpZt8ANShsfFticrpiSm/+9OfaJAr0 NMalP9r8AxtMmW/6E78sKsle4qH47nkgXL2nlqGGOUxZaX3AFmzffipxHsF1HZ31 L4TsusufZs/P4YJzJxReYeqIjbnvJS5WAr4pg5eXMJeCtEslmLiNArJ4dVkAEQEA Af4HAwK0P4Kp2eiIz/9yelWjzZ2z84LhqF+rh4sPTzGTMbVwMHi/9Uu9dIWnGRV4 9BvYN6k3rIjl3/eB/+KsT1gUXjHIuwzCVjtOk+zKZjTGBvfM02klIRxZGY7VDCVU Xw3ipqEihKs5QsH775S3OgGIVRZGt9aMzwnWwuZuDZttMBVZL6+6yeYLvKjwqCVw G/XpYxAlUqAOzn8PzD/QEf2zcV6c4xXpgVmbArWZftcrj/ZgtpYkWAaMh7mc5dI4 NNMqG/29Z91w3TXsu1LVCx0FlBza+55DDLTKYmy+L7N0sjP73ZSB9D5s1kJn+reB RxVVVm1u96iqfksQiXpJVsKcs4V9T+nbEzZ89nkYyHjiU+cx6Icm9NqM7B+DRlYj l23HzyRkE4Pn6ECNfWiPIjHs4/MIH6qmUBV3F9R2xMpaTcJQRo4BMSi0bmHdavY9 Ei8AjkcV9Ip1bdpbrYL5xRr80eSDw69uZfh5A8GRWi6L9+EcY6WZfNPC0YLMnFJB NBKWV4TvVn5e/0aX/B5EjOl4VlIhLt/Ke+i1M3nECPp+FzEL0vDRsIjKa/FUt1Bm 5Y0T3dfBy9WkHbsStBm5hl5Ia7Ke3OAxcUNcTFSEk2tvPuOm7iLw7tei3hcb97As hQsYbR4HFZHoC8K3qiRHzvlRLM4StB7UUaVwp/AcJCJ4RxFHPnu9jzV8e/59LK0G nLuvXle/aJ3sk8z+0LlNIlpxRA6sG6Th7QBUug8cXDtZ3I7pXPU9Sd+3ZPGNojXW q7YRWHHtSkuxbaEjLaambA3qbq4ahQwRk5tsqjHB0368qqb/Htk3HlzpPczcVK+U rEFg3K87h76dACeWleYqT6gw+9y4mJMu6WN6AlE89EuBVDrgehwT/S5jk2oS7eRi kR93SBnofAEfMcgONcwCqH99fykgd5QYk7RwNkmQNxEtHYfxvncgmnu+4IWpDhOe RDfUcHOlfKQ8AU8RRQTBQta66wmDpKRaMi3IKJIiIYWjpNTB/CSk+4OiLtmiq5wX WcbrmPpOvkH4Kp50MX8zke+KYVgz0a9dZtVtaDh60W9p628X6aDby9yNsD+ONIGg OtpVUz/WPmZJ9x7HH0yjxndNoV4sPbEBqATGoM5hmKluQ4m9kGfWLe1SrVOWe4Nh /xJ46lUYZidP6UEzWnvQj0MQdp+DZb0fgQEJrAE858EaKoUmmYt7t7cm/MF8tnz4 lWSk4W5YuziQpTmXq9zv0GocEcZN5PaMqsWw8+4h2WgyaOO3phkssmKeoH+9hzcD 1OkTZgBCHvxBx7M3B+gGN/tfx8g76HohZ2ULGCDGxt0hu5MieTzSH0oDAOp9GYUW cXd508rVTL6Gw4kBtgQYAQoAIBYhBJQQ6W5oZDgheUYIJpy1AGEWgz7nBQJipwpE AhsMAAoJEJy1AGEWgz7nNiUL/i+xWjLk1LMIhEtXk/u+rBaNiubOyWX7R0LDg04B dJ+c6ESP1GUeiVUUadeYzg9kvEbm01I6aEqgo0KAwC4viXIjcdT9LWnIap9tptMw +CzzI0c8xywnCkTPNhoW3qydzUc4i8bsJFAg7Ua7O/40en87UJdK2SmxjZJBSJXY f215W2y9b6QFMQjThHMQcBZyl95dO0jw12oYTsTD6pfN5VGgxC+oAU0wCUpSSCUi vpSILffgxE3NsXhtY6lo6K+4lRJGU1LNl1gJ/SyxE8fnT3c6xCQDCHP7LlR0cGTz XVYqAnAjFy0Qde88EQD/C8P2Lu/hXoaT7Hg8+GlYuj6el6X3D22HdzvKFRLMRZlI mjQE9uCx2P5Vn0OjRSEfX9nJVW69/En9zcGBNErQoLGL0LerHzd9AtSn7yMcSg+B Ndj2Ud6t9vfzeqSIaS6VwCcVgC3/e5IWI7G6gnKYQhO1a/WZbnzLebtsZhB/NA3y rlGAFLGGkNp0Qd1/FVn4ea16eA== =3tzU -----END PGP PRIVATE KEY BLOCK----- sequoia-keystore-backend-0.7.0/tests/data/keys/bob-password-smithy.asc000064400000000000000000000120741046102023000241650ustar 00000000000000-----BEGIN PGP PRIVATE KEY BLOCK----- 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 rlGAFLGGkNp0Qd1/FVn4ea16eA== =NCqb -----END PGP PRIVATE KEY BLOCK----- sequoia-keystore-backend-0.7.0/tests/data/keys/carol-subkeys-a.asc000064400000000000000000000205441046102023000232520ustar 00000000000000-----BEGIN PGP PRIVATE KEY BLOCK----- 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 oQh/nG3ZOMUHJ1Y= =JUXd -----END PGP PRIVATE KEY BLOCK----- sequoia-keystore-backend-0.7.0/tests/data/keys/carol-subkeys-b.asc000064400000000000000000000271471046102023000232610ustar 00000000000000-----BEGIN PGP PRIVATE KEY BLOCK----- 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 t0UDcVH+UCpfFJJ1TX/HtR8ommWG+AA= =h+c4 -----END PGP PRIVATE KEY BLOCK----- sequoia-keystore-backend-0.7.0/tests/data/keys/dave-not-all-keys-have-secrets.asc000064400000000000000000000302521046102023000260710ustar 00000000000000-----BEGIN PGP PUBLIC KEY BLOCK----- xsFNBGbN8e8BEAC14MP20XUGRoYVGvN2NE0iZ53i4gVCWuLm8G6cuNW9AxT7psUr DgUJxjRs9NAgAxluWPqXHMj6qO7qfouD22LuB7PNt7owlYBNhLXQyJr7ae7xOz2D hF2qUmeT4+/fnX3G1UtHRj99W4+Us2L8sJzOI7c+gUEBFPDtAPxj6ViuwuOoGOrv fMUUKsz41sapprsNBUIlCd/PYa8Yv8dDT5okQUE6GihXR1yO3tScQIdD7Vv4kC3h Mauey+HROfZ9a2UsiKMBkyL7uDq3N0Fen4o2PxYLmhuxnmD1GzLpgI3WP9aCuvIK clr4qfXDKbire07o5Ze4UEmibdOkJfyITIWorY8GJLhFRUGoj8AJ0b16VkJJBQXD 9tPgg9qpojVXZQCkv8qUjIEg8I9pchUoDO8OKTxFfu1Fmz/Oe1aLUAJ286ZHh4XS C5Iu+TeiGg5LJqBh7ExvsjWkX0a7KW6PXwZTqZ2XgVZCCvF0A56NZnFhqg7hkSZb lvRE06GSzVBgk0ZOGy69oOT/3g6ZXslbYNqClJsskHENJelHMQZ/kxQY8GXPDWbR yBwO3idEAYLCpQodQyUux7sQMjpy4hYmF5lFTDYXxH/Yt08h2MyLybarlUJHUuNs pM/hto5HjzeuYc/JvaXlc3WksPqyoQvAYnQJ6XJLQU+bd2y4NqOV0Ue2wQARAQAB wsHPBB8BCgCDBYJmzfHvBYkFpI+9AwsJBwkQ7g4AhS/sMrxHFAAAAAAAHgAgc2Fs dEBub3RhdGlvbnMuc2VxdW9pYS1wZ3Aub3Jn5nRJQz/p5Sy3Twy/d9GzljS8qUtM MlFerNmGUEdVR30DFQoIApsBAh4BFiEEpIxaziBOIg+gK7NH7g4AhS/sMrwAAMV6 D/wPPeIyx/SnMR5CArtBHHud3e7sEwlQAb9Oa3yq7PoCDmLVel8eQAx3gHSDE4VR OLVy9DoVt0lnhtr9+41XMjEawiZqltGTajwCdb9sH7jIQLC8JdMwKkOEynZtENGN 6CYEJe2ZBIufnHtJW4RGooJQsFudXY+sprmAkxLASvYE4CNNyO6CTutH5WbcR7Nu H7GJEaEKsShyOl0kgOMyr3oz4lycbJPaOVa5SbuvPsxU5GHWS3RX6GwoU1iN6Ykq DPr6QiZE6bw39bbghr2K0ZAI+WCfQ03UYgPOGiP7r7Tr9n4W1teFEAYB7RlxoXVp fy3rX2i9951ag9w15jpMryX+H7CXKvZBREhgrLUUl7Zkcx2IL2sdHcJ3Cqo0BmRG Qrqgz/LshMgAWVXirrFeVzXNy9jHFqIOn3S4xli6k5QBpKnm6HOBMhBfllEs4Bq1 2/5yYBM/CnWJcCvWbWqZ4IiOv26lm5PuaolZJTIicrrNvmxiBinZnyPn11vadsy7 0QSmtoH9pZkEpgy02DdFG26vElNFnqqdksMHeWt3P1Nwx+/c4YKFOxFiH+kPKvfr giQlLivO8eblBJxWbwBJv94Fll4LurMD0uONFrnznHlws3oGYKqh+NLe4rDnR9ay feERH1AXJCxnQCg2jrFfFhXm+J94T2hHMq/muFVRefP0yc0XRGF2ZSA8ZGF2ZUBl eGFtcGxlLm9yZz7CwdIEEwEKAIYFgmbN8e8FiQWkj70DCwkHCRDuDgCFL+wyvEcU AAAAAAAeACBzYWx0QG5vdGF0aW9ucy5zZXF1b2lhLXBncC5vcmfZfd/Nc8HEl2N0 u7DKgS8yKoMGjdPXbgSiXOUbQgkFmwMVCggCmQECmwECHgEWIQSkjFrOIE4iD6Ar s0fuDgCFL+wyvAAAuPwP/jhSsu02vUWmZwYM5eyRnzoAGTnnj02OaJiH/hwIlF9S duAku3glZrF1pvfXPVIo8+1i49sNtrENZtbFcwzs2pxX0wuprWzhaL2UXgN+tkPw A6+v5PwrcBxqsyRME8R7BLdG+xAaxuNnhbq4Y9kSB5t/IW1P5X/KpSVarE7v+Xxx kwCbKLlqZXJc5WRlz3Vj9cWNin7zSoAFdLJ/5YcY1ijikjTpTgBPSMwKfYK0UHgs NTkpbkWX+7k4T0+drT2AA4WR4pB2TQD7/wxug2i/lcQJoRAsF0LGU0eOLlnsqs2p JqBtAiV1iBm/gPmVAF9CUtfzDs0ZDzvbkqrpwP/Fn7b4T7G7Y6T/x5u9YE3N9iv8 SQx0KR6lqcHNS6Ffm5LV4JDCRkZI0eug3eJUeWe9tAFXzuAUBBmVXqVmYJukQMgo CcaUxKJL9e3BRKzAOtZA8VONl36Uj5Egd87BcLo1Rmck7qEuufhpbpP+2Gp/QIGB 3ZILVgE5S+/c5OxRkgDGpA5kMKVljy8PcUX6frWG9mDaIETwdAFi1KsRtpxGh8jA +Ez6uxHEIl6M3EH3X6UzpDItxGAwOrTsXxaObxMYdEgDm7Ty7xxsLRkCxVxVjywF 2a6lOWxAYCqYiO+NquA8oa40d64nVo9RYO87/zLugF+NO81y6BmJHuqBa1uh+KOG zsFNBGbN8e8BEACTJO95aD2iS2OQTrkatkC3Scvy9QY7XLSPyZBcSoeNiNrRVKXq kYNLxJjxKqJqqfunOLuXZiSg9GnPQgGN7mczjoMPzSOmKSI9YeK7qNaeDsEm0TIC rZvCuO7lXDd5Z+SStV9/BvQsZbfGFG+K/oqhouCgpk3pS52EwrpeINBcnqB0kICN Phywyx0dyiXfDZmy6a/988EuT5PdbsgKFn5Qf12iiVeN6EUdE9gq0FNwdIcF9IwH H0bVJa75zwAXqnMy+TW5jTrLFsiHyvFKVnP4os96ScDv6tknTXhpr+VZxSRHhY4f cX0Tu+pXEbNKWZh9bvM5gjy1NMzjH1aOKcBggOJxpJU22Ya12GJH0E9Wy2xQwLOr wRP6CI8XgcjJ8TbrlxdxVuilC2sUkUQrfFA5601B4JlsHvUWvF0mLafmUUlVMi1y Ni/ceigMgrNTst0Psr5fZ4uKcS/S42+u38jqFv4anT0Z5S6SPwlS5O9d6ATx2uHP 5CkmjIvO0cZA0jLpR+fBbETa6LKVY35XurltnsHZMblYpq/3FX5+8YTsldNg7E5X azcl6HwVYfK6sRGT/Sn7UbXSm2vjHcxFnNeJdBY8OLBRSymrpy5s06dq9kP1oxNu fhSrB7OJh2rUxXZQEv8eDSQ2Mybk+27ASKmhJhCaOeAdDow1SEjP9PcEfQARAQAB wsRCBBgBCgL2BYJmzfHvBYkFpI+9CRDuDgCFL+wyvEcUAAAAAAAeACBzYWx0QG5v dGF0aW9ucy5zZXF1b2lhLXBncC5vcmczRGZigcqUf22rR7tRIbHptYk8F/uIWlkj TM3W66dm/QKbAsG8oAQZAQoAbwWCZs3x7wkQMPVp2H0ZoXZHFAAAAAAAHgAgc2Fs dEBub3RhdGlvbnMuc2VxdW9pYS1wZ3Aub3JnTvphwkfjygidL8yQNuoS31QLWWBO xzL+A7Ks+aK7lT8WIQRQso/x479d25ek4U8w9WnYfRmhdgAAV2cP/jae1K3v/W+G 9ymuk4B8MaqJ+U5AaSltu6Ns5SCeAek6B6u40FFQn+VKJp1YmNU1EMIkkdvGWbHg d7KdhMLfwy7/R2uMqLkOgdfYKzMFToQUI5GDMKThH4hJS0lFIVcezD2acovjB+yy lT0yIz9x4l4LFB5Z9XVeRV4G5aOhfWxZFy+Ly5OTbUr8la43/qg3jm6T+gasCMWc GKO6KCJ0G3fbR82rmRwwdlKv10EB8st2Ou+pfCgsy8tm/mU8DjhNHDLyaytekGJv Z0Aqz3FZM/wgFzMM9JEnpUcyfGM1iKwSP+3L+qeE36mp4N1W9inI6Rq+jTVIOyjy 60fP1By0rY62yEHStGvaDS42AY/xQ3SFMvf1r0yanUDtdQn1WPAsky/i2IPt0PVe 4W6ap7Yho/fDQK04bmSvZvJC2DjbjQCWMnsdmL2QcBYhW9P0u63XsPOv0vmVHa6D nn1ogwGASqmTuKhhvUXTqQsvASjQJ6wtx06vqvKEOuqTPHFOcC+11pIpnQYkCgXa Wv9TVdDOy0WS8otyC66Yx+5DOs8NHn4hJtWHbswy7I4wfR9I76K8jJnGOyorpDKR xreJ9x/64xmlEug7aY6f4t3YUUwBwnAO0GHzCQH3/XuuQl2VZIHVLLQmAuegOeCY FFbKQwkNGmaZuM8qOoDAIAmx6ZFE0+HCFiEEpIxaziBOIg+gK7NH7g4AhS/sMrwA ADTQD/4/U8Bgyf0AKe4tdLM6GJ0TfMofW9jXx/TZhmcJag+C56txGhUy+d62obKD azsKFxgkJJVPGxhR8hRtEwFX6K2cYxQZY5nKMKe95azMZY7CjCdChf6tVFJeBiwo cEAak1Ouin06dToRiXgGp6bG5ixCGpARny6MeLtvK1zEk6KtSgP7sfSTMQSg8jH8 FKbi495+Cax6eRT1PwIVwtms8VQv/zqhYoDEhMffh9O3kGQ0QzkpisafTJNpbElO kpExYCtSJ4rujfi3CXD4EKaPu3efWO+JW0Ooo/pkCvP/JGOvElF4SnMi9JP4mkm3 8AFk01bQ1XvdhkWUx962YLgXAdwI4yIuOL6Z7TdUqqgiTeCF8rzscUN4lAnT0O1o ey7Ld/rx9xVZtT9ejCG+76POk4NpWOTMnmQVBQarAYHgUBZcWe1BzMX6W1HoGG58 jd2W0Xa3nF10qZLVL+fjD6qNUafuZLCrWv1CoKUdgxfmFZC02ikfIXewRRKS59mC uapO05sLsfjpld0YMzVTEjMUI7m4yuH3w/qUfwIJKPcoBSaj3wKYuRKAbRtsoXLk IxG2jqsK37iQtg9UZlGnf+1LIPuuMH3VIgGEdX3htHAymu/d90uIlR8rNl4Sgsg7 8aoQdIZR14CbOxaC95DkYrBMh/suRRqAmkKVvVC/OszPjimezc7BTQRmzfHvARAA rGCzK5ERYDyla3KmEfUiEi4iiF4IOG5M/Jwcn1dFKrSVFcdAkScyhqABTLaKXiVI Wwbqw7ArojtrDFf0qjdsYEBy9MIdYxOaICk8gkxjxO4RIJmsQ6159DHAqcNz7RVW eHuO34Y8EsgCnSHcEtYSvVhdihhT7s7B6ID5IcPHxtWrn9UzpIKUrVMnzvsb4ou2 iLcpT68P1TbltaLoWvfjkjxbJ4erX/SD00GuZE9L4UvtXCzcJQ8Rh0SGCich/ea+ MomQHNvm1NUpi9x4nFwfjyGn6uKXuyoGmJTtkcpGIY9tim3o2SpjvKzOGg0Iprld fx5GXHp832Y/jlqO/gIMyV80wkE6ehlUSJZnDMALLUxy6J3e8I96mI4kGvKN4S28 9gDuXtYccly5jINBtAGg8TDczqvQuFgkfp6SK0B3cU6E+lt+5o1O4KawF0UH1AK0 MCIou09VTSI/09cj3LpQ2OtltkeQhcdk1KKkp84br4d9U7fGm51UMffDr+pmaNar LZT0M3jAYFjZcP6zQ7cmacI7bxT3VywN653SMFlsYpTX1xSocswe19fs3RhANBJR Ngb1/HVjWZugTWsiTYJMaPLduBfDX5Fni+ChI1o48Mnaqcip/y7jhhOwG1KyzKgl wKlo7SKTFJbaPrPh9XKBgJbdx6AF8IHbQFwyqJWpyC8AEQEAAcLEQgQYAQoC9gWC Zs3x7wWJBaSPvQkQ7g4AhS/sMrxHFAAAAAAAHgAgc2FsdEBub3RhdGlvbnMuc2Vx dW9pYS1wZ3Aub3JniOkNpbkbPo+r0/7V+TIqe/mb/Wgc+JG8iW4W8oLORtcCmyDB vKAEGQEKAG8FgmbN8e8JENNhrn62Qq+SRxQAAAAAAB4AIHNhbHRAbm90YXRpb25z LnNlcXVvaWEtcGdwLm9yZxY2gCI+YBXlVUzt8K2n8W76JB5ObKjsIWqFHiB6pvpJ FiEEcoARllN8kz8K+vxg02GufrZCr5IAAOCxD/0cttAnns4MV99NrAtqWODFvGPh BHH5sybkKPp2RbpjcCK7AJ98oBsZb0g9A/KrYXALeU+RNKyKK7vFR0D5lMSjhbCg /bNqdGOrRchaxpcwEMDsB5v9IaBfLpkBoOR5FLKQNQbvtt+x2MnSc6fp+9O2/j4e 4nRYFsKGegrbEucoLLJW8F7X7Cxi/nLOU4MuXYOm5i5Llj1To7KsO9xLXi2b8WvF HxVj9oYUbH/8DAdICMqGWG3jzn16PchE7zwyTARufKLkdaigPAoOFtgHc26uFBGY PIOODsFBrgN/DBp5rT8jfCQtxcOZnRMH4DCRt3sHqiIi7fo9y7eNgMpHEj8gmcC9 xfEzLQYNp6hi8u9oSHTpQxx0zi+yPs8zzesur7LwT5KIT8h1QyUizt+2Kdh1/8GA yjaCXp1TCvwKi5BU6RfUYLO4hkCLhN7Stmq/yB/M5ygX0UH1BZuQFmjnzkR+PoqL zr871tYWgpHvr5mMq7WlRiaI8r/1gzumorUMGZOR7PesmNGiSquBqu5CLYdvyszY 2n/Q1oKgJM87NkYguoSLaa31tBHmEPuS2bQILoK+FZ4AsQfzwAO8zCs80HOrzQ4P 60Hw0KHY0+PEdrk+bbK4bAIRg5RQ6nONRd7+M/Von5AGWDbVSQ+DQqpf0UFP2fNi 3uAAkTa7unk4rucnohYhBKSMWs4gTiIPoCuzR+4OAIUv7DK8AABG3A//S3519g+t Gn9O1+dKwBj1qB0jaWvGvd9Wik6M9oMj55unSfZfvU/F+dekAlqOxZpFPwMqma7G 6iWMeiCR6G3V27DkE3oFmBTM+tKgOT+yKxqhPyTMwxweXaQYubAkdDpSyduOTX5j EJmORhCQE8V2fUzwdYnxBiIOCM2Hc7Mh4ZwND701FtXQnQX3efl3vTFCZkai4W+f 1B5Ge4QFqdgbpSH124BzLK39SGb+e9dWHepMjdXdA/ESyaiieUpmzzrMREdlvK+o hXIMohGzEXzgFJrHwGQ8DSjPbbIcHq50UJr5IzcP2fwlNhB93We7iGYO1P8N2RiL cXfcuUToLi5MIC4EErxkEGchDm0ZMRWiCwf1Nz9i+eFcVvdI9tS/l/94t3RPmLUD dYPmeQ4PfBepBLUIrQ+FCDf76LGZIJ4W1of2zRODsbZ1RtZL+k2N1/VyjXC9LNg/ GXQzPXvRUGArebylzng6lDLo63oMB4Za2a5VU4suDhXOj5QLy7EW0SKUNqvOrITS 4yz6S5DL11NddXMWrt8v3Gs4OXHSxJUoprsCX6CcIRSpHjiO3FSeupzFUlkwZy7L 97BcThs1bsIHX05RmDsmEGfJrVUWc+Z0ZZqavXH67SOX+u86sGo4mbQ/zuij5l1R kh3MW6OdIYAKBnXYsFeCtbwc/QhFvb4QZQrOwU0EZs3x7wEQAN/OwEq5ko5YvGr/ HLerTbwBGUbQ7FhDfutya5ijr2DGIX46K8sbGu6kYcNN0umv/Ww+TaRiQFCWYdoS FbC4gNIyawJzuuIKsY9RogoeYp1ehRnZdORl0FMJJ5y21as57Oweibfn3i3sadHp 9mBtuwLCN3Rz8ChoeYDvk1LIAibg2F3txIRV+3G7Zs8U2ppiNtV9E0F62spbeu9A BQrtBkVYx82Lv8dmw1Jc/Z7Qho2S/Xn7/R161IB1EXT71Recd/p7QTwfra5vbvAp A1GOibAk70NbLcD9yKOk/vN0RsFxPrj5hzyh96JbC44KE9FLabMewq87dlB706af uIJnqz5LaMj3RtX7ThBUHoNGC9MWcKQ9l/z6meE7GNuDjEUQIemT3udcJDs0lSZK kmHzHUjIeJwmKdTO6clg8AC+8iw/rALTNZD9ty/tthDw+S6G2pYL2A8cSw3YwmMx IroroUuhPDxwATEM66U4C7WbJJh8QpA7aCDIbmcJbCNSxulTnlkGaYdLpRyhvxqR 3TQU5mx/L6WGkOotI2cUkU0IYKnDmNYKwIQcjmIzbT3BIZtXhs4UwEtSByx4VTnI vDnYm6H/Fc1sApfqmeQxzo2VKOxbN49i/DGFk4+RiHiCKFbCblCTCKZa6oGikjae eSLUMxqhjtthBoq5MakJCsbpVmNRABEBAAHCwcQEGAEKAHgFgmbN8e8FiQWkj70J EO4OAIUv7DK8RxQAAAAAAB4AIHNhbHRAbm90YXRpb25zLnNlcXVvaWEtcGdwLm9y Z41qTSEs46GVoPjHxUD8o1mxZJ+UNVRU0MR55tkPYB7vApsMFiEEpIxaziBOIg+g K7NH7g4AhS/sMrwAANnJEACkc31FOTn+qpaUJM7gHD75b6a/lJn+nrRASuADXPVp S/yQhrt4CfC0LnpuUBtLeo+aaNZaiu/MIFmTY7fIKUbmCNm6293yE4mYjOa6H225 l+f8EDepzaPK9aDkeGY4WNSJwQVSs1YrS9QnEQVOvX6DTNjzrehtOUjaw7mxhjfF tv+cn8my7NydlxiN++WvR0zA+j/9k0BNp74DRdAY1yO43+Df62B1kNvn2Bx3aWbV qOwiHfJAhonZd6LpFbqnNgEito7wi6f+tQOlzyEei0RAVqaa/Pxpxx7F5Zr3r1Da H/hPjvFLFrbB6VIERID60B+0gemHaLjVuJyC/quHnK/LqdCJjwYLQSWBV5re/kob Z3hR+dRfc+rCvcJrul1BAoaW5hVXTpG68Sp0HCeszCs5KB+/hZnKMPhjKgekT6Yu yRGUW7SHJI/ZszKHWFw2h0B6huAOy8Lncy0PrgK2pax3Rpl2SZz1cG+ns1PFhDhi VnOeujQlqD4fgv5CEIsdEjtHQOdzBX5DmhoBlBuZfG7+LYAc4IjMGv6uB6lXpGnl AQsgg2+BZjEFWdaZIbqV1PKA7hSmWckceBaG3kUcSF+funCOLQAGIej9Nh697ePi dF4mhQwUYSKFAkn5sFuV0wy7LqOd+M7jnRvfbWAnZnv6HD55zq4KC6i6ZReEzEFH t8fGWARmzfHvARAA387ASrmSjli8av8ct6tNvAEZRtDsWEN+63JrmKOvYMYhfjor yxsa7qRhw03S6a/9bD5NpGJAUJZh2hIVsLiA0jJrAnO64gqxj1GiCh5inV6FGdl0 5GXQUwknnLbVqzns7B6Jt+feLexp0en2YG27AsI3dHPwKGh5gO+TUsgCJuDYXe3E hFX7cbtmzxTammI21X0TQXraylt670AFCu0GRVjHzYu/x2bDUlz9ntCGjZL9efv9 HXrUgHURdPvVF5x3+ntBPB+trm9u8CkDUY6JsCTvQ1stwP3Io6T+83RGwXE+uPmH PKH3olsLjgoT0Utpsx7Crzt2UHvTpp+4gmerPktoyPdG1ftOEFQeg0YL0xZwpD2X /PqZ4TsY24OMRRAh6ZPe51wkOzSVJkqSYfMdSMh4nCYp1M7pyWDwAL7yLD+sAtM1 kP23L+22EPD5LobalgvYDxxLDdjCYzEiuiuhS6E8PHABMQzrpTgLtZskmHxCkDto IMhuZwlsI1LG6VOeWQZph0ulHKG/GpHdNBTmbH8vpYaQ6i0jZxSRTQhgqcOY1grA hByOYjNtPcEhm1eGzhTAS1IHLHhVOci8Odibof8VzWwCl+qZ5DHOjZUo7Fs3j2L8 MYWTj5GIeIIoVsJuUJMIplrqgaKSNp55ItQzGqGO22EGirkxqQkKxulWY1EAEQEA AQAP/iDFmRG4F7ZBVyHBxnY8ns7bSFS+zgTkqUaXxBqfSVR93rSplvUQPILaTjh3 gl1WuGCrxNm/y1QhmSWCBWwRsEdXO6UpxiFIWJS4auZZaa5Kg2n0FjJFmFo4WnUP rrz6Z+9xT1A/IyENX7dtr3aSStKOFum1+mIoXjZbnnJ+OBZyUSx73w1Tu9R9EQJc tt/pZscfH/00HKqJ97fl43ckmwj3hZZbEtODgDFkzXx+Y12CuxwsInW5ITnIKqy7 HYpuDoF+n+BKcTe8OH3xO3urSA0jc2elB8+dOc6AoBaNHblAuGMEouFlhCnhdBEx 95HrnYgthmt7ZQlHAIiDFdT+kivwZcjCFU3gEkmQ7CuBnrse5PI77Dhyf7dDDYv9 5WMwWU/RADoR/1GpyKSr0K0OqmjFH3+z+6u8k4CLIZBffErTjmpax+77wjBxsD0L 7CU5jPrDT5ruc6NQP/+SQTXotl/flLAwksXOx6fs56kRMGbSbSDW9MrdwJiIgsUK JgkGliJvmuWbqQcTPo2nNuRfo5XIfIKcjPbGUhDsuW/xcRn46nX90MDKXfVrzVx4 wbMXRfjJ9a8KbX1HMWtaHMN6zmPu2uXHqDeNQ012fh/MPEt3xVq1jhCG9aA8kBsm 64J8MMmjYkL/Joft/GY4Y5+kdcbxDH6lYJ6I9Te7sOQRSsi5CADpDlSeUTQNyWG8 nFMtxDP29NT0cITbnJuBQ9+BuIw/j7KlHi+HQ8K6qwFv6fDtzh3n4SjS4k3RVvnv SXlUl2lHxmD1Z99Om64j7h12RxNDKxsywO9Ir9eAbbzjnG/uqx0OvI5bLS9zPTov HqTrGsC9OYnz3JMShTXn+DRVI6DvT4xI2dciJKzuwn93LdwSzaiax1JjAfObPJNk wEs0mj+qQXP3Z4KVgm82gjWIO5+P/w7R/diGQw56uv9lQeahR2H7HtILCcWeJkjw pln1SlwY6j6Z5bOLhhU8vcXd2QjtsOhYiuLzHLV52nGZMFRhbhiJtYGiTfD3eoex fGCOUuEtCAD111X63sWfx2jJllEt3jQROSstFBegbqPcFu1gbLxGv1+Q1mCe1VsJ PRvWr/DiiZcrVOkunbZ+nTlpkI+TvRGxxYr/3/lD1kooaSMNZb3MZYLerruukHRi TJ/ydQoR86U3ei1tb05YzihUNFvMjmyUEwH7eU/Ht+m6fLxEjhVvyahEd9+vQOZ0 iKxKP2uuYyeG0aP65tAszWk9f5mDLzpw71/Tz7MiwAin04JzSdZaaKd0NHoFtNbk p55RSA0KwZ3sVYGSq4+iht/HPlyrfAdhc5Huge3X9MUxh6CssfgdStmV0hBbGu4e HlkiNK2iVfGSYBnmAiLstgE2dfvpbfk1CADirWGoVbSmFxg3g+NKfndzKd17xLqr S11wdk3naxUZbCz5U8a2ga4AYbcqNHrOFpcp+GktDO/3ada2Y+cG+blhfB368cC3 DuTVCAZJ+N9asF9R+K71ZogACEd7uRb0TtyRMim2vfOVgVVv0u+zFkUg2ayarRwG eP9RN/sGmhFMcHpRbLOAn7panXqsOJ5l3+lbSHrbYnfWz5lEfHcl70TuHBrsdRVm YTTQA8xOmDtwxl7kCIxgX+pcsD1AVsWjTOVCf1HAemUASiyrly5KeciMZx4rrZmH iHbzDO1KPlYGuvD5scrKzMFA6MZhvjn2PB0IjELO1GMYvUNykIJHpnTni+DCwcQE GAEKAHgFgmbN8e8FiQWkj70JEO4OAIUv7DK8RxQAAAAAAB4AIHNhbHRAbm90YXRp b25zLnNlcXVvaWEtcGdwLm9yZ41qTSEs46GVoPjHxUD8o1mxZJ+UNVRU0MR55tkP YB7vApsMFiEEpIxaziBOIg+gK7NH7g4AhS/sMrwAANnJEACkc31FOTn+qpaUJM7g HD75b6a/lJn+nrRASuADXPVpS/yQhrt4CfC0LnpuUBtLeo+aaNZaiu/MIFmTY7fI KUbmCNm6293yE4mYjOa6H225l+f8EDepzaPK9aDkeGY4WNSJwQVSs1YrS9QnEQVO vX6DTNjzrehtOUjaw7mxhjfFtv+cn8my7NydlxiN++WvR0zA+j/9k0BNp74DRdAY 1yO43+Df62B1kNvn2Bx3aWbVqOwiHfJAhonZd6LpFbqnNgEito7wi6f+tQOlzyEe i0RAVqaa/Pxpxx7F5Zr3r1DaH/hPjvFLFrbB6VIERID60B+0gemHaLjVuJyC/quH nK/LqdCJjwYLQSWBV5re/kobZ3hR+dRfc+rCvcJrul1BAoaW5hVXTpG68Sp0HCes zCs5KB+/hZnKMPhjKgekT6YuyRGUW7SHJI/ZszKHWFw2h0B6huAOy8Lncy0PrgK2 pax3Rpl2SZz1cG+ns1PFhDhiVnOeujQlqD4fgv5CEIsdEjtHQOdzBX5DmhoBlBuZ fG7+LYAc4IjMGv6uB6lXpGnlAQsgg2+BZjEFWdaZIbqV1PKA7hSmWckceBaG3kUc SF+funCOLQAGIej9Nh697ePidF4mhQwUYSKFAkn5sFuV0wy7LqOd+M7jnRvfbWAn Znv6HD55zq4KC6i6ZReEzEFHtw== =4eKN -----END PGP PUBLIC KEY BLOCK----- sequoia-keystore-backend-0.7.0/tests/data/keys/dave-password-dave.asc000064400000000000000000000177461046102023000237570ustar 00000000000000-----BEGIN PGP PRIVATE KEY BLOCK----- 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 A3F/N6XbRLrb/0AkNklOyD8= =FiqS -----END PGP PRIVATE KEY BLOCK----- sequoia-keystore-backend-0.7.0/tests/data/keys/no-password.asc000064400000000000000000000272711046102023000225310ustar 00000000000000-----BEGIN PGP PRIVATE KEY BLOCK----- Comment: EFE6 47F9 B93C 5108 26F7 068A BB19 A809 B6D9 3CE2 Comment: xcZYBGbN5YUBEAC7QUMsY2UQVFb/O5OJ3l4KO0eT719/Ag2o4yTB6RNNKfqa/Tn/ seHVMKn+dBf4qM/7Ghb8PcfgdtRR8D3Bm69Qjgkn0psejReT4ImufyV0lxbbYimc sX4SM+Qmb0XkAM7Jrg1qGi0Qk1MbS5NXmbtJKYOo8dVyPbb+Fztv5KiQoOs9QA5A RqdTDw/Vg56AZ2qCL7C54Ls/4pqZc12cWvv9r5F5cMeWPPky3rplWvIYX2YBdp0A XuT21RqhAz5R4gOxdF94g3qchIR48NhJfiCMKbz60YwN78h2yRytcpo58cZtirsV IOcHvqH4UczHEc4SOdesI3T7Vt2QXJwqCNdyquxZo/3Hfen9V18/5fnOCWgvq/Ut ZHiuJEsmBu2pTfOhUAstuBnxB5SwNjsATy+h2rKYEt1VVN62+gId5RBIOw6KRGLX n+OFgueoVzIM44UH3quP35LTC58YGdu1DWJdRL0nvVJ6ICEBGNq7l3pQIu8Yvagh PVDtW8L3TktcJkRgKLGDXcdhaCOUpcFhs2SOz+KKNNCX+W0EaVRmBn34RcYW3yLI 3Hdn0vDyyYSwdvPP747ax1Dl/Vd3qbQNAAQob3dt6O+mBttH0uQ3wqetEDsD/Yjq ec0ZlITQV7AC5sDXLWypB5eVgr+T8mer8lCUEeoFmRYBXaqaMi3mLN34UwARAQAB AA/8Cxsoz8YpZVmLO2IeMwwkSbkQWr7UzCSkCMNIF9QqF+aIfY7NVNQJD+rt+jCK h24Dv+HhQR6s7yw9FYsJLqV8NWvnMRx1pM87ecLUh6v03cBkU6izzR5d2tiHDJyG 6an+mcmf9A4PZC9Iu5K073onuIQk0e1d+oOcid943/8Q3Fse+KgG8FsAa5W2G7TN vtHjaEtJ0Qx6LqTTBIzqHW7sCTTTjP9aZxfAs/qv1XkaaMWnuCh/0VjPfbBP/wLB PHwKOgkr7Grn58aYUNAAFAPODGIhWkL5ao4xNpJhCAyHBy7G1RJoXC1yZmwxERhQ 6/GrZjtWBlioBIw3YeuMO5YAqStXLYXNm0Xo87Y1HRBvCnks7MBrYrD6uS3OHCJU AqLb0///2FJuw1smv9JJeJ/W5Jkcj4abrqx71kNaWWkpNosWgGjLf2yC8J9wqFP7 9Vx0cudEjxXoqkDdj4IsFm2j7zBu1SNMPj5hKrh2fVfkYOEKpGk39OncHWL4xjFr 28bbMxCP4tK2LNqgF0Zac2MWLi6+tFdom15Pwgx3e+OBs84SL5HDyW6g5d2fzu62 CeuXH2zVRXJQLH70rvGxQbZKaIP+W7OBVpkgJabc3d92ej21xm0UaFkO5SCWixAE YzRQKVhAnOumKjhpK8t7AZStopuKl52Hz4jxWi66hArzf5kIAMkTY7dg0SOuivk9 WFA7g2bfxEMEjS1+BH84tMkVyhvFp1wNbDrQWfZBL0ECAU9ZpdcWRcYWttCf4+AQ JGhgAiZT97IfEAm7+XAlyFEMHIkQxu+yUeV+sk8V/UjvVIxNQtXdDkBA3Eeicwwo S7reLG+4iRtxXTFsrRJtcSpcOgYauNkbs9Z+KegJnu+RwlT06Wfu8vW2/POw0eo9 JOJo47vjB7HverIKoGTMkWomWyepBV/i0tb6ATS/FEpXXi1XJyMby5jpA9ziIrpO PioRrbal5ngjsJsANEVNQDFepKRqr4+Kvwiw23IMzcLpu1QFwA/8vpf+g4fOBBx/ KsdU0p8IAO5nbRE5HNjNJ7y4PxPcADK9xXwHzSxqBb+5/uD4aMmP/HeXQXAs9GXR fy1h5r4B0Zl/si6IOw5jIWWk/8asvJwzdbRz1+tapWeROCtGUcy8FXvzW3Obl6VM jeRg+fotFnUQmeh2WPr6bpe2/n2XaZ3GLFM5D+4ODmyf74Efl/gOIQlyaw0/GlZZ dLo4unfSJ+F4wVLtbYSj3vhv0EGuQFnPMW1kGFSNzvhF7r2uxfSqSb2ppEDYlfCg bgRlN9e9ODMTZ7SogwwW3NiqvQxpXQ6h0UOcli0Xs3yuulRTIcDDxO4rVlGusCXy DXg3EeYQ6vsyKD1CoDsYxkoPwnqTUc0IAOwg6y6uMJA6j8oXG1lV0MhyyL3L3xX5 xKmfEU0Glab6/gLmvpFTgOVMGmuWHlgZ+RvpynF/PmVp+qcLfRMPR196SDIabAlT vElWWWlBTt4Z2HnvKmV2Y9mLMREjEWVAlR6YlHFCMEZ7oDKDfisacEtkddh64aeY c2iiosnp8fByOBWKKbpecOyour/F6YQ3i1MhwSL9DxfcvVm6RBh9XxAyczDIhRCv QcdRM6MrG8XJwXf+ZRBZaydXhBaXVg/gYRoGFJOZ92JuHwLm9ZlZlMBgKUwdg7IU WSlcJIdL+YplireRwAoewdA5o3/gwg3pBsAYpaacQBLOXkwNhGO9bB9tHMLByQQf AQoAfQWCZs3lhQMLCQcJELsZqAm22TziRxQAAAAAAB4AIHNhbHRAbm90YXRpb25z LnNlcXVvaWEtcGdwLm9yZ6OWN139H2VCAaano30JBXaBPr2VW80qYIvsyqyjBNvS AxUKCAKbAQIeARYhBO/mR/m5PFEIJvcGirsZqAm22TziAADAahAAn0Wvee6n/Nwd PFaZce0begmdIjEm7ORn4CMYbfI1ZlufHV5bIiuSgAwUOcmC52OvgLrh+/owaZzk bnshJXo7sH0OV3WqZ9IErlQHMSdz2iBC2QRRO4Hl+6MwKM3qEyMet+O43dl+u6rf Z3foXqrw/tJt9m75DYJj1r6oHj01h79DqHIsmqUxWz3X9K+ldsdcrvlJRB0z++K2 1Dd4AluerlRxLP4D6ogkMhO89/yNhgxfDCD/nA2E5LOzFN28o2DUQIIoq14bKjhr 5uAzjlRPvlM+EFMKw37zqnteddh7YW6hBQC7b7fDzFmkTXt4WvWfCpwCAtjiP+tj D1Pifw2iXrTPcVDfXQWpLVvTBblJMvckoxsCEfUzXCe7mBXMiyf1ogV5w8Rd1zpR lPirOdKJlPhBY69dFWYtvADFkUQKm3FhIi1fi1Ct0/AdEfugTtye+98dMD1mbzDU rXJzrnvhi1liOPzEVCnCf9+Nyb5ynh9UcOaJO1VawOXNBwiAy7ti50TBUv8vXuBR dzOjpXUX+JXDz57sNrDHTceG6mzX4x4XBdwI3zpxVLA3P+rOdKwBgeks4QpPB0sV 8K1wn4xpjQTdG2WR29O15hxXQQDXFGNzABXQqulHdP7yM//1qJXPSdJvTvadmU5p cKzVUwD3u2dokMAx+Pl4EB7dYSULnNnNFDxqdWxpZXRAZXhhbXBsZS5vcmc+wsHM BBMBCgCABYJmzeWFAwsJBwkQuxmoCbbZPOJHFAAAAAAAHgAgc2FsdEBub3RhdGlv bnMuc2VxdW9pYS1wZ3Aub3Jnrbb1T1WsGaiLeBxjSrZLsm1MjmN7M4TjlGk663/k AW0DFQoIApkBApsBAh4BFiEE7+ZH+bk8UQgm9waKuxmoCbbZPOIAAFinEACbG5Km 6OmG9NDf/eeW217iH6MUZ/IImRLSQ/qaAE6jcbflMibZ+e80DhNkrdMzLybQ3nfM GOmGP+4BnCXqIHrqTePpJiSKRQCDBLzn/yVXkJhLoj5+bPq5wPEd6troU9AlNxdS jWRk21ueC4PdTpcO40FpEB6kPmYczeehJfN8U/hxqXA7EGbJnY5CGrsok2OXVuYU jFcIDrAhC96fZQxnNGFWA9aLosP1dbQu45jYsdr4cSoFNVYzmgTt7W06bAlV7bvC ZLZ/vD+VoVZTz0/c4w60HMf33EigkTGwNqwKRTzmOCJMq2SYfRA37BZ5KWMgh4P8 abo696XYPlQXdq1S1v38gE2HNOIHPdpx4JEEvjLw2aRV3v8xvq7hr7OaYQQb+R/j S1ZSmjlhDJP74mh0H4wnqOnrPNvN6GWjJA6Xu1WEY/7XsQI9IbC4lT16Wfb/o48E XTqSYyv0LLw8/JMEU9xKvIuwyb5hfths42iPJOUE3ajjWgeIRukknpENxzXiElbL +kzjuNA9BuTRDmVSc8BeVauPA4YXjma2AcqldPTeyGmF+HL1XHL2+llcAq4whM8S iZszIihriDfSDlQeeSTOiOzo1JEmrAtt0C1S9xSesh6nSe/uMHEDU/fkMYU87v+D IQs+ObXRDMC1RhXvnLsemhVP5tkOAkJPLLzVp8fGWARmzeWFARAAvOCBrunlSOLR fR7wbRPfjAiP7w5sLqyLtggyobR81pbiAG4WIm9dhTikVwIHHLkTmQtSc4AlCSOu QF8bfLUHCwwCO1aiRMeEOLJoYyPid7aOI6X70ebm/hQaUzISEvzEJtnj0kkbY67K 0ztOayTmTQZa1qQ8wkd001bZ/PObAHEiN12eHnljuAUl9KpWVih5Zhn8AhMOtH8E wmCmovyHZEIYujIHs3R0O1VKXwGHWYqVaXla0gQdlju7q6LtvUN3Sd/nKm5JI+z/ SZ5H6PN/tFkCExFspHjEEBqVfJygBz/nCsqienqPnUVIJdjTI3IQ+KxuiJfWJxfp DW+KXgQT+fPJWdUvy0bnxy1JiIBe1yBlCEMwLKwjKBQ6QPZq7jgrarmmzQhh889J reaWgDgL8dNd45JN6dFnnx5lWDI+x7t8qqaGN9L4I7IrSOE7WqNUc8+JE6PLzYIC tAFiQll0CQ/WR8T2p0lzN7SXeIXQPnmdbLGnfXUPgIGvVWBvCeUVQ4LATHXXHIg5 uYniQ71lhxsydFpmejEJrlEfcjz68jApSeL61A2SpMz+SUr6x7ZPQDfmW3GQiXTk WViTjUJU3PHASsXfD5RTdRS36wizjruuSA7cI2AmC2WkzX7cGaNWyZM+2Bc1uPf9 jwzbiaC9qzgu0aoHlrMGNouMtLRaST8AEQEAAQAP/RNCZqGKAsdGhEtYjEuTFd3B lxZZR3lllBl2XIirTs99iINitlRskVde9I2qt0RGhakQGSg4jjjlr9mrLl0DreQt JU0dAw7gXqspW1uV8nx326aRlkv2WjeDn+uRKialf5rhPPSEX+FE7DRTJ9E6bKwN /yqZNK4wJcl8YbNZY8TNGcrA0Q6/x1tMVcJ3sWC3tSlOx6kD0yFfPQJVDf4wod2n Smjcu8xLY6QT3lwxsQuAW3FAiUeWWS393p/HIqwvOkqzehmUMAEUeYjtitzwzLon GVRjF8uYROXKJX6/ZHyuF3ESQzRvVZWZKvIxBIE+GweVuEUAC+Y7RJhfd0x+6J+3 Pi4WLIvYdRtoZ54YskMpi5Tc8wU6Bpzg9STi1EeLIb2deSvUYrXWnaek5U0LGN5p qcLbNb1VD7mXsl5g0Mp1qh3yrRYzUvmsiK0qLU9wDtqSnC+x7gZxHxtM2AU6orUR h832n9mwRdd7qnia35Xv3FVdnefJxMPeIqAkGIT24GeHvQd6O0/eyreYBF+jiNqJ OvbX1AiUweonQCNjyALlx3Ssl2jhtWTxfygM8N5H8DqkBxzI4/zgXA1qU+deIBOx bzLqCI1mQKnBTdp4Pg3XmgQV+24SFpZu5GuTeoaZ2gd/YDZ+sQZspg6Nv2qPpAu8 1zYjhztG+hmcjWuFXB+BCADOxBzA4seruDkgrLYkZ8BKQNUNfvuyfZd/YVbyt3LE l4zUORVjdT89LKaO3ywhfVNqXBD+HiF41ioo4rcoUEkZG539HPVBKzdRgCsVGcGI pB8VLprI49No+ZuZR7tamJng2Jbpm1ISWxk53vCet5ZMefIok2rqnzvGhM/ayMEk t1Y3OaUJLW+p9RsvZZkyZh5tu/aIfz7c7uEsPH2hidk8eo7uWNhSwlHTJ4/5HXY2 P7dIDNF8h4+5/2l0E0Yg+kRUVDy+kkH8VVMicQ6Pzxc4p9z8aXH3PI50Fzf2bUHW IcJ/4mLWHNJiBwIw6HkEFgXCoNyyAx+ugCquYCzPdtcFCADp2ezSt/63I8LbQhBA xzwuc4h9GlPSK4geeXthvbV/ewO5PfYNYf79ppiCVF5J0RBRZxbVCDpYegNIaQ/b YX9olqT+zGs2H2AJIkQZKc+NKusLNJYkv9DcJJwjH8KNXZdFLRwt+0uboe9uLt3q qhgowtgjAKkG/sNKwFi5nv2Wr7Y6ZMTFbj4nafeIM9fNErAbK7YaOIgEOeXsTqCw qW91oq8np+cnXkTRoxOR4WIe3cny2OUUQ8zR1/JN39RvUb29y+nrsARk/VCobxFb 9mrVD5K1TSYqa06PReEHe/D34jsEw50i+uAjElDZx6MjWSoFryUu34fW9fxJME7J A4pzCACPczGOrxzg4dxDC3um7cdnFmGjeK8caiHO4OZWGYATTFCP8yt9zV36iAKh pAEF0OM3R9GhliC5DDO3+cFdCQdKLBWhCUofgoeJp7VUj0OxeV7lkW/ZfvE0s7+E FhcpKs8kX67g4UM4PSbMacsh21bpk/dkU1w+pwp+M/TM0Ktx3CIfSNciPbzJgMgy dfta8feqoVQY2PllEaaPQ1Iixsdzb2eMnR7CbG88rHwawU4WPtA8n80tAp7nJhG3 AofuZPsTUgwqhmpGQEPUFKzimTN5AfqDLn3vp64Te65/VIFhkfDn+zY1wahCZPvG gZGFNaCqqlMYnO1uVXFhpGkPUvlZbSvCwb4EGAEKAHIFgmbN5YUJELsZqAm22Tzi RxQAAAAAAB4AIHNhbHRAbm90YXRpb25zLnNlcXVvaWEtcGdwLm9yZzhLMbi6lPlY eP0oNHDEmcSY2+AxEAlt6dtXtEd6w96oApsMFiEE7+ZH+bk8UQgm9waKuxmoCbbZ POIAAGJTD/98w1lD4F7++ADe3zH1Exjt+TQ/vz9IkG3tP0ebSUPZfnVX52RcpoCt 5pP9F39+RiU/58XXZW8a3sJQo2ynF/phFHa0WDRQ8H4xLpTdnRiqjfu44TbEb5KQ 7K3pjX73vmkhU59IccFBylHmdrVuBiQAwBEuizeOEAvTrXAJzxhuAlNd80aonDa+ o91pLMmVqc+qf6gd1B7qfiO5u5pqiH8hao64zXjaUYjSZjdw6YQJkwduchzXjOd1 fTNi8AbQUwrV3TbhcKFVOIceDP/X2bfRyq/E291895ZUWGZ1zVPr5yofYUWHwuiW l1lFKx5lGFKWn6JHgoSjzcmtGt4tIwSc8AFjwYzv7TPPbUXxdjDbe/cLPNquCwFd XE6hdc07RQqUOLfi0eeJ39ApbOljSRH5dQ7xJhxBbWC8WRrbuLeZOC9wS2hmhviU zkSxoPF89ed6VTjqhaEwXT9KP6XJDjEhKmBjjizRiepJo+CSMrJsZW/SoUimqf7o erQPu08zWNlmaJRsnxpRRrSuu0FRzpp8gsR4JRym+ydJUmVUVv/Ef3OQeHVECElh 0BD+eR2KGKVXR+UWtzlZXIcIKznESOpPUmbWiKkva4hiBOm8aBBgbgWPElq4UyfT 5nkcaH1Oqt3jDCEOKcCWY5erJjBSOjAHowQcZnU696jEtJ/bUajURsfGVwRmzeWF ARAA2WVxvw4ImKIEw3/xkf5ZLZmEhQskBevAN9N3OXqN6IEIPN9qmU2eNbyzbos6 KArvgAwbquXzAmRfbVDE/Z+5j6E0Y6BXb3b1o0UZlVH/TuM7I5e/KSxZQ+yAzlgN RqnBbzG6G/GPgrUcC7zeLcZQK4GoCy9qJ7ZU3l8RYIOm2lTPh38lOHMeGWWfhjCg n3obiKQulTLdn/lJFcXaYDlMGyCDNaAGXNxYfaHo2CtwxUJh7e8GEu/uLVnbJJcz iU81EZ1itIDSwpsldTz4YvKrC5USdxviRW/qQug9Lh1NbjDnKF9MQtjFhIK9pgDs 8FGFoINynEAQ1xeAWRFr/2I/l5ht2Q6pct4+6ggrJkJegsHVkgkZuC9ctghty9UC l3p5jCUfDfMzloV5+uX6aYA59wc0S3FRlSp5UngLflS7JuFWBHCtp9prj6C/sb4D GNJV2XghNo5JUNkjEZPKarpEQmpVWZmht+zekDkrnAtMs94k8QfRYWbeIPRNk9qC IH0Ryv9LyLk1gMh8KvdXr7et4IjtiCexcb2kdJxlcGvaVo0ofVjePHdcVOm9R/Ks LZnaRC8jNnaLXigj1t2x5Yq6LmLVfXymTYemPS8/8ROg2Cvi41AukLTqXzqVlIqT r4bmaNFRvu9Fmrg6Lols4AdK88ty3CBvwHZw/swor+JbcTUAEQEAAQAP+PcdWS7T xPG7Oa8AwJgzhytOVlTlVQ1l7hmHRv8PUD/6bGLFk2av1CdBWLVPjcv2okfre4fH 23PcpJyeM04ZQdUCaYrVuI37qzzsTyhtDMmfgpny5FjpEI8lR0VG0dCBJmA/Jk6d R4RMWpT9G5Ds3DSYLWyJeSGrIM2lQxtyizejMEPVQ3nnYU99NNhUbkDZjHLGLi1q pIIz29/kB1dZyikLzBoozRLBZdVpNkSDHK0dyDOugDkGgrcKbRAqz2pFnw1m2cxU oz6THQEnTTEsp0GDMnoyOAK2NJPZabIBnQKklB5QNV/HCL6X3vvUEYEbKcpLoPv7 1yiojjywkRK7m4udii54AAcyIcjNSDVJ7Xouc2ov9gyhPu5Oc2RMVDJl3LC7yOPW mz3jor36D2gsJPxIGGEf3dslVFwqNGFpRRJmC0DqNQoGdN9+XQ5AdzIX1rGf7VRU fsjMGTmNBBW++JA37GoLQ0TLhou6EAGFqRO/kSNKb/wFdRdxYiA/7Y1iraicnuSP Bp0sxhzzjgk1SuUnAQXunyZTXzgYlHUejFMC6Q3IqgRWLhhFuse9Ng3t2cJuJaNA 9nL5BvofKzd/Nceca80mZiKXObku3Uqs1nICY9HHlmVi76T2yDQjrPfOc9fXIxzs sBbjShoDU0vWgx/gcngeSfLxwFU9XZhNwaEIAN7wxKfZB3HowjjOXTj7Z/m7IrMQ wF63T+4XmiTtFBIToSgX5d4Xhweh5wVDttYiCIq9CwhxpxNVPW83K9vscXcmFJrG 7H3Newv8UqeiqPl5GKMp54T72OxOUsfY4g+HVYg/F8OA+jYj5iSvMwYU6jC/acJo 7nFEnXbp+EKv5wf+gcDlyZF/vnXEbw8DTa2jhkpEEqeIHh47we5MoveKxWb/e+GI 14ehRjL53vYnWnCR2VopG5W/DOGzKuX7QkY512ULNV8RgopW8k+NeuZBJD/FRI5C HWpvt1F8dM9gt5b2NyuyT/lTPIBf7LqCG7gRWciICIwIkNaq3+B7Z8qa9OkIAPmi NPGmoqxqaBaPzO7gOzxKS5Xsm82/TBrhdMSQPUUoQm/any1OImjWpH5bv6fZVQoH 0yFmi4zcYSK5c1wVipmXK7FtXslEcB3KzkVsXABrdMSVsxlKuobizS5CyfndM/lp RkN/eeySxuOQ4QdFVhLgykFiDIH3i367FHAvpkR80HdVt71Vt5b+vQdpger2ByjB 79av2kRWn8tN+pW8Qz200xwXG+sopL+3DDPy+N21xvS6tHo4yPl8Jv+ArT0Wh4ic LFd3gtxxU0/I6rS82QFfwAmz/k93HB9EFT5iYRSES8fzDGCRlgOdkLerJ5Mh4c6C tu5ZDRwULB/YiJqFmm0H/11InqavSPXuDfPkarnu8HpG9PBkxQ7Aq/Cbg/rh/ykB ekJPGX5TIQrh3awU+5UOixIFI1ZhQLwutUHRV20YwZpzRPDcRo5ZLv07HodSDGsg 6QEhyzWyg3nFpNSd6R/msF5CGt9ikJBc4+SIeIJsK3YJ/saRDCWF2Z92ZoAS48py 93TFbThDK12UmCxRvNTs4RIPbdyQKmOX/ABGvZH+INWcNIofjdHpfl2A7eoiWphK hKz6g92fKcV5+anGaRFU7L4yZx2id2hR6Ygk89WAZVmyop9Dl0I+9VjY/gqxUN3T mbOxLFQ+eiUDIFy91bjgBlMTts6VyBwOo6/DWWmeH0NzkcLEPAQYAQoC8AWCZs3l hQkQuxmoCbbZPOJHFAAAAAAAHgAgc2FsdEBub3RhdGlvbnMuc2VxdW9pYS1wZ3Au b3JnRcoSV3ma9OQPQars+GF4/Xn5aKLswUd8dyYcZODsoykCmwLBvKAEGQEKAG8F gmbN5YUJEGuhvzkd+ALIRxQAAAAAAB4AIHNhbHRAbm90YXRpb25zLnNlcXVvaWEt cGdwLm9yZ/6Cg428bd6C+YKTtOlAECOya5Q2GbcsC0LEIcq4hcSdFiEEjUayl1iQ phWvQQnLa6G/OR34AsgAANBeD/9Bc8kgW+GpLmWtvD9CBfCYwXhslJIJgS9X7000 bp9wM03RV9rdpooR74DLftg2jMlFkAzRmQCnXFBzPAIfNZlHyx2FMmYkeMvQwFx1 i6bsv/tDvDJen3LyW1jGk0XMmNSd/JcfK1BLKsBAFZUw7RR9C9ZAi7uA0xOIuPI5 YmXfxcGBuDICN4Pmxt9JMZnHIPxz0CXn5wTX99Gw3OIvvli61EWuI0KX72yvKduT 69CUHKF4puOGh3fEMAVmzQiTNAWmNo2ZraDoZG/2qD6lI5WLU5+v11dPpW+jUzAS be0jYY1l+sKu9ujph+GINF/DVTgy5PjuCjLA8MBiboyc7yDT7PXEzYNU/bqc9XOo SJzHMSDxiMvV1XNY0Kni6bS1IvVtXWXKLyA5WqOwaO9ylp3a1xzSuDH10sxkUKL7 1IQGtNgCN1lV/+dF7N0FX4DAo1mbyDTv6tO+AvYhWioI8gZ3zE4QwxJblUboAIUU 8A2+YZHIv3LMSUCFn3kV+CdKw0tSLrz4upR7GFytzQdSx0CXJbNqME9Fab3jrfpD 7bzHXDW1ClSmIyambTyUlJCJOc99cXvCamqNbSz0R6+/Ny06etd4Oefx8tnY1uD2 /cERKp9XP1QjBXeN1KRj/YYcsnCD57+NbsYP8y2r3YuDqnkVDDlKEoKTFtyazqiR Lo3BmxYhBO/mR/m5PFEIJvcGirsZqAm22TziAAAtjRAAtTEz/Tp4HYXaPBPLxjv5 JErEdfAl0rzoO4iAXOwkjBC4GXI5BcBsj+QEGT2mDoAoLjVsgHMenJGHgC56x2fP D636pCg4yFEsJjc4334Oswjcgtvts/pwzOrRcCgFRCY7iiFdFY96uuaxL5Q6gkyt Y9HrOcLxxM7bQaRr6a8ItWblZlArSGZxMJvG4mxIiJlywQVp9M+qhSMuWeOJSUoy /7v3if7qgx48KmEdUsuisEj91Xf3Erg/OgK8Ey5jaoKmCmAOftFWZWm6f/MTI6br hhglc88iMiru5jK6BRYonRfjiFcnnHi8PTZLiGPJ7ESyEc2MOeFp5Dw03zRCqL9Q 27iVRi622JADcPbqqa36p8YRFHTSzo8cnDbdEwTf6K/7I/GQxSArkX6T2H50u792 JJtqtZS3EqK1saFMQIfZO1Rf7H0dfxXyo6on1UVW+Bkj8VYSgobHOLBlPFz99GQN ImLv2jwQg5ZyASMZH3uQZ/FG+WxHx+r+CAROEUTA9Zo5f9lrnELqrtyyIjklGL88 kBeF9pHUzx29bjRzhxoNIYpdLH6uI2Es1KcGg+aT1oJm0ggIY10iP6/Ztfq7/bhs yeSgjdM7iF4zGsFIW1RwpTIBwoG3fADj28GFLmEw5PhFN7gPX7reB1786Ma0p+bl QDQbAQBcygH8+Zq8KjHunPs= =SX4i -----END PGP PRIVATE KEY BLOCK----- ././@LongLink00006440000000000000000000000154000000000000007773Lustar sequoia-keystore-backend-0.7.0/tests/data/keys/rsa-parameters/06090B8738F4CC3F41037CA7AA5BFAC1E4A121A0.jsonsequoia-keystore-backend-0.7.0/tests/data/keys/rsa-parameters/06090B8738F4CC3F41037CA7AA5BFAC1E4A121000064400000000000000000000071321046102023000267270ustar 00000000000000{ "e": "010001", "n": "BCE081AEE9E548E2D17D1EF06D13DF8C088FEF0E6C2EAC8BB60832A1B47CD696E2006E16226F5D8538A45702071CB913990B527380250923AE405F1B7CB5070B0C023B56A244C78438B2686323E277B68E23A5FBD1E6E6FE141A53321212FCC426D9E3D2491B63AECAD33B4E6B24E64D065AD6A43CC24774D356D9FCF39B007122375D9E1E7963B80525F4AA565628796619FC02130EB47F04C260A6A2FC87644218BA3207B374743B554A5F0187598A9569795AD2041D963BBBABA2EDBD437749DFE72A6E4923ECFF499E47E8F37FB4590213116CA478C4101A957C9CA0073FE70ACAA27A7A8F9D454825D8D3237210F8AC6E8897D62717E90D6F8A5E0413F9F3C959D52FCB46E7C72D4988805ED720650843302CAC2328143A40F66AEE382B6AB9A6CD0861F3CF49ADE69680380BF1D35DE3924DE9D1679F1E6558323EC7BB7CAAA68637D2F823B22B48E13B5AA35473CF8913A3CBCD8202B40162425974090FD647C4F6A7497337B4977885D03E799D6CB1A77D750F8081AF55606F09E5154382C04C75D71C8839B989E243BD65871B32745A667A3109AE511F723CFAF2302949E2FAD40D92A4CCFE494AFAC7B64F4037E65B71908974E45958938D4254DCF1C04AC5DF0F94537514B7EB08B38EBBAE480EDC2360260B65A4CD7EDC19A356C9933ED81735B8F7FD8F0CDB89A0BDAB382ED1AA0796B306368B8CB4B45A493F", "p": "CEC41CC0E2C7ABB83920ACB62467C04A40D50D7EFBB27D977F6156F2B772C4978CD4391563753F3D2CA68EDF2C217D536A5C10FE1E2178D62A28E2B7285049191B9DFD1CF5412B3751802B1519C188A41F152E9AC8E3D368F99B9947BB5A9899E0D896E99B52125B1939DEF09EB7964C79F228936AEA9F3BC684CFDAC8C124B7563739A5092D6FA9F51B2F659932661E6DBBF6887F3EDCEEE12C3C7DA189D93C7A8EEE58D852C251D3278FF91D76363FB7480CD17C878FB9FF6974134620FA4454543CBE9241FC555322710E8FCF1738A7DCFC6971F73C8E741737F66D41D621C27FE262D61CD262070230E879041605C2A0DCB2031FAE802AAE602CCF76D705", "q": "E9D9ECD2B7FEB723C2DB421040C73C2E73887D1A53D22B881E797B61BDB57F7B03B93DF60D61FEFDA69882545E49D110516716D5083A587A0348690FDB617F6896A4FECC6B361F600922441929CF8D2AEB0B349624BFD0DC249C231FC28D5D97452D1C2DFB4B9BA1EF6E2EDDEAAA1828C2D82300A906FEC34AC058B99EFD96AFB63A64C4C56E3E2769F78833D7CD12B01B2BB61A38880439E5EC4EA0B0A96F75A2AF27A7E7275E44D1A31391E1621EDDC9F2D8E51443CCD1D7F24DDFD46F51BDBDCBE9EBB00464FD50A86F115BF66AD50F92B54D262A6B4E8F45E1077BF0F7E23B04C39D22FAE0231250D9C7A323592A05AF252EDF87D6F5FC49304EC9038A73", "pq": "4FEE492444F4DE549363EFB290E49F33BC45E6F41BE2A88C340F41124C46AC2AC416447165DEEF0C80ECD6600820BDC0750635658FFCD67791C59B17131A4482AE26C0DB6AD845F831A9CABFC60865C899A4476AB6612486D8B3032BE98D478940683E22FEB3C83F9885880DFCBFA4003A1CF59F69BACDE9CB14A70407E15B51D5CE6C60DAC6E743B8EE14121996E61F9B07D5381D2C78C54B155873E42BEC2EDA622EC2972ED9D8CB3F4D6E57153D558D1A7BF2688EBC0384B3A103CB2F94C0A5DA6A5CB14F19232F59B8A9D6BDDCDC27497D9C2C0E6807B019CF89AF8C91464B58C398BA0415D70033D71F8DB612553ACD6E4C4D2140B4C841486FFA2CC6B1", "dp1": "05D491DAFE8A12D58706DCD7E5FEE6F5310ED0EA9BBE54BC48E33DC86A53DA274BD95022C243341D4D7D04DA562C3B94769352075862293E20C2366263C89FC70D784F02DA07946862EBF24B0E06DF0B81B4DF338E269E777F525BE821E8541542B9D8C78D91AAE2D6BB430615F3A75150BEFB55ECD5E0D796A97812FB4636FAD47B8A2C952DAAD06810F42D313CB2947913ABC7FD8E903C4C2D2B277FBE9B59913B268D6ACC2A9E940DB1899CC310948B5E84BE037CEF18979329AAC1777C9720A99F6CE042EC129BDD84C29C5B82941E67A4D674583C64E7F11FAADB39D807EBAC1F7E19FB86132D8F6A41A3E7F19707FDF13B33CB58E8544BC67A7CFF24E1", "dq1": "59BF896455B92C104D7858A2643A129EC13860CAF9E06F548E5D913CB1D2365ABFD31834966E45AE938174836CAC67D01B6DB5158D52D721FCA08DB1C84062E580EB51DEA246E343B83DAE64F9E6EE06CAAE42405D5A408E3C7EAFFC406E80BCCD8FC280E330E14A04DA04A2A6AD211883AEEFC0111EDE279548BCC4808052949D1B4C1138B456A649C4F640EF51851A9152F5509AE198BD9FC0516CDA602CA6B908FFEF3087AB663E0E9834248BC3CCDAF498C9523DB31DD602E8603EE77A3797DFEAA6C9A6E61B5219528717043B7C09BE0456D78EF01FF65C9B408410B711DC14B7FE56AE71D703F083A45AB7F6406A6E0D972FB2B28D3585E1445B614081" }././@LongLink00006440000000000000000000000154000000000000007773Lustar sequoia-keystore-backend-0.7.0/tests/data/keys/rsa-parameters/78A99D7156DF6019725ED77CE861DB738F65C8A1.jsonsequoia-keystore-backend-0.7.0/tests/data/keys/rsa-parameters/78A99D7156DF6019725ED77CE861DB738F65C8000064400000000000000000000071321046102023000267520ustar 00000000000000{ "e": "010001", "n": "B3EFBCB68A533D31D4745723EC7641B7620AAF6E7DEDDDF91A385996A24138F748C7166F0A3D59F34D95E6A181BBA8D4A4A74EA621C746BDE4E400BBC15DED202D00B04233C87C53DF553486CB967F246CCDA9333533A9224D82E766FE66102CB574ED01989900572200E91AAFE30502A680F7EA8CF67CB70D4D5A9991E96C3A92A712E3A9AC0DEE9416B79CCC9705BD0812E4915BC95EB5F54239A2DA5CDFFE5E30937B7796D0D5F76D8A44A32027E0F38DCC6FFFFC9759D1CA31875F1F7B4F0CE5815921E1E223D51E1BA1A1457FF531CF239DCA6715E3134134600683B6B0E672EEC3084223AF0253BB08C6C61173D86AC4CAEE745C5A25D17FCBA7A0FD4FE4669F6E4ACFCD50D713C25DA5B72CECC5D21EBB0D40554FFF48F87122241FDCB423349389F257D99321A72864EF84DFDEE8431206EA0B0A989221ACE29ACDF2119944C348D6B5AA3E750279840C44CA2518F24CE9A577F61C9170203255A3B195C32E2A2ABE0762DFE93EDAA0263372F2A70350FFCE0F296B6746C837CB3FD2E07AA9E7DE295AD735B1415FD48340C7A9C1070C4623706BDE28EEDA786D6F397412F2678A25B3EAB2639DA99661729CD2C7359C1D9AC26089559558424A2FFF9F0B3F5A1941F5F047C0AFB0346587F2CEBE4F5FCA73B9E14F1B080F5062564FF3E92FF6C07C53E405A10C02A58BFBD83C8042C7982371E2A3A09DCFE0B39C49", "p": "B5E88557AB1450C24323F339E0ED099C6006235EBBF0C4F535151AE0345A3ADD0CF797E9CA0A666DF6EB1D1BAABD78889841FC544BAC30BC4DD6AC80508F1B7F21FD1C7A112D0B62E26F3351221E7F20C38169581A58D5A487C78BF878B2CD5BCAA0A70CC3D95DA2B4A7B19E24E142466C4368D3A485286B430F059C2169B2E6080B81CE45AED62B1FD7B9B4E1CAE08E5A56702FFB7700D256263056CB0ACF342D4BA3629167DD67746C8DCBCE7970692F622A323CA8E4AE0AC0FE316F46613F89C18923DD9AB1A3151FB9B24680D9EA3D2ED62A1C29A9478FCB760231CD821F269EFF5573CAB715050C562FD2DEBD5CD0CD14E46E9AF1F33085F0E904531931", "q": "FD399DD82CB3E60C73151D467AAF0EC71639B59B1AFDDD9C83958C02A60F97C652D3ACD30FEAC1507BADE9B42B1AAB0524B20FDFBEEFDAE0180218FF91A4E6009566DFEAA0F811EEE914EA88C2FF92A68E069DC8F77D4AE57186DBD4C9E91A2121A855C5CA3F27D5E3C174C1828A21664A904E1774155C7575E1C2A1E50A76EE377E09230D2CBB2C24B27F4F4EE35EE86C89FEE6CF85CC4BB8E7340CE1F3F4BAA784E824E0685138D44DBC66EDD403E7A90E9F712C8A45C38F6D027F15B297FBA4E3C88F8DEB0EC377C5D7D8B0AA38F6D7AC3754F8641C4E9A565506F49B5E1A875A54AC2E31E6DDC2D863A5088655E142FB68F2E30DED306EDF8A31FBFEEE99", "pq": "7B69E442D7EF6F432FA3746F402D4791DC22F45FE263D729E57BB5AB2432DDF55912E02BEB90549FAA98A3DFA1B3377839C3C2EDFA677207E82C77F6F4E17C5790FE0FE89FE42C2CCC5BB1E96C7F9C7A718446670303D6E141B557AD50550625DB1459DB8F84E3BC4FA45D400919840E0C44E80FB6B0BC105CC9E855FC2A9B9B608107EEFE38F83F84705FB10CB08E5C5CAC25E6EEAF44117ADB48F9463D95D5653F40351AC880554743993FAB35C533A0846C15BF3641345192AC2BEE6146864F81D0E9695F8C6DDBDE0D1F26ABF12D4CCE420BA1F18B88BFBA9600B8B3C092742A987FC92A80E1DB6CD9CBD3C5872BE76A1F420017FD1B8668A3D298ED9C50", "dp1": "08FCD209C0D4222156FBE1BA8C5869CF2617678BF8B12EAA06D3621E8DB79F8CE8651B465BCB23C06F20B2B179401F427073622A300AF3E579DB0F6ECF8C2289A77E3FF7EFFD4FC0B4FB5587BEADCF0E295AAD7FC2DD7CC0C24CA3A7C51EE0729692556E9606994FBEA9426753DF254D21703B2FA9C34279FA3835C8BF05DFE6E9A2D7E8FF1C624C83283F6EA67145A302E79E67607F42B521B8854EE47D463B87B962FB2DBFF9FA709024795B5C38A799C5B9DBFD8F42AD2EAED6604EE5254CE45B81911A13D88EFC2E331891CF2FF518CCC59C130423EEFB35CC40D38119DABC27C2E9CFECC61AEDC2EC47349DF8B12B47D6AE6AA0912FB8C8055D1DEF9521", "dq1": "A3DBACB03DFD0B57F3002EB97499E2CE212BA6C07F6ED700788544DC51E8B525B86310EA62DA5DCD5EBAE3079AFCDEBDAD492BCC75197060A2287954A74235331B7A3E5AED5E98FC280748DCC691EAABAC2BCBDE4787E3F724C74769225E9C71E3FDB1C313645ABAA56E81C6D659DBD2FD5CF3AB698A8911D8FE059C0D42004395D510C485B9F444545ACCD6DD0D7454A22789B28186EAF3F4EA675C0EBA761A725C267BF65A8A7463AD09C4F110C896176746F54D050CAFC7179B0DF15467D486967F29A583FD41AF376EBCE154C517B5E7D2C6411546DBF632F74250F658A681FF89DB00E979A2F67A5FC0630BCA76C1893E182DA4CD5F11DFC4E523538BC1" }././@LongLink00006440000000000000000000000154000000000000007773Lustar sequoia-keystore-backend-0.7.0/tests/data/keys/rsa-parameters/8D46B2975890A615AF4109CB6BA1BF391DF802C8.jsonsequoia-keystore-backend-0.7.0/tests/data/keys/rsa-parameters/8D46B2975890A615AF4109CB6BA1BF391DF802000064400000000000000000000071321046102023000267210ustar 00000000000000{ "e": "010001", "n": "D96571BF0E0898A204C37FF191FE592D9984850B2405EBC037D377397A8DE881083CDF6A994D9E35BCB36E8B3A280AEF800C1BAAE5F302645F6D50C4FD9FB98FA13463A0576F76F5A345199551FF4EE33B2397BF292C5943EC80CE580D46A9C16F31BA1BF18F82B51C0BBCDE2DC6502B81A80B2F6A27B654DE5F116083A6DA54CF877F2538731E19659F8630A09F7A1B88A42E9532DD9FF94915C5DA60394C1B208335A0065CDC587DA1E8D82B70C54261EDEF0612EFEE2D59DB249733894F35119D62B480D2C29B25753CF862F2AB0B9512771BE2456FEA42E83D2E1D4D6E30E7285F4C42D8C58482BDA600ECF05185A083729C4010D7178059116BFF623F97986DD90EA972DE3EEA082B26425E82C1D5920919B82F5CB6086DCBD502977A798C251F0DF333968579FAE5FA698039F707344B7151952A7952780B7E54BB26E1560470ADA7DA6B8FA0BFB1BE0318D255D97821368E4950D9231193CA6ABA44426A555999A1B7ECDE90392B9C0B4CB3DE24F107D16166DE20F44D93DA82207D11CAFF4BC8B93580C87C2AF757AFB7ADE088ED8827B171BDA4749C65706BDA568D287D58DE3C775C54E9BD47F2AC2D99DA442F2336768B5E2823D6DDB1E58ABA2E62D57D7CA64D87A63D2F3FF113A0D82BE2E3502E90B4EA5F3A95948A93AF86E668D151BEEF459AB83A2E896CE0074AF3CB72DC206FC07670FECC28AFE25B7135", "p": "DEF0C4A7D90771E8C238CE5D38FB67F9BB22B310C05EB74FEE179A24ED141213A12817E5DE178707A1E70543B6D622088ABD0B0871A713553D6F372BDBEC717726149AC6EC7DCD7B0BFC52A7A2A8F97918A329E784FBD8EC4E52C7D8E20F8755883F17C380FA3623E624AF330614EA30BF69C268EE71449D76E9F842AFE707FE81C0E5C9917FBE75C46F0F034DADA3864A4412A7881E1E3BC1EE4CA2F78AC566FF7BE188D787A14632F9DEF6275A7091D95A291B95BF0CE1B32AE5FB424639D7650B355F11828A56F24F8D7AE641243FC5448E421D6A6FB7517C74CF60B796F6372BB24FF9533C805FECBA821BB81159C888088C0890D6AADFE07B67CA9AF4E9", "q": "F9A234F1A6A2AC6A68168FCCEEE03B3C4A4B95EC9BCDBF4C1AE174C4903D4528426FDA9F2D4E2268D6A47E5BBFA7D9550A07D321668B8CDC6122B9735C158A99972BB16D5EC944701DCACE456C5C006B74C495B3194ABA86E2CD2E42C9F9DD33F96946437F79EC92C6E390E107455612E0CA41620C81F78B7EBB14702FA6447CD07755B7BD55B796FEBD076981EAF60728C1EFD6AFDA44569FCB4DFA95BC433DB4D31C171BEB28A4BFB70C33F2F8DDB5C6F4BAB47A38C8F97C26FF80AD3D1687889C2C577782DC71534FC8EAB4BCD9015FC009B3FE4F771C1F44153E626114844BC7F30C609196039D90B7AB279321E1CE82B6EE590D1C142C1FD8889A859A6D", "pq": "8BA1AF04BD5E0E258433DBBE436F6FEE014EACC6C18C585DC2FB305EE0E9341DD1CC002B16E1110C33A307BF1ADBEAE2EEE5226C4662B9985B1F240FDCEBBD57E69A38CD3DC5CD90F975E0FFE9FAF0FC9F3B9CF11E47EDB042AF64CEA7009BDAFBB80B358FD509B3DC6CDFE613FBF9C014947E381131976457E33660B5F76A084C57917F6061C426166AFE6DE60DC7AFCB7094518E981E89037AC3F41F4000DB651E4B7B680B41121431D932F93097E6AC9E4A08877F1C8E29DB9078C6A7AAA10FAEBC524E42DB37556FBAD0FC3F2799F56CF66BA2ADA0AD2E80F4089F1B4F7DF6C612F18E49F215E3E626D6372EF1352B55CB25738EE23C6BADE5657C1E6147", "dp1": "DB32D5D8C69DF854C7AA3CD511F2B6BFA74CADCD59A7870B72E907E928A52444E29E5E28E81E2FE8C43A3645E6DE51E61E2B534EC11869FCD483A6365C6CF4FF169509BD6EC71EA2CE1D1053BCADF1642C62391067038CBC83220756EAA624056809C8DEB3D0D02CA9DB05DBE02DEE3971EA9578C080E3DB031176C472D97055BFD41EDAFA5124BDFC1ECA1F10601AB92E0A12616087646892FC2FA3C84A4C5F41F1D6C5CA4C93B846E4C1613B3E44125327BFE55C6DD54790F72BDAC8C5ED9727C5467BABE6B3085C04F5F191B518E40E9CA256C53F628A56F74C8E9DE4C4EC5F407A790186E2A4C22C2B114419CE0D7E0AAA84ACE363FDEC5376628DA5A009", "dq1": "5104BA162BB4E42C6CB7D5D7F73743426002841814C103F3194E4EED74BACDF5310AC8739CEA9CF455A571752990BA52853CE0E3183AF66E9800031C53A8922123150532AFEEB68D84BDCB907088B3822C9598D855BF1126B1F951A84F910E9FCDB4C31F2902532B97ED479A2117F9C58ABB59D90EA227CB5848336BEDAB12D3477D538E9C9E7345484BE559F2D6651F11B54FB7E7BEF92AFC15A9AB48699F91295CD2E315268F3C5914799B6AA226A2D67D9B12F40FF5FA32B71D798FC021CDBF22A0A98A9A281D87A27F5CDD67E52E32FB4AAAE640B831A25C2060ECE1011DA6D2B029363649EFC675AF869703839D9BBE84CC7A8E6CAC875D96934F434949" }././@LongLink00006440000000000000000000000154000000000000007773Lustar sequoia-keystore-backend-0.7.0/tests/data/keys/rsa-parameters/C4397A533A031A950187627772643C657B02355D.jsonsequoia-keystore-backend-0.7.0/tests/data/keys/rsa-parameters/C4397A533A031A950187627772643C657B0235000064400000000000000000000071321046102023000265360ustar 00000000000000{ "e": "010001", "n": "DFCEC04AB9928E58BC6AFF1CB7AB4DBC011946D0EC58437EEB726B98A3AF60C6217E3A2BCB1B1AEEA461C34DD2E9AFFD6C3E4DA46240509661DA1215B0B880D2326B0273BAE20AB18F51A20A1E629D5E8519D974E465D05309279CB6D5AB39ECEC1E89B7E7DE2DEC69D1E9F6606DBB02C2377473F028687980EF9352C80226E0D85DEDC48455FB71BB66CF14DA9A6236D57D13417ADACA5B7AEF40050AED064558C7CD8BBFC766C3525CFD9ED0868D92FD79FBFD1D7AD480751174FBD5179C77FA7B413C1FADAE6F6EF02903518E89B024EF435B2DC0FDC8A3A4FEF37446C1713EB8F9873CA1F7A25B0B8E0A13D14B69B31EC2AF3B76507BD3A69FB88267AB3E4B68C8F746D5FB4E10541E83460BD31670A43D97FCFA99E13B18DB838C451021E993DEE75C243B3495264A9261F31D48C8789C2629D4CEE9C960F000BEF22C3FAC02D33590FDB72FEDB610F0F92E86DA960BD80F1C4B0DD8C2633122BA2BA14BA13C3C7001310CEBA5380BB59B24987C42903B6820C86E67096C2352C6E9539E590669874BA51CA1BF1A91DD3414E66C7F2FA58690EA2D236714914D0860A9C398D60AC0841C8E62336D3DC1219B5786CE14C04B52072C785539C8BC39D89BA1FF15CD6C0297EA99E431CE8D9528EC5B378F62FC3185938F918878822856C26E509308A65AEA81A292369E7922D4331AA18EDB61068AB931A9090AC6E9566351", "p": "E90E549E51340DC961BC9C532DC433F6F4D4F47084DB9C9B8143DF81B88C3F8FB2A51E2F8743C2BAAB016FE9F0EDCE1DE7E128D2E24DD156F9EF497954976947C660F567DF4E9BAE23EE1D764713432B1B32C0EF48AFD7806DBCE39C6FEEAB1D0EBC8E5B2D2F733D3A2F1EA4EB1AC0BD3989F3DC93128535E7F8345523A0EF4F8C48D9D72224ACEEC27F772DDC12CDA89AC7526301F39B3C9364C04B349A3FAA4173F7678295826F368235883B9F8FFF0ED1FDD886430E7ABAFF6541E6A14761FB1ED20B09C59E2648F0A659F54A5C18EA3E99E5B38B86153CBDC5DDD908EDB0E8588AE2F31CB579DA71993054616E1889B581A24DF0F77A87B17C608E52E12D", "q": "F5D755FADEC59FC768C996512DDE3411392B2D1417A06EA3DC16ED606CBC46BF5F90D6609ED55B093D1BD6AFF0E289972B54E92E9DB67E9D3969908F93BD11B1C58AFFDFF943D64A2869230D65BDCC6582DEAEBBAE9074624C9FF2750A11F3A5377A2D6D6F4E58CE2854345BCC8E6C941301FB794FC7B7E9BA7CBC448E156FC9A84477DFAF40E67488AC4A3F6BAE632786D1A3FAE6D02CCD693D7F99832F3A70EF5FD3CFB322C008A7D3827349D65A68A774347A05B4D6E4A79E51480D0AC19DEC558192AB8FA286DFC73E5CAB7C07617391EE81EDD7F4C53187A0ACB1F81D4AD995D2105B1AEE1E1E592234ADA255F1926019E60222ECB6013675FBE96DF935", "pq": "122AD0EAB514B2749F7FF09B33F017C40CB3AA6D10AEE45A47A1F3224FEF5CF1CF7EB7E8589EFB53BBC08981C7753BA2EE5910A32BD8242C766754594698F5616E29F9D802BA5216106FA14257780637FD23A9900E4487B160FAF51B0A8C792D62EEF40DF960E6304C2E42F55C7BB401568DAD73670F893B73AB5703409E061362928575710C56FAA1DFC4B2D69E97DC67D643956EC246F6654816A09647409BA8E149B5F89A8031D72619118E46E0DA6E78927B8E86D6CF1EFFCF0BD359506B919172F2D4E74F1BA4DF2196A66D79B25AB3719652D66935CFE0405B64E92DCE4F0122D7764E43C199A0B799E720391673FAC9D59B6CB5AC3BCDA19E76D96EBB", "dp1": "9E7CF85E91AA6C95BEB99D3593B21204A78B0A905A495EBF01B13E95E102BF56E18E187109F3B2C16EF99339EC764BED5A7B6C5FBD365E5E5FA9B2B5A8292F9777F907EA9399C9952B2A0B2F1C36A53EF348189CA139B3BBCAE4E184C939ED73DD49AD25A41CD8A9929FE89F0EA32ADF83F9A4B523EF3C57E4608E7637BC8201FECCAC17F94827B256E28811CFCF99BC4745B5694F32732746B505701F5DA65E0A14EAF2A1833B2896510646970573CF682CB60C4181E89EDDFC40C80827357C14626944C868739C658E0212BB14CE7CC30FBF68CE28DC0E2538890ECD419D22E95F0D54393014D9C10BEFB94628DBCE241823085528C1A3BA13A119A8B00421", "dq1": "528B741620F8B0366F6BC86A0781A56FE7072542AAD03676146F2A53070F8C9DB343D98765AD73BCBD64FC87E4D4DBA80367A647FDB289FED689287DDCF84DD9A7DF8D1CB2006212525142F0BBA9A7D8A9C18560053401B003D46CBF799B1F78E910BFF20FBE79B8F6F79700FFC50E96056FD3F51EA18B921208D1DA1EEEF9B2F729CE2A30191588295FD82A4548AF88550F4D04F0BD135E0129220FF4694631275EC0AAEB960E6E99933E28E1B0F4785149865936534B184963B21D042C0968B232DFA7D4AD0CC046A10AC268DDE348885A867FDFD174214609291CF340C0ED21F3D92D9EB9831C5FCA43DEF6321CB35917A57A825B21A9D6EC675F2738C2C5" }././@LongLink00006440000000000000000000000154000000000000007773Lustar sequoia-keystore-backend-0.7.0/tests/data/keys/rsa-parameters/D6AB039AC8C59647B6DA709A9041B2E27BD7DC7F.jsonsequoia-keystore-backend-0.7.0/tests/data/keys/rsa-parameters/D6AB039AC8C59647B6DA709A9041B2E27BD7DC000064400000000000000000000071321046102023000270000ustar 00000000000000{ "e": "010001", "n": "D73BAA7A706F6F1711EDC6ACA68009092042702BE72138311EF22404B28E5BDED1C5E19897EB31CDE90A36E823F9683354C4FC68558BB26A0A6B33AB8ABBBC0DE79C78410F2F866BBC6876B76F53A4615B58FFE28D3C3846E9E9B782BCC9EE81327ABA3C129F8831BB23BE1514B7D05D383092058360C51CB49FB7B8D080A0E3B0F7E57E4AB0627B38B3A1D029BD9E38E13C8F7B4F6214DB7B97996272279890826C19FE9252D2019D2FE9C9390CE561F791AD340B7893CE25C00B2E0D5223EDCC86C608D440E936E5ED72EC1F2821FCF65445B0339EB1087CA68431FB48C0443B4E687E10491C52B644BD272BB660C2C2B201DBB9A63180F1C7E1C9D02462CAF5D30399335F41D7D7858B2FCD50E24CDA3A24825185509528FB9ED24FEE1271558B3B33F187CDB9434065995DE270F4C6EAE42F816E83191AB243A7C16802E693A8976AD9AA2599942ED7526AB8321C6C2008484D93943B7DDC7B467CA71127790C6BAB91262D2A4C7AE4CCDE61ADEFDC0416CD595F13985FAD2AD92C1BD7B11493591EBCA89FFD9D447C4E280763DF3BDC3BCEBA91B56ED7E7460EE828C4940E8F85A9EFE5896554F72CB7F25DCC828DD46654F59CD1A776BFA6A1FF54BEC18262F645EF687765BBFF2FA27F57B0EE8452BB5C64F8B637D90C70AA65027A2479B38D8863523EF45A0E39B1B07425CC6053EA1336DEE6C341E4FFF1727035D9", "p": "EAB6300992FB73A2A9CA748F9388C19D2D385F1DD84E73E4E74DA71226896D00F38A6E719B9D53B21559600487A63E4BD98CDC9EC958BC2F8A224C43BAC8C5681B3FA899643472FDD6B8B113EDB372A4ED37BDCB142B3D3AB2A96B00AD8ED44FBD8EAEC0D00EC0BBC3920942D9952443E2930DA6B93A015C27F4B97C24F35CCEEE8622DDD4842B2BAB39A35007BC473A7FF4A8531FECBA08ACC7C8E5274B3CAF0ECC1EA29C6A63C2C99E7FB8140E5E85046F15275A80E750026AAB9E2FD70F6E4C2B5D091595F8517B07830788D97E1D3DBCDC6232762AE55C05F7808799F9B75448BBE4307ECD357EF009AD3D0264722B7D224D7C8A43DB70DE1D4B2549DC07", "q": "EAC1337FCE0C79B760B1448B1BFE59B12A349643D2C4B4CCA06AA13D57989D7BB0787D0622D0815E1E69DBAFE4FC6FD75111C071CF46ADA56E91AA77FB0E7992147282CCA036B853D67FA1B2E0F6A15E8D48A75F2F2B1174A6D3A137CEEE0CFEBC482B1C5835E0D6445D1CEC26C252043E7DE64C1EC0DDD2B1F5D62E96B1B18C5C68ED086722218071806115827A29073F0AAF6237A7EBF899402C79863F6C80A3DEE1BFF2606C7C209A557CDA516FB3CFE2599869E0E7DA236FD14A89EF9F01C5F38464F8D6CDBF2D0A66C50187351DFA4466B03DFBFC066308901F00EFC30EB806CEC1033B4FB72DF4C78449016ED98154F184419FF1FDB50237F10EDAA71F", "pq": "B5BFACCA2DE7E8ACDFC2869CB0E0BC6195F7C1D4ECF3F80489AB9C0A5ACC6119A366A3FF5A5402F6B14B1130786542819282F2F82C328EE66B465B698D26E769A5B9FE8F54145F30E413DAFF5E08DDE99E6CE147DC9C2B5330E8EF3D3B9F9E151CC408BC6F6201956D3B79B5E096DCE6221FAF75389F8F70A01AF9893901F65379460123E24242A3550E05C8ACCFC5FFDDE429811B9B2533E436C8B7DBF988DB842A09ECAEAC303B3965F6820A1F6F8CD31CDD095771460AD25416F54C0CEAFAD50AD2296DCC10BADA99AFB7FED0B0964F7D37FF8A31ABBFA78493BB42FD2B1D5FBF3A3808DC0CDEA291DBCEFAC0704C401E69C71BB643CA31DD7C554B81CA2F", "dp1": "122DD242AB93B63D1F11833DAB9BA8035881493CB2884109B5B09A0419E0030553D7A0FE43A347DC3F3310F0C8E0E36A548B487B33F51F7E3F20B0EF7E0416E61D562CE4D4920B6605BF80579ECD8B4FA2DFF25F4C4C9D0D72D1146C9504BF04FE15930B7411F0739A8E31117070D0C241464A84634C4ED6A87197FC39906FDBC735B475A2042AA3D33B3F9EEF3A71F9E1F73D225312AEC6053BE41F7B8FA43F9AD1CC7DA3C7C9BA488B7230FBBCB12D744E7640FA0D89DCF492F67FE60CAE3148CD0303B51C4C8363180DDA038B74ED26DEFDE2CD2DC1DCC9E7DC67A41914F25220E00CA884E9B7FF00F07EEE7EC4F0E2D56A56BE12A776D3A32079B585A6F9", "dq1": "2514BF7DC09E57DB8F7A70C94872B4D837427739DF6112EDFFA8D82F4856E30956A6B198F686D8E87505639E351D6ACD281115C4E468D5A4FC02265B2D5CEBF71723BF65732931948C9D3C7D74EB8031DF3F4AB0CE528F3F4DDABFEC80D3395A438362CBE7631B50BD1BB825D5397C9B0F03F40CB20EE4FB13013203C9E9E791B4471EA9E5208F0A2AE38C724959E28132840D90061A903B84798E8CE397C11BD0C6B4020DD70D4BCE1A92C655F5E71F100740FFC239B465D093290C0D1DBC901B248C1526F947269B86B9150558C61B261D07DB6EEF0EB0339476AF6F06705932D860703C8271E50D6D4CD6A8718180F9DCE109731440B542924723DCA4CD21" }././@LongLink00006440000000000000000000000154000000000000007773Lustar sequoia-keystore-backend-0.7.0/tests/data/keys/rsa-parameters/D8ED70A465EDBDDC9DBA54A6BD3F28C7C3F75B20.jsonsequoia-keystore-backend-0.7.0/tests/data/keys/rsa-parameters/D8ED70A465EDBDDC9DBA54A6BD3F28C7C3F75B000064400000000000000000000071321046102023000271260ustar 00000000000000{ "e": "010001", "n": "CE5B5E9C91C8F2E7C8F83514F0917A3A4788A4AA6AF59CF92C80565F406C2A72EB640AFE3D55CD14DE4E7287E679A8169BBF972F043DD1151A84352F433FF1AD7D54454ACA2C92F5560D11017BF8DBA9F38A7DF5AD9B1BB791E7FEF480032377556F209AF7420F6A9422A7886AB1DFEDE63DFEBAD4E2FE14A16BEE01601A489257F7111DF5CA8713B89DCDC1F6A3D86C21EA42CCE6F103F9D5334173934DAC73C773954AF5476B18711513E56A9639C28F65E563809C1FB890E218F66420E655DEF7803C34AAD86B59CDC20CD4277269E3690EFE37CFB45823DB89731D895CFF2A9C67A98ADFF11F17A8A4E083DCF149FE02477A4C86BA81B1150F1F9186DCA6433ED4D0633EE2F4B7037EA4D87FDA34C8C8583BC86E9034C13615C9F1466872D595CDE41788E26837CB99A5627D0F0A27610C130A8D0B7D14B9C9BE01F7E183E91E7AE4EC32C3E475348E097A1669658819D4E6A84CD67142D2CD25C10540F6816B8BA4305F2ED55C90B72548722F504CD1A2DCA8F8E8D7B953181331489FBBF3E8FB88F8315E3F1642B182E6AB0C31ECCEAD61BD967BB9CC8BAB45069DC7526678FB11B30BACC9A4A1C00DFDBC7B8A4F0C2ABE27B774B4D04038F85FD3D32CCC5E1ACDF4B38D4B4DFC5FA6E714523D2FDDF0CA7265A0FDF6C5BD19EBABE84AE439C258BC45683DBCCC06DA750FCD10953975A5AFCF8D9C756E842DE1E7B697", "p": "E59C713EF0FB932CAAA80B3D61C3652A2E6327409292C92890ABA5AC9DDA262CE318B8DFB9A8672EC003B97D3DF1BAC3CC1E8773B95A559A5FA584FC06355F5259E282AE6FA4113A22FF9E9E47C90190CE58A0DF3274EFAD3CB2A2C574993A8579D24C00F3EF9632F22C0A75F5DF1DB94E2CA9B18D0169A87DB4AE0A6BCEF4E7EAA8B31DF27D75A2C8ABA54FA7E0611B54D6AFCA3EEB44ADAE9BBAA6AF94628EFC49DA68B24D9F3C74379AD2D2969054F0501703F38BDDAE14318D1327484DEA4B231291E64AF161F603FF346B3C7709026F3E009FCA1966170A29DF9FE5B3385D8F6D9295E361CAAA0CB8BB74D21EA2EEC8D3CF0F8F63F4F8BB275FC65A41AD", "q": "E612BF9EB22BDF5A1A5EED23821AADDFA4AFFEBDEFE8CFAD75FD01552BF57BE3FD2C027566DCE0398AECE4B03922FEE0A85263B0BA798DE15BBD3CE6F0F7B932BC728964750705DC9E3E078ACC394AC7CAAFC931B0EB50BC7BD864AE6EEF3A7F59752F7F931168EF3A715EB86E089D20F4BD9C2D40C7DB48F2D2E1BC32E8541B9D5917E12628E252CABBA15A40385F75D914B1FEE579C18AA17D5A5697D2F5C879C7D7F89102A04A94CB5C92102FE9749E18A452CA93E69FFB673F15B7955AD075F222C2F3F1381E0C44440AE4672D0B5586BDD3FF44DFA183A7813EDB84B34DA14E4CE76F8C1BDD5EDF1DBC3A622BF3C438D109B488C2BBA6A3BB7CB19689D3", "pq": "789DE016473EE1206364CAE1822424D5EB6B905AA5911AEDE5CCFCF432057BE87807A56881E12D12752C936B488D0D4CED8F207C7D5663C778C4F3DF2498A5997F9BDEFF1EC8A27DE20391194903415BF17B813BDD1C43E22F9F3821081824C05B72BCD2F2D82A6789CA339B0CB11BB3C1FFCCA5C04EED56B88ED1E994C419DCF90B5604F76EF3BF87FABE2EE15F57C4E01F1CF845CDEF5B43AD41A161427CA4B9F4D4731870F4969F77CFD27F359938620844577672EFF85C49B34369D73C795C70D6BFEF28F62802CBCA439DD9C21DA9063E7977417E333F5A6283B8A801F131B1310FDEDE011A7CD2459E394C17DE85B1B36D4D8656D684231B6A5559DCE1", "dp1": "C16B6ABE51B42B035A731A9CC78918E452953610A028448A066C81B08A7CA4E1F51FF3448B99FFE992D8D05D5F5C0D2F38F892B3FA74CD5DB0AAB6FEB2A02D3F2AF6B38D0C00927E7DD305246266420A60B8AA33BAC664CC73302C0BD7AFE86B5DF6B80DA96FAF00159EE1E5028CC3F6409341138F2B9C7CD1FFED085C4EC761C1FC007EFEB18EF1E4C72B0791EC6300EA13BB9BCC2AD5FCD4F4DC63E3CE44C41C647E36E9D4978A0E8074CC999739D84363C42F90EEC67C0908C0C55CB6FCE39C0DDC6BC92A62725A127DDE0363B9067EE584BE73DC844ECAA3C6285A02DE5961FF1B977AEA438BBC79E0F8106D9C5F3675386FD9B4B9C837EB383CE6D34B35", "dq1": "DAB3D3C72D231B4BF1696F0EA3EC6C7FFD72F73AE24572B537456BF0E4BA942C634B6482E966E9168A032A5881D7CC650E5C533B79E7768154CD8C891362C87F7C377C772BEFA318D6ABAC4BBA5A73C57BDCA1EA447D4BDFFFF1F1B306ED0DB464FB4A4D8125B9943EFFE9C4738468A91D3CE8AAF3BB87ADCE75BBF3448928FA9F1643E6D87960BAC6D0994ECB614B0D216FD4CBB2A38CE11525ADAC46E258955B7E26C4B843C0CF64A5F3B73CFFEE71D69F2205396062888D58D5D4F5105AA57298DB866A915080EFB42CE215C0264771E385AB722AAC52426E062414540E85AAE25DA45A9ADB1A11C711E30DB4A8872E6DBBF7F7CF511D4408BC7E89E9C9D5" }sequoia-keystore-backend-0.7.0/tests/data/messages/bob.asc000064400000000000000000000012671046102023000216500ustar 00000000000000-----BEGIN PGP MESSAGE----- hQGMAwpLoiSRaNd5AQwAnoTHj0yfu/ucS+6PLqfvKvarcUzjb+oYq+wqBSKwug9Q ej8mim+yzNmJlZ7GSIISxc5hLU7hlaKvI/rjQ3MkxyA4BLXa+NAg4wdQNXnMZvYM BqtLLY26eZTrEECgu+1ksmTN7XPS/8h0rtuLGsmEZ9bMk1VA9ktMa3/LBhLrPnwK 4Ljxyl1RKaFKEBjhRTHX6KA0sXJZlDgh266feSfXo76WOUfmp5lCuliD0aWA3rDL bVOJxL0XWRMdnZNWrjIsBRGBOk8QoMo5h59S+YGKTZQ5hwWfDoegeiInWKtfQ39i AgKOlbdOL7p35BZmmmTswIX5eHmcLiR5YV8k/ZRGo7QpmhUVh1lIR/7p5aKM0tK2 z+e80Bem+lpHgmObR+IaWBBh46MaOT3BQo+4wEnIvMneySupN60t95GJpUXJf8VQ QL7YmXVKdkH9LmH8LUZkxfaFpTKaDpTG1wkq3MukPhRqP9RiCiKAucalkDxC9QUQ uKmHRliJ5JVvAmQHRQ0w0kIBjeAmbLB/1hp26pcT73AVja33Mth5cBeGRVcex9KH NNifUCA8JEMliRnNf3yQL3HizybkTSGUkeDF83LnjWwVMvE= =mqlq -----END PGP MESSAGE----- sequoia-keystore-backend-0.7.0/tests/data/messages/no-password.asc000064400000000000000000000015221046102023000233540ustar 00000000000000-----BEGIN PGP MESSAGE----- wcFMA6pb+sHkoSGgAQ/+Pj9nv8NDWz7siwx95WdGvyrW90ax4No38UkJ0nREiM1M LnC3LN3jIpht0G08f3SpVhq8PzNRhLtPfVWY1g3ZQ2VYm2f0W1qi1rN68XeVomqy 0hohol1XgIOPqsva0z9as3mBQNBHeyomBMAjs6HEeULoUqugQsNotUZ40ptjEpOS rmQJR+m1+cE69e8ZN2EVjWtLB4bXvArGeBkVR+J1PqLQQL4KrzYsNl/ymrh2UlzO +A5hplU5MOc7xqSamfWN4rihazIfxuwwLMlAX7mtdxCOPc41q0QAdIJk9qkWnMpw TihfuVsLbi3WTAtivNDrkwI7qtRpQapg5xTE/KfteLFMJI9m4A7OrbbuVm4EBrin /asMOue/kcVB3l+wzE0rbKxajxdWhd04ifWDdLVrH+zY4gqOwxxXrA+Dvhxp/zIU R+efnsH2iOhUDCKgJRhrIVWOk/7IU1E8G3yqWmTjqbP69AppMyOjEpxYQxS9lxQV rtZOEIRW27jkAVp2bfIGHE8pK8npjSxprglBtgOhUabCOHmjcCfjnwzefccgByxL 10RQu4IqZsrgHeaLdp10D/hUxip28lehguXV54oL86aoF2c6SHatbhPJWx9Ovgsp Rqak5QXQXsmkAar0H8LCYkGFuTOkJlF965ci2MfHxqXFNzdRBeUKbWuKWmywMInS NQGWsHJoVm3S6Y7fsZ4Y/pSO/M8udD4GfzUaxbavLhBkW0TbAzvX5vM0RayhTJXa lrIR8Qcl =T3iI -----END PGP MESSAGE-----