Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Backports:SLE-15-SP4:FactoryCandidates
wardstone
wardstone-0.2.0~0.obscpio
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File wardstone-0.2.0~0.obscpio of Package wardstone
07070100000000000081A40000000000000000000000016537CEF40000007E000000000000000000000000000000000000002100000000wardstone-0.2.0~0/.gitattributes*.der filter=lfs diff=lfs merge=lfs -text *.pem filter=lfs diff=lfs merge=lfs -text *.pub filter=lfs diff=lfs merge=lfs -text 07070100000001000041ED0000000000000000000000026537CEF400000000000000000000000000000000000000000000001A00000000wardstone-0.2.0~0/.github07070100000002000041ED0000000000000000000000026537CEF400000000000000000000000000000000000000000000002900000000wardstone-0.2.0~0/.github/ISSUE_TEMPLATE07070100000003000081A40000000000000000000000016537CEF40000022F000000000000000000000000000000000000003700000000wardstone-0.2.0~0/.github/ISSUE_TEMPLATE/bug_report.md--- name: Bug report about: Create a report to help us improve title: 'fix: ' labels: '' assignees: '' --- **Describe the bug** A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior: 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' 4. See error **Expected behavior** A clear and concise description of what you expected to happen. **Screenshots** If applicable, add screenshots or terminal output to help explain your problem. **Additional context** Add any other context about the problem here. 07070100000004000081A40000000000000000000000016537CEF400000259000000000000000000000000000000000000003C00000000wardstone-0.2.0~0/.github/ISSUE_TEMPLATE/feature_request.md--- name: Feature request about: Suggest an idea for this project title: 'feat: ' labels: '' assignees: '' --- **Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] **Describe the solution you'd like** A clear and concise description of what you want to happen. **Describe alternatives you've considered** A clear and concise description of any alternative solutions or features you've considered. **Additional context** Add any other context or screenshots about the feature request here. 07070100000005000081A40000000000000000000000016537CEF4000000CB000000000000000000000000000000000000002900000000wardstone-0.2.0~0/.github/dependabot.ymlversion: 2 updates: - package-ecosystem: cargo directory: "/" schedule: interval: "weekly" - package-ecosystem: github-actions directory: "/" schedule: interval: "weekly" 07070100000006000041ED0000000000000000000000026537CEF400000000000000000000000000000000000000000000002400000000wardstone-0.2.0~0/.github/workflows07070100000007000081A40000000000000000000000016537CEF4000006D7000000000000000000000000000000000000002C00000000wardstone-0.2.0~0/.github/workflows/ci.yamlname: ci on: [pull_request, push] permissions: contents: read env: CARGO_TERM_COLOR: always jobs: check: name: Run cargo-check runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable - run: cargo check clippy: name: Run Clippy runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable with: components: clippy - run: cargo clippy -- --deny warnings docs: name: Build package documentation runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable - run: cargo doc --no-deps rustfmt: name: Check formatting runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable with: components: rustfmt - run: cargo fmt --all --check test: name: Run tests runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable - run: cargo test --all-features ffi: name: Check FFI build runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - name: Install Rust toolchain uses: dtolnay/rust-toolchain@stable - name: Generate header and build static library run: cargo build --release --all-features - name: Build FFI example working-directory: ./examples/ffi/ run: | cc -I ../../target/ ./main.c ../../target/release/libwardstone.a \ -o ../../target/release/ffi_example - name: Run FFI example run: ./target/release/ffi_example 07070100000008000081A40000000000000000000000016537CEF400000024000000000000000000000000000000000000001D00000000wardstone-0.2.0~0/.gitignore/target # Test private keys. keys/ 07070100000009000081A40000000000000000000000016537CEF4000005E3000000000000000000000000000000000000002200000000wardstone-0.2.0~0/CONTRIBUTING.md# Guidelines ## General Building the source code can be done with `cargo`. Having OpenSSL installed on your system may also be required but that comes bundled with most Unix operating systems. [Test certificates](./crates/cmd/src/testing/certificates/) are stored using [Git Large File Storage](https://git-lfs.com) so that might be required if you're going to be interacting with any of those. ## Contributing Test Cases for Validating X.509 Certificates The easiest way to contribute test cases is to run the Python [`generate_certificates.py`](./scripts/generate_certificates.py) script and file a pull request with the changes if it was able to generate new test certificates that were not already [present in the repository](./crates/cmd/src/testing/certificates/). Additionally, run the following command where the input is the newly generated certificate. The error message will contain an object identifier which will be used to identify the primitives used in the certificate where `$new_certificate` represents the newly generated certificate. ```bash wardstone x509 --guide bsi --path ./crates/cmd/src/testing/certificates/$new_certificate ``` This should be enough but if you want to go further, you can lookup the object identifier in a registry such as the [Object Identifier (OID) Repository](https://oid-rep.orange-labs.fr) and update the tables in [`certificate.rs`](./crates/cmd/src/key/certificate.rs) along with the instances in the [`core`](./crates/core/src/primitive/) crate. 0707010000000A000081A40000000000000000000000016537CEF400006062000000000000000000000000000000000000001D00000000wardstone-0.2.0~0/Cargo.lock# This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 3 [[package]] name = "anstream" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", "utf8parse", ] [[package]] name = "anstyle" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "15c4c2c83f81532e5845a733998b6971faca23490340a418e9b72a3ec9de12ea" [[package]] name = "anstyle-parse" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" dependencies = [ "windows-sys", ] [[package]] name = "anstyle-wincon" version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" dependencies = [ "anstyle", "windows-sys", ] [[package]] name = "asn1-rs" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" dependencies = [ "asn1-rs-derive", "asn1-rs-impl", "displaydoc", "nom", "num-traits", "rusticata-macros", "thiserror", "time", ] [[package]] name = "asn1-rs-derive" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" dependencies = [ "proc-macro2", "quote", "syn 1.0.109", "synstructure", ] [[package]] name = "asn1-rs-impl" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" dependencies = [ "proc-macro2", "quote", "syn 1.0.109", ] [[package]] name = "atty" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi", "libc", "winapi", ] [[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "base64" version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53" [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" [[package]] name = "block-buffer" version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] [[package]] name = "byteorder" version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "cbindgen" version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da6bc11b07529f16944307272d5bd9b22530bc7d05751717c9d416586cedab49" dependencies = [ "clap 3.2.25", "heck", "indexmap", "log", "proc-macro2", "quote", "serde", "serde_json", "syn 1.0.109", "tempfile", "toml", ] [[package]] name = "cc" version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ "libc", ] [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" version = "3.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" dependencies = [ "atty", "bitflags 1.3.2", "clap_lex 0.2.4", "indexmap", "strsim", "termcolor", "textwrap", ] [[package]] name = "clap" version = "4.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956" dependencies = [ "clap_builder", "clap_derive", ] [[package]] name = "clap_builder" version = "4.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45" dependencies = [ "anstream", "anstyle", "clap_lex 0.5.1", "strsim", ] [[package]] name = "clap_derive" version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" dependencies = [ "heck", "proc-macro2", "quote", "syn 2.0.29", ] [[package]] name = "clap_lex" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" dependencies = [ "os_str_bytes", ] [[package]] name = "clap_lex" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" [[package]] name = "colorchoice" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "cpufeatures" version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" dependencies = [ "libc", ] [[package]] name = "crypto-common" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", "typenum", ] [[package]] name = "data-encoding" version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "der-parser" version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e" dependencies = [ "asn1-rs", "displaydoc", "nom", "num-bigint", "num-traits", "rusticata-macros", ] [[package]] name = "deranged" version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" [[package]] name = "digest" version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", "crypto-common", ] [[package]] name = "displaydoc" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", "syn 2.0.29", ] [[package]] name = "errno" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" dependencies = [ "errno-dragonfly", "libc", "windows-sys", ] [[package]] name = "errno-dragonfly" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" dependencies = [ "cc", "libc", ] [[package]] name = "fastrand" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" [[package]] name = "foreign-types" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" dependencies = [ "foreign-types-shared", ] [[package]] name = "foreign-types-shared" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "generic-array" version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", ] [[package]] name = "hashbrown" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "heck" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ "libc", ] [[package]] name = "indexmap" version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown", ] [[package]] name = "itoa" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" [[package]] name = "linux-raw-sys" version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" [[package]] name = "log" version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "md-5" version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" dependencies = [ "digest", ] [[package]] name = "memchr" version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76fc44e2588d5b436dbc3c6cf62aef290f90dab6235744a93dfe1cc18f451e2c" [[package]] name = "minimal-lexical" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[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" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" dependencies = [ "autocfg", "num-integer", "num-traits", ] [[package]] name = "num-integer" version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" dependencies = [ "autocfg", "num-traits", ] [[package]] name = "num-traits" version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", ] [[package]] name = "oid-registry" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" dependencies = [ "asn1-rs", ] [[package]] name = "once_cell" version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "openssh-keys" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c75a0ec2d1b302412fb503224289325fcc0e44600176864804c7211b055cfd58" dependencies = [ "base64", "byteorder", "md-5", "sha2", "thiserror", ] [[package]] name = "openssl" version = "0.10.57" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" dependencies = [ "bitflags 2.4.0", "cfg-if", "foreign-types", "libc", "once_cell", "openssl-macros", "openssl-sys", ] [[package]] name = "openssl-macros" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", "syn 2.0.29", ] [[package]] name = "openssl-sys" version = "0.9.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db7e971c2c2bba161b2d2fdf37080177eff520b3bc044787c7f1f5f9e78d869b" dependencies = [ "cc", "libc", "pkg-config", "vcpkg", ] [[package]] name = "os_str_bytes" version = "6.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d5d9eb14b174ee9aa2ef96dc2b94637a2d4b6e7cb873c7e171f0c20c6cf3eac" [[package]] name = "pkg-config" version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "proc-macro2" version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] [[package]] name = "quote" version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] [[package]] name = "redox_syscall" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ "bitflags 1.3.2", ] [[package]] name = "rusticata-macros" version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" dependencies = [ "nom", ] [[package]] name = "rustix" version = "0.38.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "745ecfa778e66b2b63c88a61cb36e0eea109e803b0b86bf9879fbc77c70e86ed" dependencies = [ "bitflags 2.4.0", "errno", "libc", "linux-raw-sys", "windows-sys", ] [[package]] name = "ryu" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "serde" version = "1.0.189" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" version = "1.0.189" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" dependencies = [ "proc-macro2", "quote", "syn 2.0.29", ] [[package]] name = "serde_json" version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" dependencies = [ "itoa", "ryu", "serde", ] [[package]] name = "sha2" version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" dependencies = [ "cfg-if", "cpufeatures", "digest", ] [[package]] name = "strsim" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "syn" version = "2.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "synstructure" version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ "proc-macro2", "quote", "syn 1.0.109", "unicode-xid", ] [[package]] name = "tempfile" version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" dependencies = [ "cfg-if", "fastrand", "redox_syscall", "rustix", "windows-sys", ] [[package]] name = "termcolor" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" dependencies = [ "winapi-util", ] [[package]] name = "textwrap" version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] name = "thiserror" version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97a802ec30afc17eee47b2855fc72e0c4cd62be9b4efe6591edde0ec5bd68d8f" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b" dependencies = [ "proc-macro2", "quote", "syn 2.0.29", ] [[package]] name = "time" version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" dependencies = [ "deranged", "itoa", "serde", "time-core", "time-macros", ] [[package]] name = "time-core" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572" dependencies = [ "time-core", ] [[package]] name = "toml" version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" dependencies = [ "serde", ] [[package]] name = "typenum" version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "unicode-ident" version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" [[package]] name = "unicode-xid" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "utf8parse" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[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.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "wardstone" version = "0.2.0" dependencies = [ "clap 4.4.6", "once_cell", "openssh-keys", "openssl", "serde", "serde_json", "wardstone_core", "x509-parser", ] [[package]] name = "wardstone_core" version = "0.2.0" dependencies = [ "once_cell", "serde", ] [[package]] name = "wardstone_ffi" version = "0.2.0" dependencies = [ "cbindgen", "wardstone_core", ] [[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.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ "winapi", ] [[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-sys" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ "windows-targets", ] [[package]] name = "windows-targets" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", "windows_i686_msvc", "windows_x86_64_gnu", "windows_x86_64_gnullvm", "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "x509-parser" version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7069fba5b66b9193bd2c5d3d4ff12b839118f6bcbef5328efafafb5395cf63da" dependencies = [ "asn1-rs", "data-encoding", "der-parser", "lazy_static", "nom", "oid-registry", "rusticata-macros", "thiserror", "time", ] 0707010000000B000081A40000000000000000000000016537CEF40000005A000000000000000000000000000000000000001D00000000wardstone-0.2.0~0/Cargo.toml[workspace] resolver = "2" members = [ "crates/cmd", "crates/core", "crates/ffi", ] 0707010000000C000081A40000000000000000000000016537CEF4000002EC000000000000000000000000000000000000001A00000000wardstone-0.2.0~0/LICENCEISC License Copyright (c) 2023 Tshaka Lekholoane Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 0707010000000D000081A40000000000000000000000016537CEF40000047D000000000000000000000000000000000000001C00000000wardstone-0.2.0~0/README.md# `wardstone` ![Continuous Integration](https://github.com/tshakalekholoane/wardstone/actions/workflows/ci.yaml/badge.svg) The `wardstone` project aims to create a library that can be used across different programming languages via a foreign function interface and a command line utility that users can run against their existing keys to detect conformance to varying cryptographic key standards and research publications. The repository is organised as a series of the following Rust crates: - [**`wardstone`**](./crates/cmd/). A command-line application that checks cryptographic keys for compliance. - [**`wardstone_core`**](./crates/core/). A Rust library that curates compliance information for cryptographic keys from varying standards bodies and research groups. - [**`wardstone_ffi`**](./crates/ffi/). A version of [`wardstone_core`](./crates/core/) that exports a foreign function interface for using the library from C and other languages that support it. This is a [Google Summer of Code project](https://summerofcode.withgoogle.com/programs/2023/projects/QjOBHrdT) with [openSUSE](https://github.com/openSUSE/mentoring/issues/198). 0707010000000E000041ED0000000000000000000000026537CEF400000000000000000000000000000000000000000000001900000000wardstone-0.2.0~0/crates0707010000000F000041ED0000000000000000000000026537CEF400000000000000000000000000000000000000000000001D00000000wardstone-0.2.0~0/crates/cmd07070100000010000081A40000000000000000000000016537CEF400000314000000000000000000000000000000000000002800000000wardstone-0.2.0~0/crates/cmd/Cargo.toml[package] name = "wardstone" version = "0.2.0" authors = [ "Dennis Knorr", "Martin Sirringhaus", "Tshaka Lekholoane <mail+cargo@tshaka.dev>", ] description = """ A tool to scan cryptographic keys and certificates against recognized standards and research publications, verifying their compliance. """ edition = "2021" keywords = ["compliance", "security", "ssh", "tls", "x509"] license = "ISC" readme = "README.md" categories = [ "command-line-utilities", "config", "cryptography", "development-tools", ] [dependencies] clap = { version = "4.4", features = ["derive"] } once_cell = "1.18" openssh-keys = "0.6" openssl = "0.10" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" wardstone_core = { path = "../core" } x509-parser = "0.15" [lib] doc = false 07070100000011000081A40000000000000000000000016537CEF4000003A7000000000000000000000000000000000000002700000000wardstone-0.2.0~0/crates/cmd/README.md# `wardstone` A tool to scan cryptographic keys and certificates against recognized standards and research publications, verifying their compliance. ``` A tool to scan cryptographic keys and certificates against recognized standards and research publications, verifying their compliance. Usage: wardstone <COMMAND> Commands: ssh Check an SSH public key for compliance x509 Check an X.509 public key certificate for compliance help Print this message or the help of the given subcommand(s) Options: -h, --help Print help -V, --version Print version ``` ## Installation ### Building from Source This can be done using `cargo` and the resulting binary will be located in the root directory's `target/release/` folder. ```shell cargo build --release ``` On some operating systems you may need to download the development branch of the OpenSSL library i.e., `libssl-dev` on Ubuntu or `openssl-dev` on Fedora. 07070100000012000041ED0000000000000000000000026537CEF400000000000000000000000000000000000000000000002100000000wardstone-0.2.0~0/crates/cmd/src07070100000013000041ED0000000000000000000000026537CEF400000000000000000000000000000000000000000000002500000000wardstone-0.2.0~0/crates/cmd/src/key07070100000014000081A40000000000000000000000016537CEF4000008A1000000000000000000000000000000000000002800000000wardstone-0.2.0~0/crates/cmd/src/key.rs//! Key types supported by the application. use std::path::Path; use std::{fmt, io}; use openssh_keys::errors::OpenSSHKeyError; use openssl::error::ErrorStack; use wardstone_core::primitive::asymmetric::Asymmetric; use wardstone_core::primitive::hash::Hash; use x509_parser::nom::Err as NomError; use x509_parser::prelude::{PEMError, X509Error}; pub mod certificate; pub mod ssh; /// Represents a cryptographic key. pub trait Key { fn from_file(path: &Path) -> Result<Self, Error> where Self: Sized; fn hash_function(&self) -> Option<Hash>; fn signature_algorithm(&self) -> Asymmetric; } /// Represents an error that could arise as a result of reading a key or /// parsing its contents. #[derive(Debug)] pub enum Error { Io(io::Error), ParsePEM(NomError<PEMError>), ParseSsh(OpenSSHKeyError), ParseX509(ErrorStack), ParseX509Certificate(NomError<X509Error>), Unrecognised(String), } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Error::Io(err) => match err.kind() { io::ErrorKind::NotFound => write!(f, "Key not found."), io::ErrorKind::PermissionDenied => write!(f, "Permission denied."), _ => write!(f, "Unexpected error. Please file an issue."), }, Error::ParsePEM(_) => write!(f, "Cannot parse PEM file."), Error::ParseSsh(_) => write!(f, "Cannot parse SSH public key."), Error::ParseX509Certificate(_) | Error::ParseX509(_) => { write!(f, "Cannot parse X.509 certificate.") }, Error::Unrecognised(oid) => write!(f, "Unrecognised key: {}. Please file an issue.", oid), } } } impl From<io::Error> for Error { fn from(err: io::Error) -> Self { Self::Io(err) } } impl From<NomError<PEMError>> for Error { fn from(err: NomError<PEMError>) -> Self { Self::ParsePEM(err) } } impl From<ErrorStack> for Error { fn from(err: ErrorStack) -> Self { Self::ParseX509(err) } } impl From<NomError<X509Error>> for Error { fn from(err: NomError<X509Error>) -> Self { Self::ParseX509Certificate(err) } } impl From<OpenSSHKeyError> for Error { fn from(err: OpenSSHKeyError) -> Self { Self::ParseSsh(err) } } 07070100000015000081A40000000000000000000000016537CEF400002882000000000000000000000000000000000000003400000000wardstone-0.2.0~0/crates/cmd/src/key/certificate.rs//! Create X.509 certificate representations and perform actions on //! them. use std::collections::HashMap; use std::fs::File; use std::io::Read; use std::path::Path; use once_cell::sync::Lazy; use openssl::x509::X509; use wardstone_core::primitive::asymmetric::Asymmetric; use wardstone_core::primitive::ecc::*; use wardstone_core::primitive::hash::*; use wardstone_core::primitive::ifc::*; use x509_parser::pem; use x509_parser::prelude::{FromDer, TbsCertificate, X509Certificate}; use crate::key::{Error, Key}; static ASYMMETRIC: Lazy<HashMap<&str, Asymmetric>> = Lazy::new(|| { let mut m = HashMap::new(); m.insert("1.2.840.10045.3.0.1", C2PNB163V1.into()); m.insert("1.2.840.10045.3.0.10", C2PNB208W1.into()); m.insert("1.2.840.10045.3.0.11", C2TNB239V1.into()); m.insert("1.2.840.10045.3.0.12", C2TNB239V2.into()); m.insert("1.2.840.10045.3.0.13", C2TNB239V3.into()); m.insert("1.2.840.10045.3.0.16", C2PNB272W1.into()); m.insert("1.2.840.10045.3.0.17", C2PNB304W1.into()); m.insert("1.2.840.10045.3.0.18", C2TNB359V1.into()); m.insert("1.2.840.10045.3.0.19", C2PNB368W1.into()); m.insert("1.2.840.10045.3.0.2", C2PNB163V2.into()); m.insert("1.2.840.10045.3.0.20", C2TNB431R1.into()); m.insert("1.2.840.10045.3.0.3", C2PNB163V3.into()); m.insert("1.2.840.10045.3.0.4", C2PNB176V1.into()); m.insert("1.2.840.10045.3.0.5", C2TNB191V1.into()); m.insert("1.2.840.10045.3.0.6", C2TNB191V2.into()); m.insert("1.2.840.10045.3.0.7", C2TNB191V3.into()); m.insert("1.2.840.10045.3.1.1", PRIME192V1.into()); m.insert("1.2.840.10045.3.1.2", PRIME192V2.into()); m.insert("1.2.840.10045.3.1.3", PRIME192V3.into()); m.insert("1.2.840.10045.3.1.4", PRIME239V1.into()); m.insert("1.2.840.10045.3.1.5", PRIME239V2.into()); m.insert("1.2.840.10045.3.1.6", PRIME239V3.into()); m.insert("1.2.840.10045.3.1.7", PRIME256V1.into()); m.insert("1.3.132.0.1", SECT163K1.into()); m.insert("1.3.132.0.10", SECP256K1.into()); m.insert("1.3.132.0.15", SECT163R2.into()); m.insert("1.3.132.0.16", SECT283K1.into()); m.insert("1.3.132.0.17", SECT283R1.into()); m.insert("1.3.132.0.2", SECT163R1.into()); m.insert("1.3.132.0.22", SECT131R1.into()); m.insert("1.3.132.0.23", SECT131R2.into()); m.insert("1.3.132.0.24", SECT193R1.into()); m.insert("1.3.132.0.25", SECT193R2.into()); m.insert("1.3.132.0.26", SECT233K1.into()); m.insert("1.3.132.0.27", SECT233R1.into()); m.insert("1.3.132.0.28", SECP128R1.into()); m.insert("1.3.132.0.29", SECP128R2.into()); m.insert("1.3.132.0.3", SECT239K1.into()); m.insert("1.3.132.0.30", SECP160R2.into()); m.insert("1.3.132.0.31", SECP192K1.into()); m.insert("1.3.132.0.32", SECP224K1.into()); m.insert("1.3.132.0.33", SECP224R1.into()); m.insert("1.3.132.0.34", SECP384R1.into()); m.insert("1.3.132.0.35", SECP521R1.into()); m.insert("1.3.132.0.36", SECT409K1.into()); m.insert("1.3.132.0.37", SECT409R1.into()); m.insert("1.3.132.0.38", SECT571K1.into()); m.insert("1.3.132.0.39", SECT571R1.into()); m.insert("1.3.132.0.4", SECT113R1.into()); m.insert("1.3.132.0.5", SECT113R2.into()); m.insert("1.3.132.0.6", SECP112R1.into()); m.insert("1.3.132.0.7", SECP112R2.into()); m.insert("1.3.132.0.8", SECP160R1.into()); m.insert("1.3.132.0.9", SECP160K1.into()); m.insert("1.3.36.3.3.2.8.1.1.1", BRAINPOOLP160R1.into()); m.insert("1.3.36.3.3.2.8.1.1.10", BRAINPOOLP320T1.into()); m.insert("1.3.36.3.3.2.8.1.1.11", BRAINPOOLP384R1.into()); m.insert("1.3.36.3.3.2.8.1.1.12", BRAINPOOLP384T1.into()); m.insert("1.3.36.3.3.2.8.1.1.13", BRAINPOOLP512R1.into()); m.insert("1.3.36.3.3.2.8.1.1.14", BRAINPOOLP512T1.into()); m.insert("1.3.36.3.3.2.8.1.1.2", BRAINPOOLP160T1.into()); m.insert("1.3.36.3.3.2.8.1.1.3", BRAINPOOLP192R1.into()); m.insert("1.3.36.3.3.2.8.1.1.4", BRAINPOOLP192T1.into()); m.insert("1.3.36.3.3.2.8.1.1.5", BRAINPOOLP224R1.into()); m.insert("1.3.36.3.3.2.8.1.1.6", BRAINPOOLP224T1.into()); m.insert("1.3.36.3.3.2.8.1.1.7", BRAINPOOLP256R1.into()); m.insert("1.3.36.3.3.2.8.1.1.8", BRAINPOOLP256T1.into()); m.insert("1.3.36.3.3.2.8.1.1.9", BRAINPOOLP320R1.into()); m.insert("1.2.156.10197.1.301", SM2.into()); m.insert("2.23.43.1.4.12", WAP_WSG_IDM_ECID_WTLS11.into()); m.insert("2.23.43.1.4.1", WAP_WSG_IDM_ECID_WTLS1.into()); m.insert("2.23.43.1.4.3", WAP_WSG_IDM_ECID_WTLS3.into()); m.insert("2.23.43.1.4.4", WAP_WSG_IDM_ECID_WTLS4.into()); m.insert("2.23.43.1.4.5", WAP_WSG_IDM_ECID_WTLS5.into()); m.insert("2.23.43.1.4.6", WAP_WSG_IDM_ECID_WTLS6.into()); m.insert("2.23.43.1.4.7", WAP_WSG_IDM_ECID_WTLS7.into()); m.insert("2.23.43.1.4.8", WAP_WSG_IDM_ECID_WTLS8.into()); m.insert("2.23.43.1.4.9", WAP_WSG_IDM_ECID_WTLS9.into()); m.insert("2.23.43.1.4.10", WAP_WSG_IDM_ECID_WTLS10.into()); m.insert("2.23.43.1.4.11", WAP_WSG_IDM_ECID_WTLS11.into()); m.insert("2.23.43.1.4.12", WAP_WSG_IDM_ECID_WTLS12.into()); m }); /// Represents a TLS certificate. #[derive(Debug)] pub struct Certificate { hash_function: Option<Hash>, signature_algorithm: Asymmetric, } impl Certificate { fn is_likely_pem(data: &[u8]) -> bool { !matches!((data[0], data[1]), (0x30, 0x81..=0x83)) } fn edsa_with_sha(tbs_certificate: &TbsCertificate, sha: Hash) -> Result<Certificate, Error> { let hash_function = Some(sha); let parameters = tbs_certificate .subject_pki .algorithm .parameters .as_ref() .expect("elliptic curve should specify curve"); let oid = parameters .clone() .oid() .expect("elliptic curve should have identifier") .to_id_string(); let signature_algorithm = ASYMMETRIC .get(&oid.as_str()) .cloned() .ok_or(Error::Unrecognised(oid))?; let certificate = Self { hash_function, signature_algorithm, }; Ok(certificate) } fn id_ed25519() -> Result<Certificate, Error> { let certificate = Self { hash_function: None, signature_algorithm: ED25519.into(), }; Ok(certificate) } fn id_ed448() -> Result<Certificate, Error> { let certificate = Self { hash_function: None, signature_algorithm: ED448.into(), }; Ok(certificate) } fn rsassa_pss(data: &[u8]) -> Result<Certificate, Error> { // The x509_parser crate cannot seem to read rsassa-pss keys so // resort to openssl for that. But even that cannot seem to // extract the hash function so a lower level interface may be // required. let certificate = if Self::is_likely_pem(data) { X509::from_pem(data)? } else { X509::from_der(data)? }; let public_key = certificate.public_key()?; let k = public_key.bits(); let signature_algorithm = match k { 1024 => RSA_PSS_1024.into(), 1536 => RSA_PSS_1536.into(), 2048 => RSA_PSS_2048.into(), 3072 => RSA_PSS_3072.into(), 4096 => RSA_PSS_4096.into(), 7680 => RSA_PSS_7680.into(), 8192 => RSA_PSS_8192.into(), 15360 => RSA_PSS_15360.into(), _ => Ifc::new(ID_RSA_PSS, k as u16).into(), }; let certificate = Self { hash_function: None, signature_algorithm, }; Ok(certificate) } fn with_rsa_encryption( tbs_certificate: &TbsCertificate, sha: Hash, ) -> Result<Certificate, Error> { let hash_function = Some(sha); let k = tbs_certificate .subject_pki .parsed() .expect("should parse rsa public key") .key_size(); let signature_algorithm = match k { 1024 => RSA_PKCS1_1024.into(), 1536 => RSA_PKCS1_1536.into(), 2048 => RSA_PKCS1_2048.into(), 3072 => RSA_PKCS1_3072.into(), 4096 => RSA_PKCS1_4096.into(), 7680 => RSA_PKCS1_7680.into(), 8192 => RSA_PKCS1_8192.into(), 15360 => RSA_PKCS1_15360.into(), _ => Ifc::new(ID_RSA_PKCS1, k as u16).into(), }; let certificate = Self { hash_function, signature_algorithm, }; Ok(certificate) } } impl Key for Certificate { fn from_file(path: &Path) -> Result<Certificate, Error> { let mut file = File::open(path)?; let mut data = Vec::new(); file.read_to_end(&mut data)?; // Certificates do not own their data. let pem; let tbs_certificate = if Self::is_likely_pem(&data) { (_, pem) = pem::parse_x509_pem(&data)?; let x509_certificate = pem.parse_x509()?; x509_certificate.tbs_certificate } else { let (_, x509_certificate) = X509Certificate::from_der(&data)?; x509_certificate.tbs_certificate }; let oid = tbs_certificate.signature.oid().to_id_string(); match oid.as_str() { "1.2.840.10045.4.1" => Self::edsa_with_sha(&tbs_certificate, SHA1), "1.2.840.10045.4.3.1" => Self::edsa_with_sha(&tbs_certificate, SHA224), "1.2.840.10045.4.3.2" => Self::edsa_with_sha(&tbs_certificate, SHA256), "1.2.840.10045.4.3.3" => Self::edsa_with_sha(&tbs_certificate, SHA384), "1.2.840.10045.4.3.4" => Self::edsa_with_sha(&tbs_certificate, SHA512), "1.2.840.113549.1.1.10" => Self::rsassa_pss(&data), "1.2.840.113549.1.1.11" => Self::with_rsa_encryption(&tbs_certificate, SHA256), "1.2.840.113549.1.1.12" => Self::with_rsa_encryption(&tbs_certificate, SHA384), "1.2.840.113549.1.1.13" => Self::with_rsa_encryption(&tbs_certificate, SHA512), "1.2.840.113549.1.1.14" => Self::with_rsa_encryption(&tbs_certificate, SHA224), "1.2.840.113549.1.1.15" => Self::with_rsa_encryption(&tbs_certificate, SHA512_224), "1.2.840.113549.1.1.16" => Self::with_rsa_encryption(&tbs_certificate, SHA512_256), "1.2.840.113549.1.1.3" => Self::with_rsa_encryption(&tbs_certificate, MD4), "1.2.840.113549.1.1.4" => Self::with_rsa_encryption(&tbs_certificate, MD5), "1.2.840.113549.1.1.5" => Self::with_rsa_encryption(&tbs_certificate, SHA1), "1.3.101.112" => Self::id_ed25519(), "1.3.101.113" => Self::id_ed448(), "2.16.840.1.101.3.4.3.10" => Self::edsa_with_sha(&tbs_certificate, SHA3_256), "2.16.840.1.101.3.4.3.11" => Self::edsa_with_sha(&tbs_certificate, SHA3_384), "2.16.840.1.101.3.4.3.12" => Self::edsa_with_sha(&tbs_certificate, SHA3_512), _ => Err(Error::Unrecognised(oid)), } } fn hash_function(&self) -> Option<Hash> { self.hash_function } fn signature_algorithm(&self) -> Asymmetric { self.signature_algorithm } } 07070100000016000081A40000000000000000000000016537CEF400000AC1000000000000000000000000000000000000002C00000000wardstone-0.2.0~0/crates/cmd/src/key/ssh.rs//! Create SSH key representations and perform actions on them. use std::fs; use std::path::Path; use openssh_keys::{Curve, Data, PublicKey}; use wardstone_core::primitive::asymmetric::Asymmetric; use wardstone_core::primitive::ecc::*; use wardstone_core::primitive::ffc::*; use wardstone_core::primitive::hash::*; use wardstone_core::primitive::ifc::*; use crate::key::{Error, Key}; /// Represents an SSH public key. #[derive(Debug)] pub struct Ssh { hash_function: Option<Hash>, signature_algorithm: Asymmetric, } impl Key for Ssh { fn from_file(path: &Path) -> Result<Self, Error> { let contents = fs::read_to_string(path)?; let key = PublicKey::parse(contents.as_str())?; // It is not possible to infer the hash function used by looking at // the public key for RSA keys. RFC 4253 Section 6.6 specifies SHA-1 // but a newer revision RFC 8332 specifies SHA-256 and SHA-512 // without changes to the format for backwards compatibility. // // Similarly, for NIST elliptic curves, RFC 5656 does not specify // the length of the output of the hash function used (just that it // should come from the SHA2 family). Given that this information // cannot be determined reliably, the signature algorithm is assumed // to not use a hash function. let (hash_function, signature_algorithm) = match key.data { Data::Rsa { .. } => (None, { let k = key.size() as u16; let ifc = match k { 1024 => RSA_PKCS1_1024, 1536 => RSA_PKCS1_1536, 2048 => RSA_PSS_2048, 3072 => RSA_PKCS1_3072, 4096 => RSA_PKCS1_4096, 7680 => RSA_PKCS1_7680, 8192 => RSA_PKCS1_15360, _ => Ifc::new(ID_RSA_PKCS1, k), }; ifc.into() }), Data::Dsa { ref p, q, .. } => (Some(SHA1), { let p = (p.len() * 8) as u16; let q = (q.len() * 8) as u16; let ffc = match p { 1024 => DSA_1024_160, 2048 => DSA_2048_256, 3072 => DSA_3072_256, 7680 => DSA_7680_384, 15360 => DSA_15360_512, _ => Ffc::new(ID_DSA, p, q), }; ffc.into() }), Data::Ed25519 { .. } | Data::Ed25519Sk { .. } => (None, ED25519.into()), Data::Ecdsa { ref curve, .. } | Data::EcdsaSk { ref curve, .. } => match *curve { Curve::Nistp256 => (None, P256.into()), Curve::Nistp384 => (None, P384.into()), Curve::Nistp521 => (None, P521.into()), }, }; let key = Self { hash_function, signature_algorithm, }; Ok(key) } fn hash_function(&self) -> Option<Hash> { self.hash_function } fn signature_algorithm(&self) -> Asymmetric { self.signature_algorithm } } 07070100000017000081A40000000000000000000000016537CEF400000257000000000000000000000000000000000000002800000000wardstone-0.2.0~0/crates/cmd/src/lib.rs//! A command-line application to scan cryptographic keys for //! compliance. //! //! ```text //! A tool to scan cryptographic keys and certificates against recognized //! standards and research publications, verifying their compliance. //! //! //! Usage: wardstone <COMMAND> //! //! Commands: //! ssh Check an SSH public key for compliance //! x509 Check X.509 public key certificates for compliance //! help Print this message or the help of the given subcommand(s) //! //! Options: //! -h, --help Print help //! -V, --version Print version //! ``` pub mod key; pub mod report; 07070100000018000081A40000000000000000000000016537CEF400001D09000000000000000000000000000000000000002900000000wardstone-0.2.0~0/crates/cmd/src/main.rsuse std::path::PathBuf; use clap::{Parser, Subcommand, ValueEnum}; use wardstone::key::certificate::Certificate; use wardstone::key::ssh::Ssh; use wardstone::key::Key; use wardstone::report::{Audit, Exit, Report, Verbosity}; use wardstone_core::context::Context; use wardstone_core::primitive::asymmetric::Asymmetric; use wardstone_core::primitive::hash::Hash; use wardstone_core::primitive::Security; use wardstone_core::standard::bsi::Bsi; use wardstone_core::standard::cnsa::Cnsa; use wardstone_core::standard::ecrypt::Ecrypt; use wardstone_core::standard::lenstra::Lenstra; use wardstone_core::standard::nist::Nist; use wardstone_core::standard::testing::strong::Strong; use wardstone_core::standard::testing::weak::Weak; use wardstone_core::standard::Standard; // Having this type in the core crate would reduce the amount of case // analysis done to find the function to execute but this would run // counter to the ability of users to create their own first-class // guides/standards. #[derive(Clone, Copy, Debug, ValueEnum)] enum Guide { /// BSI TR-02102 series of technical guidelines. Bsi, /// Commercial National Security Algorithm Suites, CNSA 1.0 and /// CNSA 2.0. Cnsa, /// ECRYPT-CSA D5.4 Algorithms, Key Size and Protocols Report. Ecrypt, /// Key Lengths, Arjen K. Lenstra, The Handbook of Information /// Security, 06/2004. Lenstra, /// NIST Special Publication 800-57 Part 1 Revision 5 standard. Nist, /// Mock standard with a minimum security requirement of at least /// 256-bits. Strong, /// Mock standard with a minimum security requirement of at least /// 64-bits. Weak, } impl Guide { fn validate_hash_function(&self, ctx: Context, hash: Hash) -> Result<Hash, Hash> { match self { Self::Bsi => Bsi::validate_hash(ctx, hash), Self::Cnsa => Cnsa::validate_hash(ctx, hash), Self::Ecrypt => Ecrypt::validate_hash(ctx, hash), Self::Lenstra => Ecrypt::validate_hash(ctx, hash), Self::Nist => Nist::validate_hash(ctx, hash), Self::Strong => Strong::validate_hash(ctx, hash), Self::Weak => Weak::validate_hash(ctx, hash), } } fn validate_signature_algorithm( &self, ctx: Context, key: Asymmetric, ) -> Result<Asymmetric, Asymmetric> { match self { Self::Bsi => Bsi::validate_asymmetric(ctx, key), Self::Cnsa => Cnsa::validate_asymmetric(ctx, key), Self::Ecrypt => Ecrypt::validate_asymmetric(ctx, key), Self::Lenstra => Lenstra::validate_asymmetric(ctx, key), Self::Nist => Nist::validate_asymmetric(ctx, key), Self::Strong => Strong::validate_asymmetric(ctx, key), Self::Weak => Weak::validate_asymmetric(ctx, key), } } } /// Assess cryptographic keys for compliance. #[derive(Parser)] #[command(author, version, about, long_about = None)] struct Options { #[command(subcommand)] subcommands: Subcommands, } #[derive(Subcommand)] enum Subcommands { /// Check an SSH public key for compliance. Ssh { /// Guide to assess the key against. #[arg(short, long, value_enum)] guide: Guide, /// JSON formatted output. #[arg(short, long)] json: bool, /// Do not print output. #[arg(short, long, conflicts_with = "verbose")] quiet: bool, /// The minimum security level required. /// /// If a sufficiently low value is used then the application will /// default to the minimum security specified by the standard. #[arg(short, long, default_value_t = 0)] security: Security, /// Verbose output. #[arg(short, long, conflicts_with = "quiet")] verbose: bool, /// The year in which a recommendation is expected to be valid. /// /// Note that this does not necessarily mean that a primitive will /// be deemed insecure beyond this point. Indeed, recommendations /// are usually done with a longer horizon in mind. For example, /// setting this value to 2023, one would expect any passing /// primitive to be secure for the next 5 to 7 years, /// conservatively, subject to cryptanalytic developments. #[arg(short, long, default_value_t = 2023)] year: u16, /// The paths to the public key file(s). #[clap(value_name = "FILE")] files: Vec<PathBuf>, }, /// Check X.509 public key certificates for compliance. X509 { /// Guide to assess the certificate against. #[arg(short, long, value_enum)] guide: Guide, /// JSON formatted output. #[arg(short, long)] json: bool, /// Do not print output. #[arg(short, long, conflicts_with = "verbose")] quiet: bool, /// The minimum security level required. /// /// If a sufficiently low value is used then the application will /// default to the minimum security specified by the standard. #[arg(short, long, default_value_t = 0)] security: Security, /// Verbose output. #[arg(short, long, conflicts_with = "quiet")] verbose: bool, /// The year in which a recommendation is expected to be valid. /// /// Note that this does not necessarily mean that a primitive will /// be deemed insecure beyond this point. Indeed, recommendations /// are usually done with a longer horizon in mind. For example, /// setting this value to 2023, one would expect any passing /// primitive to be secure for the next 5 to 7 years, /// conservatively, subject to cryptanalytic developments. #[arg(short, long, default_value_t = 2023)] year: u16, /// The certificates as DER or PEM encoded files. #[clap(value_name = "FILE")] files: Vec<PathBuf>, }, } impl Subcommands { fn assess<T: Key>( ctx: Context, paths: &Vec<PathBuf>, guide: Guide, json: bool, verbosity: Verbosity, ) -> Exit { let mut report = Report::new(verbosity, json); for path in paths { let key = match T::from_file(path) { Ok(got) => got, Err(err) => return Exit::Failure(err), }; let hash_function = key.hash_function(); let signature_algorithm = key.signature_algorithm(); let mut audit = Audit::new(path, hash_function, signature_algorithm); if let Some(got) = hash_function { match guide.validate_hash_function(ctx, got) { Ok(want) => audit.compliant_hash_function(want), Err(want) => audit.noncompliant_hash_function(want), } } match guide.validate_signature_algorithm(ctx, signature_algorithm) { Ok(want) => audit.compliant_signature(want), Err(want) => audit.noncompliant_signature(want), } report.push(audit); } Exit::Success(report) } pub fn run(&self) -> Exit { match self { Self::Ssh { guide, json, quiet, verbose, files, security, year, } => { let ctx = Context::new(*security, *year); let verbosity = Verbosity::from_flags(*verbose, *quiet); Self::assess::<Ssh>(ctx, files, *guide, *json, verbosity) }, Self::X509 { guide, json, quiet, verbose, files, security, year, } => { let ctx = Context::new(*security, *year); let verbosity = Verbosity::from_flags(*verbose, *quiet); Self::assess::<Certificate>(ctx, files, *guide, *json, verbosity) }, } } } fn main() -> Exit { let options = Options::parse(); options.subcommands.run() } 07070100000019000081A40000000000000000000000016537CEF4000000E6000000000000000000000000000000000000002E00000000wardstone-0.2.0~0/crates/cmd/src/primitive.rs//! Bridge types. //! //! Some types cannot go in the core crate because it has to stay //! compatible with C. This crate holds convenience types that bridge //! those types into more ergonomic ones used here. pub mod asymmetric; 0707010000001A000081A40000000000000000000000016537CEF40000131C000000000000000000000000000000000000002B00000000wardstone-0.2.0~0/crates/cmd/src/report.rs//! Compose a single report on the results of multiple audits. use std::fmt::{self, Display, Formatter}; use std::path::{Path, PathBuf}; use std::process::{ExitCode, Termination}; use serde::Serialize; use serde_json::json; use wardstone_core::primitive::asymmetric::Asymmetric; use wardstone_core::primitive::hash::Hash; use crate::key::Error; /// Represents the exit status of the program. /// /// It implements [`Termination`] such that if any one of the audits /// fail or an error occurs, a helpful message is printed and the exit /// code is set to [`ExitCode::FAILURE`]. pub enum Exit { Success(Report), Failure(Error), } impl Termination for Exit { fn report(self) -> ExitCode { match self { Exit::Success(report) => report.report(), Exit::Failure(err) => { eprintln!("{}", err); ExitCode::FAILURE }, } } } /// Output verbosity level. #[derive(Clone, Copy, PartialEq, Eq)] pub enum Verbosity { Quiet, Normal, Verbose, } impl Verbosity { pub fn from_flags(verbose: bool, quiet: bool) -> Verbosity { if quiet { Self::Quiet } else if verbose { Self::Verbose } else { Self::Normal } } pub fn is_quiet(self) -> bool { self == Verbosity::Quiet } pub fn is_verbose(self) -> bool { self == Verbosity::Verbose } } /// Represents an audit of a single key. #[derive(Serialize)] pub struct Audit { passed: bool, path: PathBuf, #[serde(skip_serializing_if = "Option::is_none")] got_hash_function: Option<Hash>, #[serde(skip_serializing_if = "Option::is_none")] want_hash_function: Option<Hash>, got_signature: Asymmetric, want_signature: Asymmetric, } impl Audit { pub fn new(path: &Path, hash: Option<Hash>, signature: Asymmetric) -> Self { Self { passed: true, path: path.to_path_buf(), got_hash_function: hash, want_hash_function: None, got_signature: signature, want_signature: signature, } } pub fn noncompliant_hash_function(&mut self, want: Hash) { self.passed = false; self.want_hash_function = Some(want); } pub fn compliant_hash_function(&mut self, want: Hash) { self.want_hash_function = Some(want); } pub fn noncompliant_signature(&mut self, want: Asymmetric) { self.passed = false; self.want_signature = want; } pub fn compliant_signature(&mut self, want: Asymmetric) { self.want_signature = want; } } impl Display for Audit { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { let mut s = String::new(); if let (Some(got), Some(want)) = (self.got_hash_function, self.want_hash_function) { s.push_str(format!("hash function: got {}, want {}\n", got, want).as_str()); } s.push_str( format!( "signature algorithm: got {}, want {}\n", self.got_signature, self.want_signature ) .as_str(), ); if self.passed { s.push_str(format!("ok: {}", self.path.display()).as_str()); } else { s.push_str(format!("fail: {}", self.path.display()).as_str()); } write!(f, "{s}") } } /// Status report of a series of key audits. pub struct Report { audits: Vec<Audit>, verbosity: Verbosity, json: bool, } impl Report { pub fn new(verbosity: Verbosity, json: bool) -> Self { Self { audits: Vec::new(), verbosity, json, } } pub fn push(&mut self, audit: Audit) { self.audits.push(audit); } pub fn to_json_string(&self) -> String { let mut v = Vec::new(); for audit in self.audits.iter() { if audit.passed { if self.verbosity.is_verbose() { v.push(audit) } } else { v.push(audit) } } // Partition by compliance status. let (mut v, failed): (Vec<_>, Vec<_>) = v.into_iter().partition(|a| a.passed); v.extend::<Vec<&Audit>>(failed); json!({ "report": &v }).to_string() } } impl Display for Report { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { // Partition by compliance status. let (mut v, failed): (Vec<_>, Vec<_>) = self.audits.iter().partition(|a| a.passed); v.extend::<Vec<&Audit>>(failed); let mut s = String::new(); for audit in v.iter() { if audit.passed { if self.verbosity.is_verbose() { s.push_str(format!("{}\n", audit).as_str()); } } else { s.push_str(format!("{}\n", audit).as_str()) } } write!(f, "{}", s) } } impl Termination for Report { fn report(self) -> ExitCode { let (failed, _): (Vec<_>, Vec<_>) = self.audits.iter().partition(|audit| !audit.passed); if !self.verbosity.is_quiet() { let repr = if self.json { self.to_json_string() } else { format!("{}", self) }; print!("{}", repr) } if failed.is_empty() { ExitCode::SUCCESS } else { ExitCode::FAILURE } } } 0707010000001B000041ED0000000000000000000000026537CEF400000000000000000000000000000000000000000000002900000000wardstone-0.2.0~0/crates/cmd/src/testing0707010000001C000041ED0000000000000000000000026537CEF400000000000000000000000000000000000000000000003600000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates0707010000001D000081A40000000000000000000000016537CEF4000002B0000000000000000000000000000000000000004200000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_SM2.pem-----BEGIN CERTIFICATE----- MIIBzjCCAXOgAwIBAgIUQiF42mojCEffYfZ9RVxdS30PuYwwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzdaFw0yMzA4MjAxMjQzMzdaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwWTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAARKKpWDQmDOL8To 4X1iDGzBh/m4n4VPtsDYIzIg0bP0JUQqP84SRaGX+v08tVtDL9ex0z/t0SQgBAfM 5Ed6Himto1MwUTAdBgNVHQ4EFgQU5QnKK3YtfNJk4LWssdvg+siTFf0wHwYDVR0j BBgwFoAU5QnKK3YtfNJk4LWssdvg+siTFf0wDwYDVR0TAQH/BAUwAwEB/zAKBggq hkjOPQQDAgNJADBGAiEA8nT7Pwr7gwEzMS7pJXY0itZj1o1B+BpCbSnHCT6GLMgC IQDS0tWMeuIbshJGYmI65Wcqb0DBlq41nUjunqCJjTGinA== -----END CERTIFICATE----- 0707010000001E000081A40000000000000000000000016537CEF40000026F000000000000000000000000000000000000004E00000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_brainpoolP160r1.pem-----BEGIN CERTIFICATE----- MIIBnjCCAVygAwIBAgIUaC2VOsHrQMOiW/KBvDaN+1MgRR0wCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwQjAUBgcqhkjOPQIBBgkrJAMDAggBAQEDKgAE5MOs+/C/cGKa prcX05PM0biaLw8eOiwOeC2HAko/cV4tkA91lrERYaNTMFEwHQYDVR0OBBYEFKpx uPtno+dT7AIdHQluzaCVbEfqMB8GA1UdIwQYMBaAFKpxuPtno+dT7AIdHQluzaCV bEfqMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDMAAwLQIVAKCyFSWByhfb IEFyDdf219Qchn+0AhQDbBc1agskIW6KHuvv7Lm2GE7/TQ== -----END CERTIFICATE----- 0707010000001F000081A40000000000000000000000016537CEF40000026F000000000000000000000000000000000000004E00000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_brainpoolP160t1.pem-----BEGIN CERTIFICATE----- MIIBnzCCAVygAwIBAgIURv5elUu/6TudOJNvVA+7ICktzAEwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwQjAUBgcqhkjOPQIBBgkrJAMDAggBAQIDKgAENToVn2H5XxhG wx4nXOiPs6P3OYLQbvigXFigkfHE3waXKz53usx5dqNTMFEwHQYDVR0OBBYEFCBh zJKt08Y0tvBlJmIqet5xXKtWMB8GA1UdIwQYMBaAFCBhzJKt08Y0tvBlJmIqet5x XKtWMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDMQAwLgIVAJ9NftCjzKm8 gXF6ey0iB0hDMpd2AhUAy+/8nMoxhtdo9saSRJ1xVJOvP7o= -----END CERTIFICATE----- 07070100000020000081A40000000000000000000000016537CEF400000284000000000000000000000000000000000000004E00000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_brainpoolP192r1.pem-----BEGIN CERTIFICATE----- MIIBrjCCAWSgAwIBAgIUBn0j3M9fnOGeX0PVTHA3hWlqDgswCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwSjAUBgcqhkjOPQIBBgkrJAMDAggBAQMDMgAELABz9FXFe9Tb Gbv6LgLN1FH4nK2DZqLqp0CkcXSbmTvyAcRhh/Ml3SSX19yzNCKEo1MwUTAdBgNV HQ4EFgQUpwkU0zqygGx5UJcqLAdw7M1z384wHwYDVR0jBBgwFoAUpwkU0zqygGx5 UJcqLAdw7M1z384wDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgM4ADA1AhgI H4ctCnFlabj0kvhkfOYvpx/IkGucU9ICGQCygbAeIEDGLYZYoZeHAewB7DV+4N8L NHc= -----END CERTIFICATE----- 07070100000021000081A40000000000000000000000016537CEF400000284000000000000000000000000000000000000004E00000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_brainpoolP192t1.pem-----BEGIN CERTIFICATE----- MIIBrjCCAWSgAwIBAgIUM8Dpj7jPj4dY2xlCDvk7ht27v40wCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwSjAUBgcqhkjOPQIBBgkrJAMDAggBAQQDMgAEkAMChz0nCxD5 76A2lwVgJgsTU9zvxsgQqiv35L7zxB/OAmlCXjJk3o37vpOacjZno1MwUTAdBgNV HQ4EFgQUKItCQV+e8UoWnsFm8XwuEOzRoVQwHwYDVR0jBBgwFoAUKItCQV+e8UoW nsFm8XwuEOzRoVQwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgM4ADA1Ahgo m4hmuO+1jI7KCepytT8euCH4XIPqhIYCGQCLYTeziKlnFG7LINlpOxS4laooB2de 1oo= -----END CERTIFICATE----- 07070100000022000081A40000000000000000000000016537CEF40000029C000000000000000000000000000000000000004E00000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_brainpoolP224r1.pem-----BEGIN CERTIFICATE----- MIIBvzCCAWygAwIBAgIUK8kxJGN5nZJwkxQAPQwoKL4VbjEwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwUjAUBgcqhkjOPQIBBgkrJAMDAggBAQUDOgAEbsLxYSimUQXj ssZlQ0VXSIS+iJoBgeJVAt2nUxALaKAwZfRE3a+FZ+yx7OFqsWy8OtqeMxp/2eWj UzBRMB0GA1UdDgQWBBTa/1j9+iOkMKcTM9Cde/gLzq+h/DAfBgNVHSMEGDAWgBTa /1j9+iOkMKcTM9Cde/gLzq+h/DAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMC A0EAMD4CHQCCwXbGCbKmOExWvnXXR5jr0K7/EfpmgYjuLrg9Ah0AjdF3NALTPs5c pfuzUvMQNMI1Ollz4LBM1QRz7w== -----END CERTIFICATE----- 07070100000023000081A40000000000000000000000016537CEF400000298000000000000000000000000000000000000004E00000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_brainpoolP224t1.pem-----BEGIN CERTIFICATE----- MIIBvjCCAWygAwIBAgIUGTpUO93o8w8iOh1inG82Z6sVA2kwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwUjAUBgcqhkjOPQIBBgkrJAMDAggBAQYDOgAEjFe5/BH5GJJt tYdX/i/2GEOTVvHXOPzOTb5oDMCK/kyigohsEEX4wgZSR8mWoto8H4rVXlQzg5qj UzBRMB0GA1UdDgQWBBSD35V6s0O108iHGaGhHQQ/YQ9iWjAfBgNVHSMEGDAWgBSD 35V6s0O108iHGaGhHQQ/YQ9iWjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMC A0AAMD0CHQCcOve5FftznqF0DTmBddR81iaumExEha+E1kxuAhwu1zTGwR5zv3cm uVS944jfSseNeV+Yix4ocZ5N -----END CERTIFICATE----- 07070100000024000081A40000000000000000000000016537CEF4000002B0000000000000000000000000000000000000004E00000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_brainpoolP256r1.pem-----BEGIN CERTIFICATE----- MIIBzjCCAXSgAwIBAgIUFGZuadAbxVht7c3iIjP7MWmXG2gwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwWjAUBgcqhkjOPQIBBgkrJAMDAggBAQcDQgAENoPqbTTFZ9er N/CgtTezPGMDmbtLBEOe2tQ7v6eqIQQ+A9ruHVJtMqzOdi7AQP61wB8zgvMb/sFD O3efbxkFwqNTMFEwHQYDVR0OBBYEFPfB2fdLOAnlMlcExydM0U8q8efWMB8GA1Ud IwQYMBaAFPfB2fdLOAnlMlcExydM0U8q8efWMA8GA1UdEwEB/wQFMAMBAf8wCgYI KoZIzj0EAwIDSAAwRQIhAKdu+BSTvhPWKO1QXPvp4ze1SEEgP9wuAF/FZBQxecsd AiAoPUjdCnNlBvzAWI63eOqc+DVbx8eXFfwSw2c4bifZBA== -----END CERTIFICATE----- 07070100000025000081A40000000000000000000000016537CEF4000002AC000000000000000000000000000000000000004E00000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_brainpoolP256t1.pem-----BEGIN CERTIFICATE----- MIIBzTCCAXSgAwIBAgIUTov1uJLHVzljmMDinSzWzNONbz4wCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzdaFw0yMzA4MjAxMjQzMzdaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwWjAUBgcqhkjOPQIBBgkrJAMDAggBAQgDQgAESJGJqXgizOl6 bgcedKG2JqVU6C4KHRlq+LttI96whdBoshdi8EdntMS22p91iVQhV2G3KAFHTYoM eK9LTJfOhaNTMFEwHQYDVR0OBBYEFNrqJZsQy/wyYJAOQwXKoFPYefJSMB8GA1Ud IwQYMBaAFNrqJZsQy/wyYJAOQwXKoFPYefJSMA8GA1UdEwEB/wQFMAMBAf8wCgYI KoZIzj0EAwIDRwAwRAIgDFO27cDN0y340rqlyYCRz0I3imuBGrrfhdIMW3EgwFEC IBR6483gkirU2gnwjC7X5L++Quh++sFTwWzPUnMzH1X3 -----END CERTIFICATE----- 07070100000026000081A40000000000000000000000016537CEF4000002D9000000000000000000000000000000000000004E00000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_brainpoolP320r1.pem-----BEGIN CERTIFICATE----- MIIB7jCCAYSgAwIBAgIUWEgTCRfKQYcSo0dX+Yx/iada+0kwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzdaFw0yMzA4MjAxMjQzMzdaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwajAUBgcqhkjOPQIBBgkrJAMDAggBAQkDUgAEEJnW3P5W1gRI MqNPlFptcvfvy75uWRxKGVnGB6FqWPe1gVwWoYnsPJcUYBMzKOYotqmam6g9jbz7 FW6uioNOTpAtGn25k/ZVwuZ/jriqL4OjUzBRMB0GA1UdDgQWBBSVacp/YYgko8sh sFeeWFr2rusCVTAfBgNVHSMEGDAWgBSVacp/YYgko8shsFeeWFr2rusCVTAPBgNV HRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA1gAMFUCKQCRyXVHxAzWiq7rF8kC+Q4k k8FQLHXOGdGfPJfMKcorSoKs3lKPvF6yAig19NbPzZMvqp2ZBiUme+Zk+7g+4EGC lEMJNLW68CHlvKC4KeHgvB7G -----END CERTIFICATE----- 07070100000027000081A40000000000000000000000016537CEF4000002D9000000000000000000000000000000000000004E00000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_brainpoolP320t1.pem-----BEGIN CERTIFICATE----- MIIB7jCCAYSgAwIBAgIUWQ859lQCTt3UgWf7ysjzmbbSj0wwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzdaFw0yMzA4MjAxMjQzMzdaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwajAUBgcqhkjOPQIBBgkrJAMDAggBAQoDUgAEJQRrl6Ri4qcD 5urpbr1iufULAx6pLSyhXWnTJf3QXnuZW2GhfJIjTrHlK/JaIzG+cLSfrGUrOQpD 3S9Pps8nTQma7aCAdo2NCVqR/YneeIKjUzBRMB0GA1UdDgQWBBSPe9CYBnCORGqL uA0MDWb/NbVZ5zAfBgNVHSMEGDAWgBSPe9CYBnCORGqLuA0MDWb/NbVZ5zAPBgNV HRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA1gAMFUCKQDKg3hu1KYnBtCMSMNCpf9O 6SHQLYSbBg2zfHraMZGFpmRAJf823hM6Aig79UDlpfewhC3OYENEkEseFe0jAkAi O3nDbH+huncI3FwVi+aF93p9 -----END CERTIFICATE----- 07070100000028000081A40000000000000000000000016537CEF400000306000000000000000000000000000000000000004E00000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_brainpoolP384r1.pem-----BEGIN CERTIFICATE----- MIICDTCCAZSgAwIBAgIUTnDlPgo8hFixTHNtd/7T9FlN3yowCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzdaFw0yMzA4MjAxMjQzMzdaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwejAUBgcqhkjOPQIBBgkrJAMDAggBAQsDYgAEU/BPVWJYhNjo e7V9oK1/KrB+Q8pM10adc7rhx13MHabneyFLR/oU0sDGHsIqicKFS332Imc3rPoB r766mVmEM9wN+o42EpCBjOUY/kpay6xZXyAmq4AJmFfugE3ZguXyo1MwUTAdBgNV HQ4EFgQUv5UfUICfFbKMlNgLeL6eSMEoUrIwHwYDVR0jBBgwFoAUv5UfUICfFbKM lNgLeL6eSMEoUrIwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNnADBkAjBD bdvLAIrP2GHRItp62EcAk/8NDlLMCBMGAz6geBsIqx57iYxTbjgVw8MqHE8fi/0C MBYN/qrI/vYSlQRaKeAr2P1CAVwjsBCmUv8h9LNUf4pWAN07wjgHTM0WCO7oMw0l Fg== -----END CERTIFICATE----- 07070100000029000081A40000000000000000000000016537CEF400000306000000000000000000000000000000000000004E00000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_brainpoolP384t1.pem-----BEGIN CERTIFICATE----- MIICDTCCAZSgAwIBAgIUa3iklz3NN5Q/cHmPvxlKi2jh/lowCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzdaFw0yMzA4MjAxMjQzMzdaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwejAUBgcqhkjOPQIBBgkrJAMDAggBAQwDYgAEfvTwZsnN8EtB R0eKzxlmEVrcSY8eWQdnF6Sh6aJW1uRqNJ5wnKEgpcBccFkQFA0LKiCjDDfRS+bA HPDccLvTNyPGUQqPIxwt51f2S1lpvmEbl+5CpPjbxWz2rjPlYDqeo1MwUTAdBgNV HQ4EFgQUKy5DTPhXPZ27cuApIYJj4BjDGyowHwYDVR0jBBgwFoAUKy5DTPhXPZ27 cuApIYJj4BjDGyowDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNnADBkAjAK WGDlFhkUMSZ5fXInKk9rmyAp+111Oi6DqMRlCS2rpaOWYYfkTg0L7rmn3hU2h4cC MCh+2pPojZYkaWgfGAK2Mr4ip8uEU+NwsheDzTlhXrRhTN1jh13vWgJPbifc/JiZ ow== -----END CERTIFICATE----- 0707010000002A000081A40000000000000000000000016537CEF40000035F000000000000000000000000000000000000004E00000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_brainpoolP512r1.pem-----BEGIN CERTIFICATE----- MIICUTCCAbagAwIBAgIUX22scfbyvd1ZAZP3/pMRWl1NsmcwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzdaFw0yMzA4MjAxMjQzMzdaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwgZswFAYHKoZIzj0CAQYJKyQDAwIIAQENA4GCAARMnRrZ3OFB GH0nTbgk1z7YQlQd9DWIH59AqMIlxLNVg7Jah4B313ps7r5z8S4xWinjNUlK3ada A40kTzOj8epqjQKQUa8RGodnryWspZFsAoKTCccTcm9Rnx2MZ1hrV47DarggdT6P uJKbMduytuwMSQNnjpw9jxLbL86Q7kv/X6NTMFEwHQYDVR0OBBYEFPFsrhpstDEk 2bF15soRsraFr0RmMB8GA1UdIwQYMBaAFPFsrhpstDEk2bF15soRsraFr0RmMA8G A1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDgYgAMIGEAkBA5lCAMiBTC8mEVJha RTqf5lNIZJxPbIHcj2VITcAV+MBKwCQU2bJXyV1C6bSLNr0Hf6dnPwxnBToPmwM+ sPEjAkAxCz4Ym11u0JaKzToKI3dCKPE6ufwHdm7pToGhnWhh2DngJFr5q9eKVJbF EzlziLXqkH4PlMVx82e0kX+krcOz -----END CERTIFICATE----- 0707010000002B000081A40000000000000000000000016537CEF400000363000000000000000000000000000000000000004E00000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_brainpoolP512t1.pem-----BEGIN CERTIFICATE----- MIICUjCCAbagAwIBAgIUWRJ4/nWyYZSnoyz0MNS3BzNQ2oswCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzdaFw0yMzA4MjAxMjQzMzdaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwgZswFAYHKoZIzj0CAQYJKyQDAwIIAQEOA4GCAASIwkR+raJj k5SYNvEK4YU5NZj3rNZHTmqZv7OVtgcFvNzTggZvhPGRJhlytCi7Ykekh0zRK7jy /KqLUnmfDxtiHmWDV/yM8unN9mKxv53Q3zWmfhXZ1UgIuGrb4o2WKXNrEgVcjigt eHM06M7A38xAGhKC4Sosw1b9mEOB5N5W5KNTMFEwHQYDVR0OBBYEFBBVoX4jTxAp WV0B9puScNeM4DekMB8GA1UdIwQYMBaAFBBVoX4jTxApWV0B9puScNeM4DekMA8G A1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDgYkAMIGFAkEAqeYOUdIza6CVyf1g aBINchOsB0d4o/VqcFXQtgsrplCmIaKjxAz891kMiHv20/4tQf1iYV1u1Obgrrm5 FZH6SQJAcH0fgdUacIoADnoOui5GrUGDFvaRBSatLD2Nbz5q4qPEQ52iKUDwhyxz wVVa8sZPtTXKdRtHPoPFHRsV1geUpg== -----END CERTIFICATE----- 0707010000002C000081A40000000000000000000000016537CEF40000026F000000000000000000000000000000000000004900000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_c2pnb163v1.pem-----BEGIN CERTIFICATE----- MIIBoDCCAV2gAwIBAgIUcFymVUm2wYwhvbVmB7OjkoWBhKwwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwQzATBgcqhkjOPQIBBggqhkjOPQMAAQMsAAQFO7MUmasIgr/o +OlV3dRHIKtgsWAHjz3DUintJ9luKseiUn5DjwnPB3mjUzBRMB0GA1UdDgQWBBQj 64++HgqoGKQsBEA4rnhKw6NlHTAfBgNVHSMEGDAWgBQj64++HgqoGKQsBEA4rnhK w6NlHTAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCAzEAMC4CFQFlbkwdkt65 1jeOeYOYttNDZQsagAIVAU7GsFLB0ncUSieB/gU/pA+IiDuS -----END CERTIFICATE----- 0707010000002D000081A40000000000000000000000016537CEF40000026F000000000000000000000000000000000000004900000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_c2pnb163v2.pem-----BEGIN CERTIFICATE----- MIIBnzCCAV2gAwIBAgIUIm8Zev5cg7PQA96aVl7zOIgkEv0wCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwQzATBgcqhkjOPQIBBggqhkjOPQMAAgMsAAQEXoePaLd4G0pP CNX46TMvS6jI7/QBxvYZDrPnRLpbNpZjHBvGVcp4dcWjUzBRMB0GA1UdDgQWBBSt fOwef8AMtB63myasZ59lLxM0sDAfBgNVHSMEGDAWgBStfOwef8AMtB63myasZ59l LxM0sDAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCAzAAMC0CFQEQfpuXloc4 vs2b/fB+VmvsrXYTFwIUStT0i+pgRs+X6QBTdxMqrkb0lsE= -----END CERTIFICATE----- 0707010000002E000081A40000000000000000000000016537CEF40000026F000000000000000000000000000000000000004900000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_c2pnb163v3.pem-----BEGIN CERTIFICATE----- MIIBoDCCAV2gAwIBAgIUSRnKWgLBPz4kMnrnRs8YqP90s9MwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwQzATBgcqhkjOPQIBBggqhkjOPQMAAwMsAAQHHWpcTW0UyaO9 m0Hk5ugPcpRP7RMGvQ9MIxtSCCV8/gjg5odp+tCfhBmjUzBRMB0GA1UdDgQWBBQK 3giaKmR607HcK11DdfAWqPdpxDAfBgNVHSMEGDAWgBQK3giaKmR607HcK11DdfAW qPdpxDAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCAzEAMC4CFQNcECy+D/L9 Z/KkAaVFeLh3rabV1AIVAR9XgokY2sIZI82bBt8Lzvx0Gu/l -----END CERTIFICATE----- 0707010000002F000081A40000000000000000000000016537CEF400000273000000000000000000000000000000000000004900000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_c2pnb176v1.pem-----BEGIN CERTIFICATE----- MIIBoTCCAV+gAwIBAgIUD0SG7zJim453Qhu/+GlOlhi+8CEwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwRTATBgcqhkjOPQIBBggqhkjOPQMABAMuAAR2dwn8dma5QNs1 bhY0y/4EOUmZMVE1ytiXB8KRRwZQnXVzcRzJSVR9QLqO0aNTMFEwHQYDVR0OBBYE FBVCFuiu+01E5aJMflhSqqUKGyY8MB8GA1UdIwQYMBaAFBVCFuiu+01E5aJMflhS qqUKGyY8MA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDMAAwLQIVAIRee0oC vHw5zXPllr3k3jFHjB/NAhQXLhA2FXqJpVlb+/5BvqKE61Q+ig== -----END CERTIFICATE----- 07070100000030000081A40000000000000000000000016537CEF400000288000000000000000000000000000000000000004900000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_c2pnb208w1.pem-----BEGIN CERTIFICATE----- MIIBsjCCAWegAwIBAgIUKkwGJK7Bz7g6hXD+2MP7uVQTjP8wCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwTTATBgcqhkjOPQIBBggqhkjOPQMACgM2AARiuu6srfYEwBQ7 hNdjiiN3jAOjHGzsqC3teLspKpcrp4c6QdePvOkgXCPeyF9/zNy4p9gqo1MwUTAd BgNVHQ4EFgQUdhDsPeObTL2NsrInfXj8B47VEfEwHwYDVR0jBBgwFoAUdhDsPeOb TL2NsrInfXj8B47VEfEwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgM5ADA2 AhkA01+ijHPdf/T6uov5IWiG2vpGc+cRJsdWAhkA1zonf01qOMx85kncXJIniPdy bib6nIN2 -----END CERTIFICATE----- 07070100000031000081A40000000000000000000000016537CEF4000002B4000000000000000000000000000000000000004900000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_c2pnb272w1.pem-----BEGIN CERTIFICATE----- MIIB0jCCAXegAwIBAgIUcu/koEqohujkOlFFsIbCdEmX2CkwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwXTATBgcqhkjOPQIBBggqhkjOPQMAEANGAASI34Wbe5M/1fWa UhLgaOaTK5TijYrzfIfJmexT8x2EmMI0e7EbUksPJldyuv4JYZndo4ZnzM3W8dPi nLBrQO3gMDXVsKNTMFEwHQYDVR0OBBYEFK6eGYCjC4vI/5+t/QOOTwULCDp3MB8G A1UdIwQYMBaAFK6eGYCjC4vI/5+t/QOOTwULCDp3MA8GA1UdEwEB/wQFMAMBAf8w CgYIKoZIzj0EAwIDSQAwRgIhAPaaDcgDcRc5vm8c9Ffit2hfHmYT5XwBTu4SwJGA JhdpAiEA8R1Rnwz6HrzdTQjW1I9yvw4/4OjVcSnWt+MBvG7CboI= -----END CERTIFICATE----- 07070100000032000081A40000000000000000000000016537CEF4000002C9000000000000000000000000000000000000004900000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_c2pnb304w1.pem-----BEGIN CERTIFICATE----- MIIB4jCCAX+gAwIBAgIUB3tAw3QDx05Bvpt8h7bA4dhNoDcwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwZTATBgcqhkjOPQIBBggqhkjOPQMAEQNOAAThSNpU9jKaP46r 6uh3Rs+AKA1LqXz3JHVuecuameJzymIeuPeaGU52Mu2FrtY687/DFT16is5ey0Mk uBRM1dFdcl999SK9xMnDjTaKo1MwUTAdBgNVHQ4EFgQUin750SZsOgldSHXmYRwW G9002kgwHwYDVR0jBBgwFoAUin750SZsOgldSHXmYRwWG9002kgwDwYDVR0TAQH/ BAUwAwEB/zAKBggqhkjOPQQDAgNRADBOAiUA5B2O6wI7DcOJCekZvbtKCFr6h/R+ 1utHxCb6kEL4svGom72xAiUBAaLiT22y4u51Zi49/KMNWdAbg3lMIP22fRf0Z6Oe fvRs+5/V -----END CERTIFICATE----- 07070100000033000081A40000000000000000000000016537CEF4000002F5000000000000000000000000000000000000004900000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_c2pnb368w1.pem-----BEGIN CERTIFICATE----- MIICATCCAY+gAwIBAgIURYqdxdqeMUk3Kwt3UwtU26snQDYwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwdTATBgcqhkjOPQIBBggqhkjOPQMAEwNeAATbZKjKRLlMwHM2 XbM3djgpooQgZk0dO2A8XZAKo1LdOCMJkIEjQx7g/gHwcXdOTuHl5Nz3cysxwRFy vHsx5J9ez2THNGbDUD0J0KbXJsfWvlaD5K6HSQppDbiieaNTMFEwHQYDVR0OBBYE FIJet9ZG7cUub/z3OzGZzgVtwWDOMB8GA1UdIwQYMBaAFIJet9ZG7cUub/z3OzGZ zgVtwWDOMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDYAAwXQIsc+giiJsH isIgEsbYCLwAbkHxTELxrRQaN+QvEa/tpfunJ7XR7pyflIir4O8CLQDhAIp3UlMz z6slv9x/qDIxTLBAsaOwfmCnOox3fXs66lKaTUPaWYiahWhldA== -----END CERTIFICATE----- 07070100000034000081A40000000000000000000000016537CEF40000027F000000000000000000000000000000000000004900000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_c2tnb191v1.pem-----BEGIN CERTIFICATE----- MIIBrDCCAWOgAwIBAgIUS7J6J1YPDPVGECe9L+PJfzrLmbUwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwSTATBgcqhkjOPQIBBggqhkjOPQMABQMyAAQCxecPkimvv1BM CbyuP2A7FSgFCrATphMhYawHFVMv7iGVApmkfPDcc7dEsUuYzv6jUzBRMB0GA1Ud DgQWBBStQmtZAsln2J4aBANlVlXexGQ6fTAfBgNVHSMEGDAWgBStQmtZAsln2J4a BANlVlXexGQ6fTAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCAzcAMDQCGBo3 s35a/uxWWcq70EN9bYJw9NA1qERhBgIYDD2C94Cc2alCg9QdDg+7puzH+lnnqyCA -----END CERTIFICATE----- 07070100000035000081A40000000000000000000000016537CEF40000027F000000000000000000000000000000000000004900000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_c2tnb191v2.pem-----BEGIN CERTIFICATE----- MIIBrDCCAWOgAwIBAgIUXfX8aKZ/XKJScjdJ1QD6YuOlKV0wCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwSTATBgcqhkjOPQIBBggqhkjOPQMABgMyAAQoGy0UOVf9cd0o kLrJ+zztWdKPAt80pqxTguxdBkDjL8I2CDaEJKoFpMBQ0EHuajmjUzBRMB0GA1Ud DgQWBBRYWWrebBjsQBNlRa30c968FMPMLjAfBgNVHSMEGDAWgBRYWWrebBjsQBNl Ra30c968FMPMLjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCAzcAMDQCGA4a pCvHrMM5tuUIerwfISnkI1kqaC4gBAIYB6U5EX7IzHWDo2ZCZOLQXOnESSVtOxDu -----END CERTIFICATE----- 07070100000036000081A40000000000000000000000016537CEF40000027F000000000000000000000000000000000000004900000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_c2tnb191v3.pem-----BEGIN CERTIFICATE----- MIIBrDCCAWOgAwIBAgIURJ5956O9N0JAogIYKl0HWiIPEAIwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwSTATBgcqhkjOPQIBBggqhkjOPQMABwMyAARKRYCdLMFK6nU4 nhZDaGg0YhH/NHtbWTlw5eV4qCVI4eJtK5xBcIqNS3xJmsLclF6jUzBRMB0GA1Ud DgQWBBSJxOSnm4CD6m/qpjUzjGu9I9wTijAfBgNVHSMEGDAWgBSJxOSnm4CD6m/q pjUzjGu9I9wTijAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCAzcAMDQCGAjo JF4gd59msWs1ALZsKNx5dA7zn8Yq8AIYDX+xBJt1Tz9ZEKSDKxwE6OfhFwhb2QGJ -----END CERTIFICATE----- 07070100000037000081A40000000000000000000000016537CEF4000002A0000000000000000000000000000000000000004900000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_c2tnb239v1.pem-----BEGIN CERTIFICATE----- MIIBxDCCAW+gAwIBAgIUG6BZ6Ss/0uMfR9f4WUzosxax8tcwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwVTATBgcqhkjOPQIBBggqhkjOPQMACwM+AARikibYB5nt5Y6p v/meRLKurnOEr5KhycGx7JgboJwI64fwfLfKfcitCcJQE5wFVgR66HeEZDeFzKLT 7kajUzBRMB0GA1UdDgQWBBSEn/VPTN1d8ExHdNkdd68gaQc5zzAfBgNVHSMEGDAW gBSEn/VPTN1d8ExHdNkdd68gaQc5zzAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49 BAMCA0MAMEACHgK4gQ0W5gil7+vwAAV8SzRz/pDzVSc/GOCLUA1M3AIeATwvaIY1 /HdwaRQ8u+R1HztOiEY45EE/WVgkZvq0 -----END CERTIFICATE----- 07070100000038000081A40000000000000000000000016537CEF4000002A0000000000000000000000000000000000000004900000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_c2tnb239v2.pem-----BEGIN CERTIFICATE----- MIIBxDCCAW+gAwIBAgIUba5AMdA5P76r0q4/9+1gxK9wDfkwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwVTATBgcqhkjOPQIBBggqhkjOPQMADAM+AARYZ2sLrjHGjSG/ hovu24O3IcZjDRctDqgSX5ToN7puPk2H3pufCbqmj+uCE0v0UdsksQQhiASLe2ZR OzGjUzBRMB0GA1UdDgQWBBQVjnX3zRkhzG13eH8aV3L62fhv1TAfBgNVHSMEGDAW gBQVjnX3zRkhzG13eH8aV3L62fhv1TAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49 BAMCA0MAMEACHhIxDHgINmkMtqu34bUKN5dCe1ivu53woq1vq8h8ZAIeAfR56MZV 1756KkWYyGCKS8wuVrqBcF9tcLR5RnyL -----END CERTIFICATE----- 07070100000039000081A40000000000000000000000016537CEF4000002A0000000000000000000000000000000000000004900000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_c2tnb239v3.pem-----BEGIN CERTIFICATE----- MIIBxDCCAW+gAwIBAgIUOkiOnNGCjbnx40/fIx/hQaalvMwwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwVTATBgcqhkjOPQIBBggqhkjOPQMADQM+AARVh5PChoaxsfOB kfMoiT6WJ1Rua06IcCmomeaT2ZlGrRQuNuw0Vn/DBN3eoiRxm3uOU1Y+RPCBxme2 7jmjUzBRMB0GA1UdDgQWBBTuWfdI6Pu3HlCPiteu8cS80MMTSzAfBgNVHSMEGDAW gBTuWfdI6Pu3HlCPiteu8cS80MMTSzAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49 BAMCA0MAMEACHgJJTYPMVS7yUrXZvNxJeJC9YqPFdTPCZmUhgnNyLgIeAJ2UV61S bjLpc4nCZAz2dvKtlwc4sGUM33d6YK5N -----END CERTIFICATE----- 0707010000003A000081A40000000000000000000000016537CEF4000002F1000000000000000000000000000000000000004900000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_c2tnb359v1.pem-----BEGIN CERTIFICATE----- MIICADCCAY2gAwIBAgIUEe5HgAFAmFHL/Ewo7AVy87eJdScwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwczATBgcqhkjOPQIBBggqhkjOPQMAEgNcAAQ87asvUyddSwuz fxhoFrxJGH86qQzUIUsn+2ReWWN/qx4Bfy+Y3JAPdSjHYVtmG/+6Kv7K/u6OcVrH rnZ6pZDRcwzEDnilqetGMubPNHHjCAs6Eb4kTXJ+M/yjUzBRMB0GA1UdDgQWBBQH 1r8zCEi9Eq0UdrpM7f6SoUd5PzAfBgNVHSMEGDAWgBQH1r8zCEi9Eq0UdrpM7f6S oUd5PzAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA2EAMF4CLQGa2WMTj7rF haeUdWrzenhBFP2BR7MAPP772otKeFriqEB8BZcJIkR5Mv5aGgItAUMUTQ4Yr6Mz DV2qWiRL7F+fURUjQ+ewPE7E7hbShgtfFM3YluFIsZhhEOE0 -----END CERTIFICATE----- 0707010000003B000081A40000000000000000000000016537CEF400000322000000000000000000000000000000000000004900000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_c2tnb431r1.pem-----BEGIN CERTIFICATE----- MIICIzCCAaCgAwIBAgIUC8ryFNQ8fqECqiEIElLbpQUgzBMwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwgYUwEwYHKoZIzj0CAQYIKoZIzj0DABQDbgAEWccVXkcjk0JH qy+HGyboQ0Ht4s4tDkHJ5vWaFsuDWQcX06L9Bq4YKq4I5D6I1EhDl7e7Xs82TDCK 7cqCvebO4g8Qi0/7Nmn5O1TYdaE3R5zANbnLOer9JXxLiSu0uSJgstoO+svyddat AMLlo1MwUTAdBgNVHQ4EFgQU/qfzSFtrrRBVZGd2Ps7k/c7uiRkwHwYDVR0jBBgw FoAU/qfzSFtrrRBVZGd2Ps7k/c7uiRkwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjO PQQDAgNxADBuAjUA0HE7zaa2r96M3Zdgq2Tb5Ih2DRVMKjt1SM5nUQdwB9qIzCL3 440f+0/aitQaSnEUZcvO6QI1ATkZAo4pwSbBjrXTh3h6ObJR+dpWzHcQoGO0urZs 4e5CHxxueekJNvX/01vDR45jjFLqaMU= -----END CERTIFICATE----- 0707010000003C000081A40000000000000000000000016537CEF400000257000000000000000000000000000000000000004600000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_ed25519.pem-----BEGIN CERTIFICATE----- MIIBjTCCAT+gAwIBAgIUCSO8YZk5Kpr5jgYEE8ZNA92JrqQwBQYDK2VwMDwxGTAX BgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5pemF0 aW9uIE5hbWUwHhcNMjMwNzIxMTI0MzM3WhcNMjMwODIwMTI0MzM3WjA8MRkwFwYD VQQDDBBUZXN0IENvbW1vbiBOYW1lMR8wHQYDVQQKDBZUZXN0IE9yZ2FuaXphdGlv biBOYW1lMCowBQYDK2VwAyEABsqL5Vei1wZ2+pQIViT2DNNfBCBP63v1Q8vODjWk qCSjUzBRMB0GA1UdDgQWBBQpSP/3R4PSs0yQsz9B4ktuC5gLIzAfBgNVHSMEGDAW gBQpSP/3R4PSs0yQsz9B4ktuC5gLIzAPBgNVHRMBAf8EBTADAQH/MAUGAytlcANB AGxEjDztg9GulrV6BoTEwTqpYQj2I3CoiJTVMqdjoa4ZMeEz0738qx5cL6aJUy7S iZJcOlZqDVdvffuND1ia3go= -----END CERTIFICATE----- 0707010000003D000081A40000000000000000000000016537CEF4000002BC000000000000000000000000000000000000004400000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_ed448.pem-----BEGIN CERTIFICATE----- MIIB2DCCAVigAwIBAgIUCRalumJE+Z2gK5+Y5urPSEhIbkwwBQYDK2VxMDwxGTAX BgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5pemF0 aW9uIE5hbWUwHhcNMjMwNzIxMTI0MzM3WhcNMjMwODIwMTI0MzM3WjA8MRkwFwYD VQQDDBBUZXN0IENvbW1vbiBOYW1lMR8wHQYDVQQKDBZUZXN0IE9yZ2FuaXphdGlv biBOYW1lMEMwBQYDK2VxAzoAle5yd60OU+2LCMg/nUIARqvoAGO9RstYTR3ZNSaP uCB8gkDb6QUbLtrZmnxjUDSB7xAD+Sup+4AAo1MwUTAdBgNVHQ4EFgQUmIVYdbYE dsOLFVLXC8sEFzgwC0owHwYDVR0jBBgwFoAUmIVYdbYEdsOLFVLXC8sEFzgwC0ow DwYDVR0TAQH/BAUwAwEB/zAFBgMrZXEDcwAT+KmGe8PGnGJoTMWtPcILEDXeaFxj 2mkFZjYQt3U0H3CKDBml8nbOYBL+VmJ20YpqkDOGbZbwIABgLq5ssbO3bsp8Gv3T z6W5ixPj8HTppbHS/YwWKqds78ym5QOg/XeH53x51GRxQZmrRBUt6m1TPwA= -----END CERTIFICATE----- 0707010000003E000081A40000000000000000000000016537CEF400000284000000000000000000000000000000000000004900000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_prime192v1.pem-----BEGIN CERTIFICATE----- MIIBrjCCAWOgAwIBAgIUIikVvb3fodJ0ao3F7MlVobxeDUQwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwSTATBgcqhkjOPQIBBggqhkjOPQMBAQMyAASCZ2z5vstBT4xx MR6U7pXUlrj86gymitoiHdwOc3fF29bjvcToLBLn0mU2EbkS1BOjUzBRMB0GA1Ud DgQWBBSkEjC9gOFnlOHdRTlhjLu1J3Q/rTAfBgNVHSMEGDAWgBSkEjC9gOFnlOHd RTlhjLu1J3Q/rTAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCAzkAMDYCGQCs st/csFWJH4sV5/EIyJdyp6Zkz/zhvWcCGQC46xZH+TappTvsiC9yC8ocw03BLyB7 /Zo= -----END CERTIFICATE----- 0707010000003F000081A40000000000000000000000016537CEF400000284000000000000000000000000000000000000004900000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_prime192v2.pem-----BEGIN CERTIFICATE----- MIIBrTCCAWOgAwIBAgIUbgqD+3iGV1FmWzij6rvZ3lVCG/gwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwSTATBgcqhkjOPQIBBggqhkjOPQMBAgMyAAT5E1A5Q/b0Pr/N 8UXuzABz2SF86GKrJ0ItzjWuSCQK4FaYvUZ/giXsSZyXO2BHcyijUzBRMB0GA1Ud DgQWBBQaJ/W9F2AdWHk+PkvLKXCl6rZ8SzAfBgNVHSMEGDAWgBQaJ/W9F2AdWHk+ PkvLKXCl6rZ8SzAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCAzgAMDUCGEUv YxcupJoxtRXrpZlgJOigjkSRuT2O/wIZANwNld3h0kW5i6KoX10qDsk1NhXeSYk9 Xw== -----END CERTIFICATE----- 07070100000040000081A40000000000000000000000016537CEF400000284000000000000000000000000000000000000004900000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_prime192v3.pem-----BEGIN CERTIFICATE----- MIIBrTCCAWOgAwIBAgIUaKpqg5NQVuL1uHFhq+EvDHx2dFQwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwSTATBgcqhkjOPQIBBggqhkjOPQMBAwMyAATt4Ts6/IqgjTtj 5t5mh7ycbura9opM+ozL9uNS7cWv+Lpuy+/gy5o3eKisZRjjApqjUzBRMB0GA1Ud DgQWBBROYr5N2Ztd8Cfb84LU4u/ozixBYDAfBgNVHSMEGDAWgBROYr5N2Ztd8Cfb 84LU4u/ozixBYDAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCAzgAMDUCGQCK PQiH1xt+XBxEI9u0SM+YTA5wQqqfgf4CGGdjZyZl5sMhL784OCXWDV4Fj9IbA92r hw== -----END CERTIFICATE----- 07070100000041000081A40000000000000000000000016537CEF4000002A0000000000000000000000000000000000000004900000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_prime239v1.pem-----BEGIN CERTIFICATE----- MIIBxDCCAW+gAwIBAgIUT+aC/BwpPXj95wPGuYO/9kiy08MwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwVTATBgcqhkjOPQIBBggqhkjOPQMBBAM+AAR/hhOgFkII8IZP urWSH37h7Q04JaJ7InCWeoGA1h5ojw/0Xvdea0/ETjkPVhKxQMgJOSMJB4ShJ8cU MnWjUzBRMB0GA1UdDgQWBBTqEILgVIj81l961KSFbHU7I1rT8jAfBgNVHSMEGDAW gBTqEILgVIj81l961KSFbHU7I1rT8jAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49 BAMCA0MAMEACHiElS57/p9c2zDcWjwgF8MhvqmwZgeElLTj6LmUSwQIeEADtHP+N 97u65dppS9wLQdg4UrhIwHncmbt0Evdx -----END CERTIFICATE----- 07070100000042000081A40000000000000000000000016537CEF4000002A0000000000000000000000000000000000000004900000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_prime239v2.pem-----BEGIN CERTIFICATE----- MIIBxDCCAW+gAwIBAgIUEsrXzXwSUf6eO4wcoZX/VLObtsMwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwVTATBgcqhkjOPQIBBggqhkjOPQMBBQM+AAQeR7MIbfudXtOa UikeRW4nIgwHpQC6vbPxqR/2BHIbUcBHtKgCyu6Veu8N7wonP855AybMET9oyoL4 ZeqjUzBRMB0GA1UdDgQWBBSD0FNXT1EZlR/td/1XIy+bqtiD+TAfBgNVHSMEGDAW gBSD0FNXT1EZlR/td/1XIy+bqtiD+TAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49 BAMCA0MAMEACHmmalPoLEoEJevUHo2Hej6BeXecxSBizYPmOV2HJPwIeCyML5hRA sB/gyvE0GyVlGY7MOS85HMVuYWEyxHrS -----END CERTIFICATE----- 07070100000043000081A40000000000000000000000016537CEF4000002A0000000000000000000000000000000000000004900000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_prime239v3.pem-----BEGIN CERTIFICATE----- MIIBxDCCAW+gAwIBAgIUDMoPnnhTCnSUzHC3L4OVaiTDGvYwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwVTATBgcqhkjOPQIBBggqhkjOPQMBBgM+AAQ+bpWATJurpVBj HuLSbVYNuK9YVUfT3Z7Z95+c/msU3vvh9f0AkpdUX/7UXHELIxgxqIKjvzcAkTow Cn6jUzBRMB0GA1UdDgQWBBQZ9xHeelsLS0LYC7kC5/CKoN4A9DAfBgNVHSMEGDAW gBQZ9xHeelsLS0LYC7kC5/CKoN4A9DAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49 BAMCA0MAMEACHljWGci9mm0kgsTZg8eLfdoImaTKNp52lIXzKAZl6QIeJchWisSo DbdVW1MXeHF7HTXnf2WpQhrOhOjCHndY -----END CERTIFICATE----- 07070100000044000081A40000000000000000000000016537CEF4000002B0000000000000000000000000000000000000004900000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_prime256v1.pem-----BEGIN CERTIFICATE----- MIIBzjCCAXOgAwIBAgIUe7KVfHSJQdJC0DBhd34MyO+8p1cwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAST8APRK4cJQRik 0CAmk8b2iaXrLTNkxnhQVKM9qiLQRMFzNo3eODEGdgprRcjkV6CT6T3KNbGjD08E 2MuA0zlbo1MwUTAdBgNVHQ4EFgQUvZ00NZQqcyQHfTkHkhCNxGTb/qwwHwYDVR0j BBgwFoAUvZ00NZQqcyQHfTkHkhCNxGTb/qwwDwYDVR0TAQH/BAUwAwEB/zAKBggq hkjOPQQDAgNJADBGAiEAkfE7QoR3jxpz8ZQZdm/JFvDH29A4VBGJuBltD3PCheMC IQDdMWLLNZZwVIN5/k180l9HzUSKB7LKioSGhxFjuDu9kg== -----END CERTIFICATE----- 07070100000045000081A40000000000000000000000016537CEF400000247000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_secp112r1.pem-----BEGIN CERTIFICATE----- MIIBgjCCAUygAwIBAgIUP/LBEPqT06dk2Bt4LJ4zmbNmmWAwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzVaFw0yMzA4MjAxMjQzMzVaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwMjAQBgcqhkjOPQIBBgUrgQQABgMeAAS7smMhJDomMD/13wb+ fltUYBLQvUU0c7q4HIZAo1MwUTAdBgNVHQ4EFgQUGHnhBcdfQN0iFR/kD30EwqX/ t9kwHwYDVR0jBBgwFoAUGHnhBcdfQN0iFR/kD30EwqX/t9kwDwYDVR0TAQH/BAUw AwEB/zAKBggqhkjOPQQDAgMkADAhAg47YYE2UwVT7pmeuuPlBAIPAL6puIf8Sn0b cgeA2I0R -----END CERTIFICATE----- 07070100000046000081A40000000000000000000000016537CEF400000247000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_secp112r2.pem-----BEGIN CERTIFICATE----- MIIBgTCCAUygAwIBAgIUV+mR2BTRCKN3588EagDa7Hb+0CAwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzVaFw0yMzA4MjAxMjQzMzVaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwMjAQBgcqhkjOPQIBBgUrgQQABwMeAASyTva3RCIwzc5UdND+ H5Vmy6aZ2xE4MCs/x/nso1MwUTAdBgNVHQ4EFgQURanOusIQNrzLWhUperx+KjrW E9owHwYDVR0jBBgwFoAURanOusIQNrzLWhUperx+KjrWE9owDwYDVR0TAQH/BAUw AwEB/zAKBggqhkjOPQQDAgMjADAgAg42qeMuYV13XwqrVWspegIOLyQY3KMWfia2 lzqcqpw= -----END CERTIFICATE----- 07070100000047000081A40000000000000000000000016537CEF400000253000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_secp128r1.pem-----BEGIN CERTIFICATE----- MIIBijCCAVCgAwIBAgIUZPvBIEQKmioGoNBuBuC7VoKQd6cwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzVaFw0yMzA4MjAxMjQzMzVaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwNjAQBgcqhkjOPQIBBgUrgQQAHAMiAAQo4z8U7aH++Mk7gh9O 8QjSiYwhN7yFtp2os9PtG5C6KqNTMFEwHQYDVR0OBBYEFNEnFYiQBQCxpWclTsua PMVm7UVAMB8GA1UdIwQYMBaAFNEnFYiQBQCxpWclTsuaPMVm7UVAMA8GA1UdEwEB /wQFMAMBAf8wCgYIKoZIzj0EAwIDKAAwJQIQccMnxKlUqAk2PzobgkYbnwIRAJ95 XwkU4kVvcIcS4dbMQI0= -----END CERTIFICATE----- 07070100000048000081A40000000000000000000000016537CEF400000253000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_secp128r2.pem-----BEGIN CERTIFICATE----- MIIBiTCCAVCgAwIBAgIUc8w3akhUn0Q43UoiWn4ctf+SZNwwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzVaFw0yMzA4MjAxMjQzMzVaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwNjAQBgcqhkjOPQIBBgUrgQQAHQMiAATvdK5j2s3chS2nd4vV v75RWl/VslgaC6wNUpKaPvGNyqNTMFEwHQYDVR0OBBYEFDGiONB0S6WAUMvG1sB4 OBikVgG1MB8GA1UdIwQYMBaAFDGiONB0S6WAUMvG1sB4OBikVgG1MA8GA1UdEwEB /wQFMAMBAf8wCgYIKoZIzj0EAwIDJwAwJAIQDocF/07EL37nn1LTChIEfQIQCPLB DdI/HYHFWUys8FdKEg== -----END CERTIFICATE----- 07070100000049000081A40000000000000000000000016537CEF400000267000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_secp160k1.pem-----BEGIN CERTIFICATE----- MIIBmjCCAVigAwIBAgIUMws/lfOml106JHXyPWxNhDEIG9UwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzVaFw0yMzA4MjAxMjQzMzVaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwPjAQBgcqhkjOPQIBBgUrgQQACQMqAASEC9Y73+nP5YSfM4Ia rvqlHrQrAuVLnL5f0zeilh3xWob2brwKbWdso1MwUTAdBgNVHQ4EFgQUjYuA/wrZ f1BeF139hUzKzbA8CoYwHwYDVR0jBBgwFoAUjYuA/wrZf1BeF139hUzKzbA8CoYw DwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgMwADAtAhRvR4W1iUtPkBzi+/GC SZfXBOivQQIVAKlf6GgqOPHGs4DpKl8hhuW1YVhA -----END CERTIFICATE----- 0707010000004A000081A40000000000000000000000016537CEF400000267000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_secp160r1.pem-----BEGIN CERTIFICATE----- MIIBmTCCAVigAwIBAgIUQ7Ko8C02B7zZbpgFDhRqseTzGngwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzVaFw0yMzA4MjAxMjQzMzVaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwPjAQBgcqhkjOPQIBBgUrgQQACAMqAAQAnQ+Q78PTPOsMkuey 8zRdPus34nP9Y+qbcwTVDjCSpU5k1EhG62yyo1MwUTAdBgNVHQ4EFgQUvadbqXC1 lv/28vyWC1m8JCZPNFYwHwYDVR0jBBgwFoAUvadbqXC1lv/28vyWC1m8JCZPNFYw DwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgMvADAsAhRXz+yMOGCcmbwSJJIq pwCCA00XLQIUO+pVP6Ih4hJvoFUgyeHgac79OhE= -----END CERTIFICATE----- 0707010000004B000081A40000000000000000000000016537CEF40000026B000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_secp160r2.pem-----BEGIN CERTIFICATE----- MIIBmzCCAVigAwIBAgIUVqJ1hRe3R11wacNSpC/4IF+nJVYwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzVaFw0yMzA4MjAxMjQzMzVaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwPjAQBgcqhkjOPQIBBgUrgQQAHgMqAAQ9GRPGvpj/4SmuK1So abV6mFMt8bI7Sdbnp+kwN8bxP1ST5UG9EUvFo1MwUTAdBgNVHQ4EFgQUoDkyvDwQ vJbn4Q4F4JgXjXaFWd8wHwYDVR0jBBgwFoAUoDkyvDwQvJbn4Q4F4JgXjXaFWd8w DwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgMxADAuAhUAxuIGbztQTz7VcV4u yUxWHH1YxCgCFQCBoMUscwGTyfpBtOuG19BWxpteMg== -----END CERTIFICATE----- 0707010000004C000081A40000000000000000000000016537CEF40000027B000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_secp192k1.pem-----BEGIN CERTIFICATE----- MIIBqTCCAWCgAwIBAgIUErCNIQWiLFHnaZ583Rkq3+E1PiMwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzVaFw0yMzA4MjAxMjQzMzVaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwRjAQBgcqhkjOPQIBBgUrgQQAHwMyAARWb6xIF26S8P64Ms4z UuXU2udA82XWdPQS9pvNRK/IAxusZbgTdoDj39i3GiT+xDCjUzBRMB0GA1UdDgQW BBTStmts61uERlHmXiSMBaOrGdrbQDAfBgNVHSMEGDAWgBTStmts61uERlHmXiSM BaOrGdrbQDAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCAzcAMDQCGGF5Fm9r 2aN5m5bmyPpeFEFTOYPmFSMZegIYfQbTiJS/BBsC0gK+MRdbDY1GmcdRO2dS -----END CERTIFICATE----- 0707010000004D000081A40000000000000000000000016537CEF400000294000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_secp224k1.pem-----BEGIN CERTIFICATE----- MIIBuTCCAWigAwIBAgIUFBfu9tZaHqKlismpDyTdndkrGEMwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzVaFw0yMzA4MjAxMjQzMzVaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwTjAQBgcqhkjOPQIBBgUrgQQAIAM6AASavq/DYTGtEFGd8a3q E1de5DI0tILlOyRR+CcsrcKAz/uZjSYgk8pDyZWilVTuL9/xYeZft+JUJqNTMFEw HQYDVR0OBBYEFGsx5cWedLwTExNhf5+VugJkl0X9MB8GA1UdIwQYMBaAFGsx5cWe dLwTExNhf5+VugJkl0X9MA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDPwAw PAIcfl6kUMmSp+wMMX+8erBUIXHISFeEhDOfoCQZpgIcG5zh1rwZUS5rH+1KvFqj zETWl+gYaFKQIEtP4g== -----END CERTIFICATE----- 0707010000004E000081A40000000000000000000000016537CEF400000294000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_secp224r1.pem-----BEGIN CERTIFICATE----- MIIBujCCAWigAwIBAgIUP19W4dOU2bhJLV8tmtQfc3H3FdwwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzVaFw0yMzA4MjAxMjQzMzVaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwTjAQBgcqhkjOPQIBBgUrgQQAIQM6AATI/IY4rlEq8wewJAXf so9eblfUH11k/8U8ZAXrxrlGKkxqFHg3OrwOZlFpTexViV8+5xXPE4ZjFaNTMFEw HQYDVR0OBBYEFIONCY0xqS0gQd3JD8C9pH7pqcD3MB8GA1UdIwQYMBaAFIONCY0x qS0gQd3JD8C9pH7pqcD3MA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDQAAw PQIcf9ZT7OxPCm/n3TUAC+AnXF/mGB8zTp5xldbBvQIdAM4GvoMqH8Tgi7mSGlSl IWZNxh8GgrCVDT8NZJU= -----END CERTIFICATE----- 0707010000004F000081A40000000000000000000000016537CEF4000002A8000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_secp256k1.pem-----BEGIN CERTIFICATE----- MIIByTCCAXCgAwIBAgIUe/G+yvPim7doKmclFt7xjmKA7N8wCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwVjAQBgcqhkjOPQIBBgUrgQQACgNCAASFGUS2HWICrjFJThXo lIGuJOc1T6Pi8OI5T6laa/IgxFKJ8Xujrsp+5K6XTcfsaZcc4E0zgOop/nXJL538 2HZco1MwUTAdBgNVHQ4EFgQUx4nxZi4l55dQ5nTKsVtdgS9Ek3owHwYDVR0jBBgw FoAUx4nxZi4l55dQ5nTKsVtdgS9Ek3owDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjO PQQDAgNHADBEAiBhVJuV90qc30EaeisvKtuzYtZz9O44/dDEhOlXwUFT2AIgTpSl TTh1MoS1+NKPD64EvayrUkCA9J1kSeCLz4Hnw88= -----END CERTIFICATE----- 07070100000050000081A40000000000000000000000016537CEF4000002FD000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_secp384r1.pem-----BEGIN CERTIFICATE----- MIICCTCCAZCgAwIBAgIUApp6h02un7OnAQDldrY7qMTN2QMwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATA+2ces9DsLClv4mZR eb5rsxCMY4cQ5Q0j3ux8kQe6M+P7DGh8zCS6zNw0PSOKvSdaWJ7URYrNzY0LwspX HpKkJfdusc+7h4CgwpDEBnTFE7LXrFoBUaz/0yzgNLP/nhujUzBRMB0GA1UdDgQW BBRLgGH+O56mFXTBfUd86l6c5TJonDAfBgNVHSMEGDAWgBRLgGH+O56mFXTBfUd8 6l6c5TJonDAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA2cAMGQCMAG+V/61 QkaZHVXrF2x+5OEV/xckJNJC74DDXGrms0Cnz0g/gvzKrWl7UcIqo0vQ/gIwY24l eSiquePiR+M9pNbj6mYYLsLHRUXIYf2Ol3gyecLa/yXbvUVrfqUogW3l1NOu -----END CERTIFICATE----- 07070100000051000081A40000000000000000000000016537CEF400000363000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_secp521r1.pem-----BEGIN CERTIFICATE----- MIICVDCCAbagAwIBAgIUHP21jJRAg192g4rUIC1R1um9v24wCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABAAOh7kjT2uDK3a8 azLcgtotDFeM17GkxVxpGiM0wR0supXbNYCW3hI6ZpjaUs5sNVIj3oJ+io/yXKCw wLjtVa/a/QBVwCIZRfVpaEe2msCLWSaCrrlzLKHtpbqFt8ecdZYRpGSlrduZztLt nig4jT+2D4D2FfDBMEKRQNb7Nasaw7Ik6aNTMFEwHQYDVR0OBBYEFLDwB6iFX4N8 EjaUlAAjJvwIrjo/MB8GA1UdIwQYMBaAFLDwB6iFX4N8EjaUlAAjJvwIrjo/MA8G A1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDgYsAMIGHAkIBPB7fCJrbavgm0iuj FfPYMTlhufGswoPXZ3Z+l+Qhlq7JBl23TMCJl+JZ0by5mjTJ6ra0nbq3CHbLEuhe XhocQxoCQSOY2fSzgp1fCTNVsK1mGl9YYuipozjBcVWYe0FUI0TouZ6Vc9OMKJVn IEkqUq2yjA4IrddTKI+kc/5pFtDEZs3i -----END CERTIFICATE----- 07070100000052000081A40000000000000000000000016537CEF40000024B000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_sect113r1.pem-----BEGIN CERTIFICATE----- MIIBhDCCAU6gAwIBAgIUB/CIoSfWjyCYbQCwtU1JU26mPQ4wCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwNDAQBgcqhkjOPQIBBgUrgQQABAMgAAQB/FyHojMNWjAGFOni 9nUB8T/EXM+LtzsSznFidEqjUzBRMB0GA1UdDgQWBBSrGZ6HvOGMMSaxDLcdbKJ/ EFJ6KzAfBgNVHSMEGDAWgBSrGZ6HvOGMMSaxDLcdbKJ/EFJ6KzAPBgNVHRMBAf8E BTADAQH/MAoGCCqGSM49BAMCAyQAMCECDn8GkFdimozAjt1fDtnMAg8A6mT26ctl j4xpnd8ZK3s= -----END CERTIFICATE----- 07070100000053000081A40000000000000000000000016537CEF40000024B000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_sect113r2.pem-----BEGIN CERTIFICATE----- MIIBgzCCAU6gAwIBAgIUdsys+K/rXPJNmg0i244EeI8WPZ8wCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwNDAQBgcqhkjOPQIBBgUrgQQABQMgAAQBnO0l5FaHwcRNy8XY 2LcAney6xv2U3eDU/ZmupHujUzBRMB0GA1UdDgQWBBTCbrNZcO20mIDLV76rNO1n fBiFHjAfBgNVHSMEGDAWgBTCbrNZcO20mIDLV76rNO1nfBiFHjAPBgNVHRMBAf8E BTADAQH/MAoGCCqGSM49BAMCAyMAMCACDir+6YXCRvSXwmGiY/KKAg4XATtl62JS rfOMMDSu2g== -----END CERTIFICATE----- 07070100000054000081A40000000000000000000000016537CEF400000257000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_sect131r1.pem-----BEGIN CERTIFICATE----- MIIBjTCCAVKgAwIBAgIURo3ly3EXnaKFgiG47DivjWRw3TAwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwODAQBgcqhkjOPQIBBgUrgQQAFgMkAAQGUWyx3WXRzMsXYbEA 5Ih2LgLs88hHNNmqg6D9qs0shCaDo1MwUTAdBgNVHQ4EFgQUSvjhN3O65VDtJP1X iCZBDG5jbqMwHwYDVR0jBBgwFoAUSvjhN3O65VDtJP1XiCZBDG5jbqMwDwYDVR0T AQH/BAUwAwEB/zAKBggqhkjOPQQDAgMpADAmAhEAyySZ9hbM3I4bI2A4ABB+JwIR A197rTXvv5C8XzzyiwqAYdQ= -----END CERTIFICATE----- 07070100000055000081A40000000000000000000000016537CEF400000257000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_sect131r2.pem-----BEGIN CERTIFICATE----- MIIBjTCCAVKgAwIBAgIUVhq1ZiobrJ+HshVNzzcc8jNDIWMwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwODAQBgcqhkjOPQIBBgUrgQQAFwMkAAQClf5whvEzQOM9qi/w LobyCgNw0DlV/JNYfMWROf5c31iDo1MwUTAdBgNVHQ4EFgQUFRPu4Lhr704q5yfE Pam/rzvU2hswHwYDVR0jBBgwFoAUFRPu4Lhr704q5yfEPam/rzvU2hswDwYDVR0T AQH/BAUwAwEB/zAKBggqhkjOPQQDAgMpADAmAhECQZUlsn5NVf8xhACqkQelmQIR Andvdo9ZKQjU78hsa05ohNA= -----END CERTIFICATE----- 07070100000056000081A40000000000000000000000016537CEF40000026B000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_sect163k1.pem-----BEGIN CERTIFICATE----- MIIBnTCCAVqgAwIBAgIUG8GAOtG4iFNSqHwWymEBsM4sSdIwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwQDAQBgcqhkjOPQIBBgUrgQQAAQMsAAQGgramA8Uv29oCJX2C DIFzY0+BhM0FXe52TBi7AqEOmL9fPAiBJ6hirGqjUzBRMB0GA1UdDgQWBBRMvtjX 9ZzWvdOTsZ/YnD5/VfcEODAfBgNVHSMEGDAWgBRMvtjX9ZzWvdOTsZ/YnD5/VfcE ODAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCAzEAMC4CFQCpmUbrxMV1e1UH UZxoJ1q36jY+KAIVA/19jtFoZu6JOjzpmIcwCNtqkZd/ -----END CERTIFICATE----- 07070100000057000081A40000000000000000000000016537CEF40000026B000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_sect163r1.pem-----BEGIN CERTIFICATE----- MIIBnTCCAVqgAwIBAgIUB9mc6jr9QWwJjJ13fzF3Cv7/05AwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwQDAQBgcqhkjOPQIBBgUrgQQAAgMsAAQF85Bl3ReviMercgmY CZsROkvQ0UoApDmT5xWtSAvDj+sq9y7j99ctzOGjUzBRMB0GA1UdDgQWBBS3caVd 4OF7XE/YiUaWZO+Cus8saTAfBgNVHSMEGDAWgBS3caVd4OF7XE/YiUaWZO+Cus8s aTAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCAzEAMC4CFQCb5iYisbyRWB29 lrzTFkhleclsvAIVATpS2wXkAul3kEUj+Meoq+tUrHyY -----END CERTIFICATE----- 07070100000058000081A40000000000000000000000016537CEF40000026B000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_sect163r2.pem-----BEGIN CERTIFICATE----- MIIBnTCCAVqgAwIBAgIUeRVVFd3hYr3cSNZt8sGz6C0anJEwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwQDAQBgcqhkjOPQIBBgUrgQQADwMsAAQCjMMHnusbLf0BCLN+ cHFMkth5TAEAwtv1BMO7LfwR+JZtsPKAiv6Z32+jUzBRMB0GA1UdDgQWBBSCq78q ykYzZ8vCvtCR/O1anVnPFTAfBgNVHSMEGDAWgBSCq78qykYzZ8vCvtCR/O1anVnP FTAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCAzEAMC4CFQHJm6qlQTGPI14s 6XH7loDA51KxswIVA33t23ya5iltdJ/YZuBWlKLkMsHn -----END CERTIFICATE----- 07070100000059000081A40000000000000000000000016537CEF40000027F000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_sect193r1.pem-----BEGIN CERTIFICATE----- MIIBqzCCAWKgAwIBAgIUP2U3OcO2kEtWW6DnlseUNwHI5SswCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwSDAQBgcqhkjOPQIBBgUrgQQAGAM0AAQBwqAABi5MR6Xv89AA 6/qPcPqgEZsyaWUfAIfhmafmMWckaMxlIivDw8ptsF4v/Wg+pqNTMFEwHQYDVR0O BBYEFLCw576/NQRVA39dikzNcKHU+l3MMB8GA1UdIwQYMBaAFLCw576/NQRVA39d ikzNcKHU+l3MMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDNwAwNAIYOif8 eEYzJ1WWzo+kw9rizcelsHYkev/0AhhRmFsczQcsLxh14vYC/NIjOkmKhUqjEik= -----END CERTIFICATE----- 0707010000005A000081A40000000000000000000000016537CEF40000027F000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_sect193r2.pem-----BEGIN CERTIFICATE----- MIIBrDCCAWKgAwIBAgIUC6JHmtSMpp3Ee4a4RZlou0Qb1rEwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwSDAQBgcqhkjOPQIBBgUrgQQAGQM0AAQA2ON6V9uEm8nW98hY vmjajMrbUvvr4xq3AKPy/mxxMqH/6dq3z2TxlkIqGICPnyUCMaNTMFEwHQYDVR0O BBYEFBpd0U5H3nQGXxHkJTTZfgHpmVeHMB8GA1UdIwQYMBaAFBpd0U5H3nQGXxHk JTTZfgHpmVeHMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDOAAwNQIYDl0Z KSo9Rgyky8qvU/bUUn3tAVRQmRUaAhkA6CzPo8Y86/Iax6Zk4KWVbbjjIVGkbKQe -----END CERTIFICATE----- 0707010000005B000081A40000000000000000000000016537CEF400000298000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_sect233k1.pem-----BEGIN CERTIFICATE----- MIIBvjCCAWugAwIBAgITNI3WtNMZhqo7C1PEr2Zytj1rZDAKBggqhkjOPQQDAjA8 MRkwFwYDVQQDDBBUZXN0IENvbW1vbiBOYW1lMR8wHQYDVQQKDBZUZXN0IE9yZ2Fu aXphdGlvbiBOYW1lMB4XDTIzMDcyMTEyNDMzNloXDTIzMDgyMDEyNDMzNlowPDEZ MBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdhbml6 YXRpb24gTmFtZTBSMBAGByqGSM49AgEGBSuBBAAaAz4ABAAeO9zFl0eb88kQQMIi eMG3fRyPKl4dUs3oUCElBgGw8p06S4r9NH21IFOzYc/MnV/eVnFArL7G7Vir06NT MFEwHQYDVR0OBBYEFII6owZgnNf7zuYzQX4mPZEcZ7foMB8GA1UdIwQYMBaAFII6 owZgnNf7zuYzQX4mPZEcZ7foMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwID QQAwPgIdbyM1hwcVIJSUIuOyV8PlxzXfyCG9nyrECNEOS1cCHU4rzzbAxS9AUrES rE64VZuswltFwY52MUqFTU2l -----END CERTIFICATE----- 0707010000005C000081A40000000000000000000000016537CEF40000029C000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_sect233r1.pem-----BEGIN CERTIFICATE----- MIIBwDCCAWygAwIBAgIUXafaDsS6qqOTW46cNHEzB2QfCFQwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwUjAQBgcqhkjOPQIBBgUrgQQAGwM+AAQAv4WQvVJuaJV8Iy4g We9sFuytOHoGpX991m0/mr0A0XV9Nm7pahoVt3JeYtzbemSNC/zwsiaGu6T+c4Cj UzBRMB0GA1UdDgQWBBT3u1DtOU8wEwt+SczwJP7e0R6uYTAfBgNVHSMEGDAWgBT3 u1DtOU8wEwt+SczwJP7e0R6uYTAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMC A0IAMD8CHgCkugN9xV2FIN+gJzzbt21txakxBTrcbMydhPcbdQIdaJE4nyfnl31L vkHjxzV4WR9NMoyJFNwBEXpewDU= -----END CERTIFICATE----- 0707010000005D000081A40000000000000000000000016537CEF40000029C000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_sect239k1.pem-----BEGIN CERTIFICATE----- MIIBwTCCAWygAwIBAgIUFLdWK7lCP3JnfmSS7FNFbjn+DS4wCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwUjAQBgcqhkjOPQIBBgUrgQQAAwM+AAQ4oVDmkQnB/JS8c7yy Xv1xSMiwyYqjyoI6r2oqrEdh8cc5M+hqgrWF/HrVpCxx2e10u39zeD1smOdwCRyj UzBRMB0GA1UdDgQWBBSNQEzNBH/W/toTRrsZs3THbZtxfjAfBgNVHSMEGDAWgBSN QEzNBH/W/toTRrsZs3THbZtxfjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMC A0MAMEACHgD+8wBbxdZvCzXQaJs0yhmgv/7VYwg/UgdD/jOeEwIeEB+4cauYlQuH IH+jAHLsdXbAekgClhZCTpqg9KeP -----END CERTIFICATE----- 0707010000005E000081A40000000000000000000000016537CEF4000002BC000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_sect283k1.pem-----BEGIN CERTIFICATE----- MIIB2DCCAXigAwIBAgIUE792bxQucjvq4nQKej5SaRxGurYwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwXjAQBgcqhkjOPQIBBgUrgQQAEANKAAQHy78neRBQ6kYQfpDB nLrze77quFs+6Nobims66nUbo+o92psBSzB5SnrgSCnE/PfwQzsuLxlTL/9wn+7y R2k5oiVvJTj6P6CjUzBRMB0GA1UdDgQWBBRr6Mcl0qXB7+4dSnGktY7S8XO8/DAf BgNVHSMEGDAWgBRr6Mcl0qXB7+4dSnGktY7S8XO8/DAPBgNVHRMBAf8EBTADAQH/ MAoGCCqGSM49BAMCA04AMEsCIw2+yF1Le39r9P23rjU5otvM3fiPxVrknwxVle7j LJj+K2eqAiQAxkn9PDgUeCXz03/5AgpaVgHiijx6rkS//kkQClzQWs3z8i0= -----END CERTIFICATE----- 0707010000005F000081A40000000000000000000000016537CEF4000002BC000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_sect283r1.pem-----BEGIN CERTIFICATE----- MIIB2TCCAXigAwIBAgIUD4y5Z4WHlePHCSiQftuMlKNCIZowCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwXjAQBgcqhkjOPQIBBgUrgQQAEQNKAAQGhH4HYLphoG6AdexQ ifb4J0OS7ZlajPDGRclkI8dv1T58bvsFtUNIdK3UInQzlGiMEZkWHbq0Ylr3vFsn VZHjvL259Mk+A52jUzBRMB0GA1UdDgQWBBQkd2s0QaUM04cca/vLDH2Z5z/7ljAf BgNVHSMEGDAWgBQkd2s0QaUM04cca/vLDH2Z5z/7ljAPBgNVHRMBAf8EBTADAQH/ MAoGCCqGSM49BAMCA08AMEwCJAPlQqEQwtFMvV0Gs2G9kUZGaS8TJCMbg94OOilz IVMRnZG4iQIkAVab9Nmt4Ei5LkV+09bh84BBzJE0G07DSXIApuE5OQmWwsvM -----END CERTIFICATE----- 07070100000060000081A40000000000000000000000016537CEF400000312000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_sect409k1.pem-----BEGIN CERTIFICATE----- MIICFzCCAZigAwIBAgIUIpDN+wyN/Gn8DWpKpq03kI/6i5kwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwfjAQBgcqhkjOPQIBBgUrgQQAJANqAAQBXq8P82+QevJOEQcE EaA/nvJ4oWUvQ0swWz2dcCI5cQfREFJgFTPO8w01C8cQw24ss5NoAdnqGtCc2kKO IkOUk5Xxgv3JMAHocG6iDPjX6+jVsuimFckRluWij+SRzZAX02YGTaalK6NTMFEw HQYDVR0OBBYEFF/1IvU/FUqGr8zUo4IMSDIGNLLFMB8GA1UdIwQYMBaAFF/1IvU/ FUqGr8zUo4IMSDIGNLLFMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDbQAw agIzHUAC5Nn35uQkR1oX83m0vPwKPrKpRJ5nU3mNkMOxoslrz4DApY+f5imO4b06 N1KtZwSbAjNK6ZzipDXZKI3P9pS9YWf70djpghLig/vuEMaahbBFDdBSu3W2xFzR xAopwTx26r9Upwc= -----END CERTIFICATE----- 07070100000061000081A40000000000000000000000016537CEF400000312000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_sect409r1.pem-----BEGIN CERTIFICATE----- MIICGDCCAZigAwIBAgIUIh6QMbKo/pwh2i8FfzVwBvCUSvMwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwfjAQBgcqhkjOPQIBBgUrgQQAJQNqAAQAd+Lm77AFg7yPza/a Tkzsk3FA+0MH/U/ZVVXnN+tMmWKXuQMWDnX3xaVg0bD/jC3QLLrPAB/7XQzz2s6K xqexDMFEtCvnGgfHLQEJtJRgIBmn0Aol4gMTvT7rqjUudecXkLTvgzEDT6NTMFEw HQYDVR0OBBYEFBUyuy9cYIkNMx7EmDtytd0BGP6+MB8GA1UdIwQYMBaAFBUyuy9c YIkNMx7EmDtytd0BGP6+MA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDbgAw awIzdKptak/eOpZsrO0GhIfagwtHVOqP1xHUmaB3eQArUxI2QTS4GCnZNhVftoHO 042aeLcAAjQAiE1600pUFEjENo5c7GDbYuMdpzTYbP5ST1aY/8Gh+aDEGi5wOuj2 sTZAOSNNWWefv7iP -----END CERTIFICATE----- 07070100000062000081A40000000000000000000000016537CEF400000388000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_sect571k1.pem-----BEGIN CERTIFICATE----- MIICbTCCAcKgAwIBAgIUCW1T/lPdgKo7gZ/nSJDbJF9ukZwwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwgacwEAYHKoZIzj0CAQYFK4EEACYDgZIABAPF3QP4QPwyjZTv Adef9KvVtXAqgyEBYkr8dIZkFIVu1aOMTQxlAitIcucka0rfK91ww//Wnr4QyEZl 8JFEqB9fffODzN1G6wJPW3MgiNv6FBhZ1983b5RKJ5y5CA7gwhdA94i/3S5xGZxM C10N9XZ0KmjOM2KbsKhn+IfIwuV6N9ccOEwJY+I/Tgxd+Rdx/aNTMFEwHQYDVR0O BBYEFKquPwVf//mVq/c+SBnLkQMebHwCMB8GA1UdIwQYMBaAFKquPwVf//mVq/c+ SBnLkQMebHwCMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDgZgAMIGUAkgA 9O6Fx98AVebyJiCuQSA8Cj3s7C2xOXwHev+vfzymQ54liQXEYfvpqDdmZonPBoW4 xwt6SMV+Tz5coXsdTynxiTl3l/4gFgQCSAGjDeUztZuxbBHDwyr12eY9s7uo5XNY pqugvnrNijw3EnDOiePvBdNxzQF8tkp+fRdDkUD6a0Ve5GfuKo3WJSZEvSZs2Zjr GQ== -----END CERTIFICATE----- 07070100000063000081A40000000000000000000000016537CEF400000388000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_sect571r1.pem-----BEGIN CERTIFICATE----- MIICbTCCAcKgAwIBAgIUZlf+OfohhBAZ7nTYXO+xAJqQxFswCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwgacwEAYHKoZIzj0CAQYFK4EEACcDgZIABAZhvc3WrTpz3raT oICusmY1vCQKJVm4WCNDOTDptkRGB/JrlIGht9as9+BzXKBfbtgldyZDs961fkZn G4POE6Us9s8b5SDSYgUIW9QTnyxPiaNYhthhj72N3xfCf8OymNVMmjA6uHRX+Fcc PJUfQSH5eOXhsOncsBo4GuCvmG+8ukyd/Y+J4eVDeUiabqujD6NTMFEwHQYDVR0O BBYEFEH/O+ZNA5rB6z/ocRYLBUV4mcbYMB8GA1UdIwQYMBaAFEH/O+ZNA5rB6z/o cRYLBUV4mcbYMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDgZgAMIGUAkgC xTegrT5xCDWiwqU+P4iEe12n8gaqHMUpDPbKlYCT+P9VTKfEmpaUDXUjN4cj2iwT uz4rySg4O8bHztZH6VCSq8ZQxKqUl08CSAN/9p4Ki4KcLWwqHnW4dXWjAR/3+iTH Zkuuqn3A0OaHMm4tFY0hVlIYIAocCXu9ooFhlcPTIoTRKC1pJUjSzzYIMCZ9Ior3 Nw== -----END CERTIFICATE----- 07070100000064000081A40000000000000000000000016537CEF40000024B000000000000000000000000000000000000005500000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_wap-wsg-idm-ecid-wtls1.pem-----BEGIN CERTIFICATE----- MIIBhDCCAU6gAwIBAgIUd4AYTS7z8BfqAV6qpPoBT9+M2dswCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwNDAQBgcqhkjOPQIBBgVnKwEEAQMgAAQAFjHnmjwkioP5SuBH 49sBa6VN2FPXD3DjFz08TFWjUzBRMB0GA1UdDgQWBBQiQ3aloNKS/FH8yburHwRX LSrPgjAfBgNVHSMEGDAWgBQiQ3aloNKS/FH8yburHwRXLSrPgjAPBgNVHRMBAf8E BTADAQH/MAoGCCqGSM49BAMCAyQAMCECDwCHBGSws2SaH7TLEPnvGwIOUTL+PVMw wNTljbbVMoc= -----END CERTIFICATE----- 07070100000065000081A40000000000000000000000016537CEF40000029C000000000000000000000000000000000000005600000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_wap-wsg-idm-ecid-wtls10.pem-----BEGIN CERTIFICATE----- MIIBvzCCAWygAwIBAgIUJPrjcAoF2uahKeIQnnHMuPtHW5UwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwUjAQBgcqhkjOPQIBBgVnKwEECgM+AAQBDEOJ/576jb9Bmw/4 dW5vYdKRHGMgs4GBMgMmaa0A8EI2MNxYnLePFe4ItlCeRnL+Ip1KYNdxDC10yQKj UzBRMB0GA1UdDgQWBBRxz36cRUfDbdc/bPCPggWq3Z6IyDAfBgNVHSMEGDAWgBRx z36cRUfDbdc/bPCPggWq3Z6IyDAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMC A0EAMD4CHTQJiG5tmQmZEI+h9sZURBPG3iFI168k59ez2DXbAh1kO0svWRm1/ZCk cs1ui2hmQrx2zKNk1jeZ7OjXvQ== -----END CERTIFICATE----- 07070100000066000081A40000000000000000000000016537CEF40000029C000000000000000000000000000000000000005600000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_wap-wsg-idm-ecid-wtls11.pem-----BEGIN CERTIFICATE----- MIIBwTCCAWygAwIBAgIUfhaWz3yqazdJyelepkrEsAq0agkwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwUjAQBgcqhkjOPQIBBgVnKwEECwM+AAQBkHyssOBn0pWma9ZH Mr3NDQAkfz/zIqQZD+S9uUMACyLN62jrz6XTTWjsqfEy/UOjRbTYLgsgozB29K6j UzBRMB0GA1UdDgQWBBQZaMotu3N1vMoiNXrDJBGe5ukP0TAfBgNVHSMEGDAWgBQZ aMotu3N1vMoiNXrDJBGe5ukP0TAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMC A0MAMEACHgDURvEwmDwzojbV9HWOOaDaqyWfG0iHGxGHSgbIZgIeAJPElWwp0ZLq 4mWZd4cZRNfbjQiRcMdAVO1+GavJ -----END CERTIFICATE----- 07070100000067000081A40000000000000000000000016537CEF400000294000000000000000000000000000000000000005600000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_wap-wsg-idm-ecid-wtls12.pem-----BEGIN CERTIFICATE----- MIIBujCCAWigAwIBAgIUfWRHEIlDxFeExuzUDlP1dyyKjAYwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwTjAQBgcqhkjOPQIBBgVnKwEEDAM6AARbajgITktE8JpjQMty 1YLqAL6dlhfgJZ9iZARIgY5Dt6zqecrMjTRRTsEsNwxCRlWZ+Twsfuqu56NTMFEw HQYDVR0OBBYEFFw8LtyHD2GyC7pZB7m/mFqJes6OMB8GA1UdIwQYMBaAFFw8LtyH D2GyC7pZB7m/mFqJes6OMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDQAAw PQIcAMse3oSk4yCgaM4Ms0BagUYTOdE+OZEk61+yggIdAMOX8EroOOnoM9d9sObx URQzpz7YCDW5Pi4s9Sc= -----END CERTIFICATE----- 07070100000068000081A40000000000000000000000016537CEF40000026B000000000000000000000000000000000000005500000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_wap-wsg-idm-ecid-wtls3.pem-----BEGIN CERTIFICATE----- MIIBnTCCAVqgAwIBAgIUAK15hKyB/bFINxF7CpPdSWZrUWswCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwQDAQBgcqhkjOPQIBBgVnKwEEAwMsAAQE6GrfihXIyXg7Ql00 HUMwuG2HfGgD0Z3ZHuA4hpmaDir/P7LRJrCOcLSjUzBRMB0GA1UdDgQWBBS5V7lb Y/4ZZ4De6vhT9uB6EuQTHDAfBgNVHSMEGDAWgBS5V7lbY/4ZZ4De6vhT9uB6EuQT HDAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCAzEAMC4CFQOGvX7Gj6X6oc86 0cobYj4Axd/D7QIVA0aa+mA89TcHm1lqBJVcIH6YgE/A -----END CERTIFICATE----- 07070100000069000081A40000000000000000000000016537CEF40000024B000000000000000000000000000000000000005500000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_wap-wsg-idm-ecid-wtls4.pem-----BEGIN CERTIFICATE----- MIIBhTCCAU6gAwIBAgIUdkxCkBuXHWjMQVPzn9WAClw1SbcwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwNDAQBgcqhkjOPQIBBgVnKwEEBAMgAAQAQrzaDwHKHSmR1oit NZMAFrIsXg7xhl9nemS4vQajUzBRMB0GA1UdDgQWBBTcmUmXtGFkzlMloWZw/Szr RP/orTAfBgNVHSMEGDAWgBTcmUmXtGFkzlMloWZw/SzrRP/orTAPBgNVHRMBAf8E BTADAQH/MAoGCCqGSM49BAMCAyUAMCICDwCoTUn8D3XyKSeXi4jgQAIPAOh5e4c3 AhNdXsSBViE3 -----END CERTIFICATE----- 0707010000006A000081A40000000000000000000000016537CEF40000026B000000000000000000000000000000000000005500000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_wap-wsg-idm-ecid-wtls5.pem-----BEGIN CERTIFICATE----- MIIBnTCCAVqgAwIBAgIUfFgnQhxJzivk7UF2RuVo9FfCG60wCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwQDAQBgcqhkjOPQIBBgVnKwEEBQMsAAQAaH4NfLzkyeHF0CLM zJLPZc9WueQBF7ZN3Lm8yv4oKZg8uK+SXoZDXIWjUzBRMB0GA1UdDgQWBBTVUg2W Px9NPxYNrCxKbj28+TYaYjAfBgNVHSMEGDAWgBTVUg2WPx9NPxYNrCxKbj28+TYa YjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCAzEAMC4CFQNtP1EKvSUzv7gJ NT8pLi0CLARsLQIVAfFCO7eErwG31MCSp6s7cTpYuXcY -----END CERTIFICATE----- 0707010000006B000081A40000000000000000000000016537CEF400000247000000000000000000000000000000000000005500000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_wap-wsg-idm-ecid-wtls6.pem-----BEGIN CERTIFICATE----- MIIBgTCCAUygAwIBAgIUb8WfJ7BCpOUfBWP1RWRX6JXkEnowCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwMjAQBgcqhkjOPQIBBgVnKwEEBgMeAAQewn/NNS30Q+y7VzPx xTYIBpyRqXnlwtGM3266o1MwUTAdBgNVHQ4EFgQUaJ0TeQ8U3Mv9nTGuHOH3RFWU fuEwHwYDVR0jBBgwFoAUaJ0TeQ8U3Mv9nTGuHOH3RFWUfuEwDwYDVR0TAQH/BAUw AwEB/zAKBggqhkjOPQQDAgMjADAgAg5m1c3XC1CdNYu5Ejt2+gIOUOptavzOUIz/ 5XCf8To= -----END CERTIFICATE----- 0707010000006C000081A40000000000000000000000016537CEF40000026B000000000000000000000000000000000000005500000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_wap-wsg-idm-ecid-wtls7.pem-----BEGIN CERTIFICATE----- MIIBmzCCAVigAwIBAgIUOts+zfLc3yZsICJhs0FjgK0PeXIwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwPjAQBgcqhkjOPQIBBgVnKwEEBwMqAARnqRgnzGQl99ikKN+V M1LYHiIKoSolY+8ALAp0DH9L3cfzi4uJ6V/bo1MwUTAdBgNVHQ4EFgQUJs81UgSn NR+ryF1cgP6mEMZIHZAwHwYDVR0jBBgwFoAUJs81UgSnNR+ryF1cgP6mEMZIHZAw DwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgMxADAuAhUArslOJewOBRt299qW 01+6Lm91SFkCFQDl0lKAD/16jOKSCg6cb/n+LwxIIw== -----END CERTIFICATE----- 0707010000006D000081A40000000000000000000000016537CEF400000247000000000000000000000000000000000000005500000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_wap-wsg-idm-ecid-wtls8.pem-----BEGIN CERTIFICATE----- MIIBgjCCAUygAwIBAgIURfBCmyOLDLO77rW4dNP79xcxXukwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwMjAQBgcqhkjOPQIBBgVnKwEECAMeAASzG5HMiFK6AWURTaHC I0/PAJpkSbQ1oZVgZ5iEo1MwUTAdBgNVHQ4EFgQUeyJN7A/QfCdjqaRfMSgfqvKK UbQwHwYDVR0jBBgwFoAUeyJN7A/QfCdjqaRfMSgfqvKKUbQwDwYDVR0TAQH/BAUw AwEB/zAKBggqhkjOPQQDAgMkADAhAg44AWwUGt2pW1ktKc6TvQIPAIl2KAYn9Dax hdRnpwh0 -----END CERTIFICATE----- 0707010000006E000081A40000000000000000000000016537CEF400000267000000000000000000000000000000000000005500000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ecc_wap-wsg-idm-ecid-wtls9.pem-----BEGIN CERTIFICATE----- MIIBmjCCAVigAwIBAgIUI3877l770dfIB24/Wz1KOPPvpkUwCgYIKoZIzj0EAwIw PDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBPcmdh bml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzZaFw0yMzA4MjAxMjQzMzZaMDwx GTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3JnYW5p emF0aW9uIE5hbWUwPjAQBgcqhkjOPQIBBgVnKwEECQMqAASYv6UnBZYuhZtA7Hwx HIE6ON0fhdvewlbcUqQ+Ps68JKVgmAcK1/XPo1MwUTAdBgNVHQ4EFgQUDv77gAsH e+eU4xiJlUSGboaBx/gwHwYDVR0jBBgwFoAUDv77gAsHe+eU4xiJlUSGboaBx/gw DwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgMwADAtAhUArkmqguEEOBAYc5C0 Cw1AqfzQGAcCFFhESklm3E4YBzbJyKx68ecoAaae -----END CERTIFICATE----- 0707010000006F000081A40000000000000000000000016537CEF400000363000000000000000000000000000000000000004700000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ifc_rsa_1024.pem-----BEGIN CERTIFICATE----- MIICVDCCAb2gAwIBAgIUf/KJufWFlTNT3BJUvr527SWP5yowDQYJKoZIhvcNAQEL BQAwPDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBP cmdhbml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzdaFw0yMzA4MjAxMjQzMzda MDwxGTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3Jn YW5pemF0aW9uIE5hbWUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMMi7d5D iyEsKumYg7Au52lTt4rNH8FmIfLvBF3ejuezbqXRhxPFto1E3+avUkJVRME647Br 42JdjD4OFxIIQ5hzaXGmZYW15jcd9PDMymIaBYlv3rtQf3QeTyONfsvhk9jYgWm3 26uzkkQQe7iibghG4br+WSm9S7G5GQPKsgYTAgMBAAGjUzBRMB0GA1UdDgQWBBQs PvaPKcYYjf4RuF/32OPaZZioBzAfBgNVHSMEGDAWgBQsPvaPKcYYjf4RuF/32OPa ZZioBzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4GBAGxiX2ASvAzT KzWMzNkcMn9T6zKXRAEgWLpR6elbdFwXiSX5SXguy1rVrt8q9KaECub1NqwXKltI pdmnJN/otuo8jw34yM8JoEhOdu0grJxUzwT3iU4ITuIC2TZ8l/XCjdtaCRKffy1s uFBeN7JOhdYr4favb6MNjJNEZKycBj6l -----END CERTIFICATE----- 07070100000070000081A40000000000000000000000016537CEF4000004C4000000000000000000000000000000000000004700000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ifc_rsa_2048.pem-----BEGIN CERTIFICATE----- MIIDWTCCAkGgAwIBAgIUV8HYQm8J630g8awylSYfy8PIH0MwDQYJKoZIhvcNAQEL BQAwPDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBP cmdhbml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzdaFw0yMzA4MjAxMjQzMzda MDwxGTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3Jn YW5pemF0aW9uIE5hbWUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCn oMe7EvKAWKxhAxMkI3f/UQKj7W4vMCKYXx0XfjDhx895TbR00OppHu9u1qLWReU+ rygyWePD/KVtlwVA7AIFxBaSExis5+4KWLX7XofVrVWej975LDwHBtspms3iAxwk RhTJ4qlACuvlomlfBHAMw5hNlc2hN72UDafPw6DkBla2Su48fZaeHVQqEgNrfjlj zOFNQqsUOD8umTz++OO8hozuGuMQOO7LM4CxtfGosm0l/ugyjuQfqdfEFHwhf3in nTVo+grSV0FV6WM5cx12Xb/a4AMWZKK9ON+4/iuQ5KfPznonZmit1XyZsH40UkUN ezry9z2axQ8yOzD5tNCVAgMBAAGjUzBRMB0GA1UdDgQWBBTowTbLxCdXIlgU/n6i B+i4hRJ3cDAfBgNVHSMEGDAWgBTowTbLxCdXIlgU/n6iB+i4hRJ3cDAPBgNVHRMB Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQB4igOfOs9uVTXqvZCEQ+fc+czR Sc0gJZmUK2aM/rHFZV9w5kK4MT8hudhtwV03aBr89eot2fsaql2XtIRJ5hgUHlR6 T5DuA1bivRg4NOx2bXPPV0gwuzZ10xh9rVTTrMJ4+DCmeuhtWpxsK1aq/URNRfrG e76Mxfc/RmNs+fx8+JUBLpR5A16IzngQ2s+FBGP6pIEPgjwtbIfOEEpwXi1aLms1 ilAFrovKKwRxHwC71lhlEA8loql1xRn0QoFeLSAjoHnp7PDBifzeiI6+8FUeAuhO fs6iqaZ1BDhPjqeNdUcrOc0ValkBZCMuGDuhV0vENSHeq40p95HhglIpt9o3 -----END CERTIFICATE----- 07070100000071000081A40000000000000000000000016537CEF40000077B000000000000000000000000000000000000004700000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ifc_rsa_4096.pem-----BEGIN CERTIFICATE----- MIIFWTCCA0GgAwIBAgIUUK14ODf6dqb2LtD8T0HOrPJ/wQUwDQYJKoZIhvcNAQEL BQAwPDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBP cmdhbml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzMzhaFw0yMzA4MjAxMjQzMzha MDwxGTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3Jn YW5pemF0aW9uIE5hbWUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC1 aHG/P5abHEqrzXyyeXPHJGp/M2ZCrDcpUbtIcKVJS/PKW14O+ElXSM0w2JkJu9mt 0HztQhc5hJu4w8K4acTIPnKDzL947tX0ilMQRvKu9vTV+BA5z4Y29qwj3L/t72wh 8k8V2zUWDbAqJIJR1mhX+eUcu/xCGN7IBFpFeg/Vu3XEA9jIe8a78xh6GErDF4tA r8msTRx/21yRccnoVwC46lU/bXUAV9orK6RWy/6CCAlTMp4xtqpLy2jcTCY/++0m 4I3ooMlLVQ0C1b5rk8fv1znu2HO8/TuJJ4Y77ZSnX5CJWTK4ddrU8MjgAoIdVsNr 39a/Z5iOfqcKaOVdym4y9SR9UvHwCDDERkSekPCR0yS8nOTpInWia0kyTYqv9LVL 6iuqB856uY1lqsIcaHZik3Vqn5pm94BHwinrhPQFp/VxlhqJ+gK9T8FU29D7Al97 iuCzmKbHS8TUHTpVudkKGpQvf2Kf0r9wnSH7cbA32nvanktQ842k8lMLuwriGecE 4N6vPMCpiqI79wARDAYIIQ99N995caB3rorAmE0iDGsOjQKzBvAWMvwUQ2Fb9TAg tvfCKUBrGTcGkafXuhjklo3A0XvGcfIG2k/4cNnhHu7gc6pQ3DdH4F75ug9gLJbp cXbSdtl0par3ivJq0ImoUbZ4PfhvOS8UH5dcMmkJowIDAQABo1MwUTAdBgNVHQ4E FgQUKLFpxOeofSK5U++L1tLNWcxRJqEwHwYDVR0jBBgwFoAUKLFpxOeofSK5U++L 1tLNWcxRJqEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAm80/ TmKMHCdZ9B5uGGnBIQdEZklSOvAMhrueIfh+36OE476gROCoNjs144YkrXC14W+6 /MB3boUUeya+7ZsOFlmXdWvyp/r02bJ1Gw/GcHyHhyAOzZNoECfCk8VSmAFJG8ht 69GQwk+eeL6tZ9GqdXkvlkd1RVUbTVnkA95bPb5Bn5mNB7toP5oEyoPlcxMTSbuM I+r21MH7PlsIQZr51AahvIeGijKqUPZCxAgGuRCzoo3LYgbLO6/n3uRqtMebS/lQ UdgY7HpCEhjjJAMTo6eSiVsCol8d+jSL4QeO5zfC1lyK5v1bZFZZuWsYYAjR2N/2 OxjnQuq5ZYUmp+F4k5EWzNBV8oAv1MYBp6Ivg2xTNDSHZggzFh2hzo0Z3dv7pmbo pTn5su+biHtINQXcxJfWUDBt0of5+K6D65UwSLle4Iw/O26FUSO9P9IuW3w5O/dq twwrfQ3KNMCFWjbawDUqRRrM05UCTWmAjc0+5suEHXa9FlPpmcSc0Cc+g1TU4hAR acfVYRBmLgdOrbJwf3jN31EVs9DaxrREjZd7sRu8QoU63Xq60SoxdfzKylRFWn1p H909uWeMPLu7Jx3XXfb4k5LgrWGtDI69Xhz2F6GVQqHG9JgEYmd71bU1sFpgG1Oj pMU2EqGmUo/h8KjkdIiJ0uVOc71K1pGU/rRjcow= -----END CERTIFICATE----- 07070100000072000081A40000000000000000000000016537CEF400000CE4000000000000000000000000000000000000004700000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ifc_rsa_8192.pem-----BEGIN CERTIFICATE----- MIIJWTCCBUGgAwIBAgIUJ+laUpwJX1nDHY7cBRq6IDveoPAwDQYJKoZIhvcNAQEL BQAwPDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVzdCBP cmdhbml6YXRpb24gTmFtZTAeFw0yMzA3MjExMjQzNDVaFw0yMzA4MjAxMjQzNDVa MDwxGTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRlc3QgT3Jn YW5pemF0aW9uIE5hbWUwggQiMA0GCSqGSIb3DQEBAQUAA4IEDwAwggQKAoIEAQDG WUXo/TWsFI7hCteWXygv9VwyMD4nk04X6JG2h3jLMqG7k6m+/LDCs3ZgF8EfQ+GJ SI3l/cSGFq57SdwtM0xLmlgstL1LmtqaLbdv5om8NPdZYCER+T4A5GhzuyhuyCkK ABiZ3AP2Fd2Zaf/n2WivPq9UuYTKsVRa8A2A6fAfmxCDSiR+NEscr2O5Td/rq2Gr 0xlfcVht2MalyEtx6rhEOd60XkK7dpcPCPi8dudFolhkMtnmv0yvLao4R46h/C4Q AoM6odKwLqtg+yKwfZMYop7M152DJ6J2/gsltUF0gNza8ohwaYtoXrr/r1H64Y+L 8ON2WPpMkwi952eXTEZ+8SsF4dk81bUrW/1Y/0amwdYQ3fH0RQ/yysZtzNLw8n27 3ZnzNByiapTnLWRbExRu36Lf2vyB+vQYplkHDGw5yOSIasbG6nd5Kd7QO0dWcTdA iBvF5BLjdV4VTwoN9RtapdW70GKC3q4NYrP+MkWbLCzQ08ht0nCFJIuY1OglBJCz xtPmMsn0DLKOVe45u2WBUUBi2FqQhDPVwlwNTdQzQDrB0DoXWYoyCx+nCGxS2eZQ cIbL0ihAuaCRFdvVLjJLcUmhtUIXVK6ICmC7TIQUJbZupW2v11+7x2AgzDiM8DSx mgI9Z8iHOnRJVHX+nHULGUYCSxI+sY7Gs59GgITg/dGRbn7WN1+auskvkC1GxYdq vmZBH+wxViQsWfv+SwK8AY9wlgRODCfE4/BKakILsp54jnO4LOvfnFx6te/JkLM+ nJMTorE0tCzk+A3OnrRS0MBcbApzFYy+m9zp0oC0Ku5/huuKRw2oD6L1IaZSFlRg l0M7NpNDvx8Kxtycmg6nFXZc6U/4iBXsE/e7pU0EkoHUPOpEdgohmxQZjbDFlPrM cGFF24vyiMarrcmgD7PkTP7da4NYn7XFGlGTsXJ6VweAQQV/zN4mxba8MOLnDbaZ mbHS3c4B/Ny3JDhFkawPqPTATu0qUBBdjz/CvJoJlvDH6TxIXPEioYrKHap9thY2 1BHy/jrTkoxncUDxWtpaw418bV02/WhPOWdFlf2kx6ty9QNZRyRqa9QzofFFX9AM M60zQee3Wgi/xHN5uhd80rQnSwhpWXZHFwbOZINFHAskz/HvHgPfexzJ0s6tahcJ jHb3+4DaEzLRjGCaCTvOowWDssDtjNpsroHDOf1+Qlbqd1wZAWAJvGlmPHSUgvB1 3CiOCqO1TYT4VK9DBeVavFk1+LylZFtTav9vTQIVRY5zQJrcNadsbHvviUcvMa24 6OlNAWtEnfHx4Z0TsnOOJXLfc4U38sCHGI7Ioxq87UBMbY2sfc33y1d+EF4I8nZ0 zjHYa+nwRHfGcLXdIqpJAgMBAAGjUzBRMB0GA1UdDgQWBBSShzBdX+iB6dYQZxuy z7LiQA9pMzAfBgNVHSMEGDAWgBSShzBdX+iB6dYQZxuyz7LiQA9pMzAPBgNVHRMB Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IEAQC7PoRNhLbAArSNzWPoXFkmeBb7 ihoQB81hk1TqVROAOtPUfh3LpehY1ZroCxGzWf7jOFLzjl/3Pd7bW8xdyHwhbKLj +WxxKmXI5w1eY52w+uUZX6Vau6sOA1S2DcKpCy114mrkxsK0oevvoPHb+y17FJRD n8bJUKqvFMv8EFv+igT0o1sJI1dIyT5gweHEmSXl/RMhl+OTzfhm6az32Fl3fEQ6 4OKwOrHq4afe8ov7TEmJ/yaHIvjfyXMi79Dbq4rzD8XDWbqeebMDwGQ/HuslY65W t9tsDC1xumBxit698gmaTzfr1T39qXi2TMa9gWOBzCsUS3CrtG/d7hPfYDMIoR86 3sdD4WZ626lvogxGVE9HhmQnp0iTzCFVT5LnL8mo0vAgwfh24sNHGbIUjm25LSZX yViVunZHlHxZrxBqpzip8aVhiQGySgVAG2wVg8+CeUpmLAoC0rWak0CnSBA1Xcbx 9Vrg+dPgA1Y9ZuMNSI9vhC1PIO8VZlRl5cVwubV5A8zgIU4fVnPZW55NmcxI+OCY 0GlGv/jfgeQ5Y9KY/re5G6KF08cRSaR4PlEDbkY60YyJK4dwK/vbDvKN6UIvEx+h lAjRRuZQSlJbOUzXPGxTy8EgDYW1d/yLtB4d+UouMOJvnEs+wIjXc3K4kV/QEADN TDqjfXMJKRU62Ffi+UYdGsRb1U3BNbARnFx2ca7YPQoXBJw5dk2h2EQtievMyTJo hA3S2SRoSwi9CEKmHdmMofSgoI6F2Z9jGacuGZL5/NCrswDucwdDketN6IabbuKb 1S+piig4IYoq7iYZLsa0AOiiuojUkfx+FFODls6kwX4sDFxNUF32azCVYqXXeRZ4 rG7EBMPjgMZoRyN5eXFqdG89bKGMdPWDGLZYVxXOcVCmw/AWS522XV9SgmvoOOLX LINOfZWG8p4vu21Wvdm2qCJOTTafdQdO3G/fiw3C+9frSUfioxmmCQeaJiE8QXrU 9N/zGogiRUriaO7TUeXBjtIlKUiRAFAnoQiGfse7xjtIGfApb7uaZnx5BjNyANW3 Vv4MSz6HS32ZyLGNA/2MdVl4iIJJoHT+CTvAgAplKBwqT4FyTniCXI2aLG348Hkp OCrrVFV9O0uC48zwksfEL76mKgrIVtXvY/D/LT5hvwvtKAe/SFjuSNrAUPY2vbgF o77lOi4qEAwEEA/8sVZMdHWbW3/zlh2uZ/Vd+hXFTVPdHV8qxH3uSvUVtj8JeIkg ISelQuIw5RS30Cv0RmsZDt4cjPe7kFdhUFdc5H/0lk7mcybHMBPvVyQf9eroP9qX UXTGkmiZNKrI6RCDaXSUt5KknEXafHy+vnVaQPSk7l+R+Ux8gW+u3n3N2EWJ -----END CERTIFICATE----- 07070100000073000081A40000000000000000000000016537CEF4000003ED000000000000000000000000000000000000004B00000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ifc_rsa_pss_1024.pem-----BEGIN CERTIFICATE----- MIICujCCAe+gAwIBAgIUavFbDsoJblNil1k47LEH7N/uwp0wQQYJKoZIhvcNAQEK MDSgDzANBglghkgBZQMEAgEFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgEF AKIDAgFeMDwxGTAXBgNVBAMMEFRlc3QgQ29tbW9uIE5hbWUxHzAdBgNVBAoMFlRl c3QgT3JnYW5pemF0aW9uIE5hbWUwHhcNMjMwNzIxMTI0MzQ1WhcNMjMwODIwMTI0 MzQ1WjA8MRkwFwYDVQQDDBBUZXN0IENvbW1vbiBOYW1lMR8wHQYDVQQKDBZUZXN0 IE9yZ2FuaXphdGlvbiBOYW1lMIGdMAsGCSqGSIb3DQEBCgOBjQAwgYkCgYEA0OXZ YPfMGAFCg+AjONjWh5JXGu3ScC4An5ah8Ybqn0/PbgmibQBUHBzCOkKIUA/ksH7S 4blvUfD3A8PtDeOa8IrdA7X/GY2huNvKNZbFsH9xW/AqHllR4uEb1/0rhf5IkK5w XgU8kq770Fb7H1uC3C73gdbWpwBL9tXJcVdA4FsCAwEAAaNTMFEwHQYDVR0OBBYE FIYLxtMZoGntrNliTJvJZaKbggUqMB8GA1UdIwQYMBaAFIYLxtMZoGntrNliTJvJ ZaKbggUqMA8GA1UdEwEB/wQFMAMBAf8wQQYJKoZIhvcNAQEKMDSgDzANBglghkgB ZQMEAgEFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgEFAKIDAgFeA4GBAFsu X/hbFgvJThteOfAHEyAOJ1domZQ4xuU/mXkSNu5E8oVXzLsG6V97mzYFvM1glLSL IfunpsNuajsZTc05zfZ8vsBTtO3tidg2Yl27BsYwOOB3/1SxUNDo2Z3JZeyJcErj 1+xSXOfL2uXhbJZDH9z99jrYQxAp5ooGsvMKRK8y -----END CERTIFICATE----- 07070100000074000081A40000000000000000000000016537CEF400000553000000000000000000000000000000000000004B00000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ifc_rsa_pss_2048.pem-----BEGIN CERTIFICATE----- MIIDwTCCAnSgAwIBAgIUYF3ydNK41dD0B8FMJdWuorwBIwgwQgYJKoZIhvcNAQEK MDWgDzANBglghkgBZQMEAgEFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgEF AKIEAgIA3jA8MRkwFwYDVQQDDBBUZXN0IENvbW1vbiBOYW1lMR8wHQYDVQQKDBZU ZXN0IE9yZ2FuaXphdGlvbiBOYW1lMB4XDTIzMDcyMTEyNDM0NVoXDTIzMDgyMDEy NDM0NVowPDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVz dCBPcmdhbml6YXRpb24gTmFtZTCCASAwCwYJKoZIhvcNAQEKA4IBDwAwggEKAoIB AQCGeJDjl+v2lcOwrgpZsGPSSEa9LttjtXN23KiKJ6gsOVOgeNpdM0ORUP/CaGgS noWH7JbZmcXgYWRXPwh/iMk+kSwR23Z8husu08Zt20PWjRAXZKrWKICwhJDboYgE eaIc71v9PIU2Y/dvK/B3j3o19lSCaqeeDfoB1/uaobiqVc9mYy8hmbaMitD/qRHZ FAa8j2mJMCjZaptFFSdZTiE58YLUhAlaKjz5RJNgg5h/3LOiRHrGhEDEDenfkgcx Gsie6b9VGpTQzDUsIxLO14L27Ckh8jk+XaFPyOfqKcizvkLqG6Wl1b3YKk12+M3y 72jwk0RFb5QjxZl4GqwvJ6oTAgMBAAGjUzBRMB0GA1UdDgQWBBTeQx8xSgBwi1g5 YnurkCPNnC8NeDAfBgNVHSMEGDAWgBTeQx8xSgBwi1g5YnurkCPNnC8NeDAPBgNV HRMBAf8EBTADAQH/MEIGCSqGSIb3DQEBCjA1oA8wDQYJYIZIAWUDBAIBBQChHDAa BgkqhkiG9w0BAQgwDQYJYIZIAWUDBAIBBQCiBAICAN4DggEBAF6e5cv0hx2k0yEd iowvuZS8KMzjlCZwLYWV2EB5YDD2/vlmGzBdnv6SPRlkhj4yte3Lnh/zniheZGRC NdiYyoLMcEM5Gf1WLkCGo2TB/AnPT99CL606MXvf3xEdZlNOB4c00ciRDfq2P0pn v6+B7sHMQlwAOdODkb6W8KI0w89CwgUPVduS+khB9kRjwlwdDyvYMUFZlzTj+DN6 HN5PTbtBHoDhKguk9LKwyrNPA0bzK8Uuuqlv+po4fDdWHVhOkqYqoJ9wLP+E6m4y r/iPUVU0ni4N0rDXcpq4xareAHxKcBf7SPehESSmBg1Rytr+AiOyd+Tatx+sSjWm Mip6+vs= -----END CERTIFICATE----- 07070100000075000081A40000000000000000000000016537CEF400000809000000000000000000000000000000000000004B00000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ifc_rsa_pss_4096.pem-----BEGIN CERTIFICATE----- MIIFwTCCA3SgAwIBAgIUT/IuH9YeWOj3AaY8tHc4kq/SrO0wQgYJKoZIhvcNAQEK MDWgDzANBglghkgBZQMEAgEFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgEF AKIEAgIB3jA8MRkwFwYDVQQDDBBUZXN0IENvbW1vbiBOYW1lMR8wHQYDVQQKDBZU ZXN0IE9yZ2FuaXphdGlvbiBOYW1lMB4XDTIzMDcyMTEyNDM0N1oXDTIzMDgyMDEy NDM0N1owPDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVz dCBPcmdhbml6YXRpb24gTmFtZTCCAiAwCwYJKoZIhvcNAQEKA4ICDwAwggIKAoIC AQCiLrcvQs0JUD+pQHT8l746PODOR2odP+qaE5rlN1To4ZR+AzoJL2Isc3vDBePx ERYCcmuH3sm7z/QmY/GJv16fczRctNC97t1voKOl4x0oCtv1L9t9iipKoXlMgxCU GDRXboWT6lUxXXwB5gSgMU6JnDs7VNxpRaOeoPYEfjN8UieeiWCNkGCfCw2uzGpa xudjxYcg8EPHLQyY0jvbZ+/6TxN8wa4L+TJqI1OHg44Af7YOdhhFXCpuI+XkTfS/ RvJVYNH19pZQgAy2TpDR/iUGqH0PgSDy1B8sKZYIvYaVueu83OMw+4EFWO6Luhut X23DO1OI89LNWOr7nN9dZ1aw/ezLQzrTg8k+bCCoCBooGljzQcTgAgbE0fJRnYgB FRjZJ9JYcilmAlCdOK9uhuGe9kPcthhEL0H5yMgKhXhC9T04bLqZ1l8QQkXjeUme ae11ymbO5/tv6fhCIEKKaZnrTW9lOPu8QCkpbOQWk4UJ0Iw1bvKLnUss8aZnM0zF mL7gGZ8vioUdq75x2sAp7atpS8mevhnNO5XpwpuoKrf4xRkNOS/sDJ2fbLPCrdCI o6/aObQer3c8w6WpcUbSiPpAbh2sYnttNSPOnU22a4JizJ+Bhod56LfJlDg3aoDF gk5kYZEW1VKj+gw6VS3UtLd/eW32BRS8DkU7kVwKoBevDwIDAQABo1MwUTAdBgNV HQ4EFgQU7MFyhKEnCbmluQyJgtV52BX+bWowHwYDVR0jBBgwFoAU7MFyhKEnCbml uQyJgtV52BX+bWowDwYDVR0TAQH/BAUwAwEB/zBCBgkqhkiG9w0BAQowNaAPMA0G CWCGSAFlAwQCAQUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogQCAgHe A4ICAQAlKzumA6L4ELgfFYfJ50GSoCewNsj6X8gjUCoEJ0LG4wJJpy5X5QCtThIW RGo7frd1ca3yNnldrMgnjb3c92O2Z2oOWY/9auS9CpDSxkmP/6QWI+xW9qWS6j77 qdtVxEoH1Res38d/5hR4SQIFBiGxFOwn9b6RusexpCUzoayXAVJumO0fcczaaUoR BqBrrpL2s9Mh7l35BQ+7qUbU4qCIy3PUXni2ThcULEus6tVRLJblxf3o/9yitjfH HZ+dh+d9/Y5Fy1NnuolGSfieF2dDgWMypJfWAccqnodmYsth7qZ2FJNKbWxS0qD1 nW/ioq9Ygw8BuQmOehDc6eDuutffxKxA1xbtk0dZzyzGa8ibG+zC65ZlXF6bdQM0 mK1mPXAS77l9Qk0WrOuunp8dHI3Q4/dKY3q9XK4dQNLqX38nRsLsYem6KQ/SStIN Z+SKsrb8sbw5fWXGSaDCrXXOWYF0q2it9dSPEzEBVkzNo3uLIu9sFgLVEVd7Nh+i gSNrBxRN3ku0KNDUusb6m0v/wycJUcG/oMH2ELcO5SFNUg5jXRhPMDqUF68ZoRtq +/VFo6XT3q0VmFu/s+mMOheLYNnDLQqXozHOqBM1DAvsCfUgJKh12WdenxaJCWFs lGkEFS/GPvACDMPexqbdiSSllihh5WkXbCwo4PFkECbrN9baoQ== -----END CERTIFICATE----- 07070100000076000081A40000000000000000000000016537CEF400000D73000000000000000000000000000000000000004B00000000wardstone-0.2.0~0/crates/cmd/src/testing/certificates/ifc_rsa_pss_8192.pem-----BEGIN CERTIFICATE----- MIIJwTCCBXSgAwIBAgIUeB9uIZ36VqWrGgqZ1ofXgj8v3g8wQgYJKoZIhvcNAQEK MDWgDzANBglghkgBZQMEAgEFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgEF AKIEAgID3jA8MRkwFwYDVQQDDBBUZXN0IENvbW1vbiBOYW1lMR8wHQYDVQQKDBZU ZXN0IE9yZ2FuaXphdGlvbiBOYW1lMB4XDTIzMDcyMTEyNDM1OFoXDTIzMDgyMDEy NDM1OFowPDEZMBcGA1UEAwwQVGVzdCBDb21tb24gTmFtZTEfMB0GA1UECgwWVGVz dCBPcmdhbml6YXRpb24gTmFtZTCCBCAwCwYJKoZIhvcNAQEKA4IEDwAwggQKAoIE AQCYp8TZz0sHWKJl5uocHipiUZRA5UC+GkjfjsFCBOto/Sd4Ihbe4aH6s1oomHE4 jjJLxlNvZMu7TiYYr9DONvvdOaN4cLi7A1SoszObLMdl5Pg2fjnfb/9nNJVYyBV4 Ff3DlUhDIKi8J8mZQbqR+KYx+J6MHPMRD4hwaE4KStQZxKCy4PPIAdQz3eTb5P7A 9dSFmKThuKNP6s0L4hRPWy3EVaHOz1D+bheTyq1+joLD7AipvN7LSFJgt14Z4UBm RYiUa7fK/7tLekH023rYL6oLZIHCvKiQsHez7zavVaTTRx10eUXjP/4uNOCReGrL RWyFFYsZNnOgt8vLXa6M1ZrjHhsf2DwmnDqVJ8spTlNZaYndCREzZqP8kay4rmZW G0hNMtYaaf3CvJmXFo/7S+oDYA/luHDUaMLyae0QSXZpCvan0NBpWJbZh2sdPmOL hUr76Bya4VcuqAzPhQjq7om2WQPYOMGTJp+MQnwK0kNQrwuDhUkLd3tRIxEHfhLh op9HE/bJsLtc0EALocUXtY+Jnch9aQB8Oq9MFEhYLYu0EtZRHfm0AbAwRDBkaCbL EDGadV/WzxnUX+mUoIKPXR79dWjXFGMnjqgmCcLUaVItRZRxUTf9cUUjy8BT67jT MYkqPZSfNxjSR6Ni9+QfIfGF5KOQXUG4/zCYepfM6je5jcPnzui78FrckJv0zYvJ UuSj9hQTPKpDZxww/Y3oX+0BtGMYQ/ydChL7WIcsUaKt4/p4nHhd/NnjiBmzX9bs ODs1TsB4qQ7KIbWCvch1CeZHKC4RXiSEzYDlC+8W2qYcOPtX9+5E6s4PvDdC60TK Q/LLQosr+0aapzbkaRddLiW4MTtSEky1I0SW11xQCXQq8BIp54SG4VsLI/qW8V7Z JXYl59Nelrgox1YNmGtVklO5OYfWSn7nfd+BZcJ77uh52T+RtH/E5yLD7SczRLWk mdvusjusTB4k1arBXZY4RAt9VkRYTqKV6ksN4ZvL5FkLnRMPGuyCsEfPgFxZwODt QQ0RxIxUevqubrHbsyybrewWzJ9xjI+1L+H/cmb2eOey+ef6wnVkusJnPMebjtb1 WF4BQuKtWjTAwpUQw8ybCtyNP5z1ltZnI5+mFvZMWVBbJGXobGme73xxDHX4LltZ CVbs64ri+14e5oDRmrGvR2ItlVWFh6CKlfPewhdGE+VNOmJIzf3k4yQspsDcijvz vWbh3FPkxDvkzg+fCan3Icn/K5y2iDKDFnVFjy3b4xnempI/b9ur+fvEJGHwDNxv +kyOSIb8jXpZ83YmfhzpHKkGZdauJhwRYFal9/mlGnSkYOoY8i3HlTdVtDYbASCD USX5UpFguge7zvUOKWduSJPzAgMBAAGjUzBRMB0GA1UdDgQWBBT/CRlI32zz/E1L 82djyPlif1nTOzAfBgNVHSMEGDAWgBT/CRlI32zz/E1L82djyPlif1nTOzAPBgNV HRMBAf8EBTADAQH/MEIGCSqGSIb3DQEBCjA1oA8wDQYJYIZIAWUDBAIBBQChHDAa BgkqhkiG9w0BAQgwDQYJYIZIAWUDBAIBBQCiBAICA94DggQBACKx/5bG8tIOEKGF CESvnxLyJUvMOUM11aqPbWnTNplqzakxWFQ1ijGTqk8Ez4pcHQP8mUNA6wN7pQc3 Ee6zOHof0sVvyEgp4nQr7lutxmvQqjvsqDAFhSUeHfhfNWaOMr4glIMtCV2GbqRT B7mz/pjrW38TJHgI03KmlwWUjc5qaoHg6iAob4cRP8XiKePNvnT0uroudPlmKUo5 7CVGxe13UiSuxVxsh08+SKjHhCTj7lV8F6OtzwM1eakwoFGcwhGk0yiCVb7eIKja NjC6qrE7NXPlMSeRTJRvnZjITm+kgauPoTuorv+KdqGTyU3nmhxfhmehEg4UOj4f QAo/YaJCaTtjE/k0YiJ2XMyh/B+iYIU1rNhd0K344IdtRLZDpUdj+6iDKXxJYnjp dzQxoejUJGLjEq6H5WoaXTrGMRgcQfUyDAoIG7CHlXOpp66na00rMmzM2sHkcfVT 3O7xrvXf6FgisJV3qcCPfoTUdYlLbSJslDkfrmCmhxrha1qB3WbH8I0UyWHZMrJW ADKjLKkmdT1vR6Yux4mW2Nsdxhtl8xloDl8GY1IEJsVoVajHdkEAMqSCEe0FAwCE GPKuqOB1YX6UNR3E97guyO0LFRP62irwJ3RFNLgN8mLRFurw6Vx4QBnVaKSvO6rr NZYZt65vizb/ovXE0XeisF3JjJTJ29ipxV8wZYxM23DQRDDKoouBvDeMnVHw6TYd JYpBkJ07wDXeXfh+4M5hlUPzRds6ewPB5LtXUlRuXlyTOr5N6xSHHfJD9Yd31Msx ttOXlNbh9+Ix/vmIUqV3M0EUgkNpCp3VgNP3tdi10bI5L046dqk2e+tLtTsJ995C F8q17BrYgNDdkCFh3SIcD3EV3jU8Tjo3B6HUTKmhTzLiudHb/g9dQnt53I1kN5eQ mOx4H3gjjn2Y5hZ3rJzzjI1ocCYiS0wHfDZaT5nNDQDrGq9PzRI6XBU4kBgqAn98 k+miNjVWw3RaUZysgTsQ34+6Uxt/jnYXyhMLdU2oSn+w73EpTzGKibIdSP//DXT3 51/IT+g3cB+488AFFi7mKED4rAFReqwcB22kQki0ZGNmkX5OFa+WTxw01/zuQf9V tHD+nh+bbkFv0+3t+gv7+58Bglf/0ZOxw8PEmqVPKgzkBtT5rwfZW5nT3TnVgQY7 sOBV7N9Dz9pLkrGRM+B+CgGBMLI8vPVn+K38Rn1kIRdsjnu5++s7cHWluuqZ3rCk 51HZImpRZZJ+XNy2Za6XNxZmh/i3Uv2N7lKnhWtSv3SZSj4DaXZmMJ2/eKynafBn l31U+obxjevuSgoQY9NieIW077Fv5aixsOF+RuTbgZBiKXL+Rxvb3QB0PJ5Vrp84 2PcFPl0= -----END CERTIFICATE----- 07070100000077000041ED0000000000000000000000026537CEF400000000000000000000000000000000000000000000002D00000000wardstone-0.2.0~0/crates/cmd/src/testing/ssh07070100000078000081A40000000000000000000000016537CEF4000000B3000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/ssh/id_ecdsa_256_wardstone.pubecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBmHlY2zHb5eVyuNxD5myl5mQUWjjNGzVF45QBHor1mJhFj1CuCCOLDaXHCAlLSVjXRKg5jzVG0IYlQyRqgkgw0= testing@wardstone 07070100000079000081A40000000000000000000000016537CEF4000000DF000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/ssh/id_ecdsa_384_wardstone.pubecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBOW29z6cRIf8k3BvmOxRKG9AhYZnNfMuOUJwkWmw/oiQcPw4riuLBIe76RICGCeBm9jTEi2gZugIJLPNuoUFdGprPP/9OWG7NRK19pgk9Da8n9kCqRJfpl2DOsnPmZwlSw== testing@wardstone 0707010000007A000081A40000000000000000000000016537CEF40000010F000000000000000000000000000000000000004800000000wardstone-0.2.0~0/crates/cmd/src/testing/ssh/id_ecdsa_521_wardstone.pubecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAHqxHLsQ85m+80P970FzdaB9XnDyNR/HzYnMAAnvSVZc5y2gyUajp2+0BaXuyzlPrkopiGKH+Si59uGJ2ncWfNJ3gEfTZ08JqKh1yPCqXRyjiu1G2wodeBkeDLdP0AlpTJaeWS7YFc4+Di2c4ZiecUC0OrxoVzNwQz/cxVTNwoUbmiUFQ== testing@wardstone 0707010000007B000081A40000000000000000000000016537CEF400000063000000000000000000000000000000000000004600000000wardstone-0.2.0~0/crates/cmd/src/testing/ssh/id_ed25519_wardstone.pubssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILEbD1/tV8qEh6b+v61CU9HRtfbu5NI7R/em4JuNvQxX testing@wardstone 0707010000007C000081A40000000000000000000000016537CEF4000000E7000000000000000000000000000000000000005000000000wardstone-0.2.0~0/crates/cmd/src/testing/ssh/id_rsa_sha2_256_1024_wardstone.pubssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDVx0mBzXM9PWdfPmQpRoNg77oHGBkzqLJWYtyYSrAqo1fHNcR+PzjxFIcBb3PvGj6arXhBH4PiOnUkeKiZ5EVzqf43q7YKidmL1NLA3gsy9cd1j5hLyseqQod/weExjMbPERR93h4LVge2bF79W490jb1/9f94KkwjeITKbun81w== testing@wardstone 0707010000007D000081A40000000000000000000000016537CEF4000000E7000000000000000000000000000000000000005000000000wardstone-0.2.0~0/crates/cmd/src/testing/ssh/id_rsa_sha2_512_1024_wardstone.pubssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCyewTRPOr6Q/F5vFcEkdFuL1V6VzQT/astfCqzr9NF3TnAbKhOK8u0MM+7sW1nERxIFe5CTLIMEjfc746N2A9vIzC+nCl5jq8TAdmruJRU6DjsrVGILwgKwx3p5gzqgj6C6RwaIadfax/pCzSx5BWYRNGYnxno3w7wzltB//41zQ== testing@wardstone 0707010000007E000081A40000000000000000000000016537CEF4000000E7000000000000000000000000000000000000004B00000000wardstone-0.2.0~0/crates/cmd/src/testing/ssh/id_ssh_rsa_1024_wardstone.pubssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC1HNDdrnYFKa35CKuH6RC3rI1SJ3OXkUEy8xVt96hIr8V4iEqGIf/d7Pu1l5+rvXfhqGEye09YQ9oYhKx74gfSL3ZVDerH3A0QG8WBRzTG5aB5TPbLb78YQfww9DF1e3EhOYx2pmHYRnWhKgtQgAWFwY7YdYTy1ktr+CCNEmOgeQ== testing@wardstone 0707010000007F000041ED0000000000000000000000026537CEF400000000000000000000000000000000000000000000001E00000000wardstone-0.2.0~0/crates/core07070100000080000081A40000000000000000000000016537CEF4000000A2000000000000000000000000000000000000002900000000wardstone-0.2.0~0/crates/core/Cargo.toml[package] name = "wardstone_core" version = "0.2.0" edition = "2021" [dependencies] once_cell = "1.18.0" serde = { version = "1.0.189", features = ["derive"] } 07070100000081000081A40000000000000000000000016537CEF400000506000000000000000000000000000000000000002800000000wardstone-0.2.0~0/crates/core/README.md# Wardstone Core ![Continuous Integration](https://github.com/tshakalekholoane/wardstone/actions/workflows/ci.yaml/badge.svg) The `wardstone_core` library contains logic to assess cryptographic primitives against various standards and research publications. For example, if one wanted to assess whether the [SHA-256](https://doi.org/10.6028/NIST.FIPS.180-4) hash function is valid based on the [guidance made by the NSA](https://media.defense.gov/2022/Sep/07/2003071834/-1/-1/0/CSA_CNSA_2.0_ALGORITHMS_.PDF), they would execute the following lines of code. ```rust use wardstone_core::context::Context; use wardstone_core::primitive::hash::{SHA256, SHA384}; use wardstone_core::standard::cnsa::Cnsa; use wardstone_core::standard::Standard; let ctx = Context::default(); assert_eq!(Cnsa::validate_hash(ctx, SHA256), Err(SHA384)); ``` Since the NSA no longer recommends the use of the SHA-256 algorithm, an alternative, the SHA-384 hash function, is suggested as the value contained in the returned result `Err` based on the `Context` which the user can customise to specify parameters such as the year in which they expect the primitive to stay secure according to estimates about cryptanalytic progress and the minimum overall security that they might require for their use case. 07070100000082000041ED0000000000000000000000026537CEF400000000000000000000000000000000000000000000002200000000wardstone-0.2.0~0/crates/core/src07070100000083000081A40000000000000000000000016537CEF40000054E000000000000000000000000000000000000002D00000000wardstone-0.2.0~0/crates/core/src/context.rs//! Specifies the context in which a cryptographic primitive will be //! assessed against. use crate::primitive::Security; /// Represents the context in which a cryptographic primitive will be /// assessed against such as the year and minimum security required by /// the user. #[repr(C)] #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct Context { security: Security, year: u16, } impl Context { // NOTE: This does not imply that the minimum security level is 0 but // rather that it will default to the minimum security level specified // in the standard. const DEFAULT_SECURITY: u16 = 0; const DEFAULT_YEAR: u16 = 2023; /// Creates a new context. /// /// `security` denotes the minimum security required. If this is set /// to `0` then it will default to using the minimum security outlined /// in the standard. `year` is the year one expects the primitive to /// remain secure. pub fn new(security: Security, year: u16) -> Self { Self { security, year } } pub fn security(&self) -> Security { self.security } pub fn year(&self) -> u16 { self.year } } impl Default for Context { /// Creates a context which will default to the year 2023 and will use /// the minimum security defined by the standard. fn default() -> Self { Self::new(Self::DEFAULT_SECURITY, Self::DEFAULT_YEAR) } } 07070100000084000081A40000000000000000000000016537CEF40000057D000000000000000000000000000000000000002900000000wardstone-0.2.0~0/crates/core/src/lib.rs//! # Wardstone Core //! //! The `wardstone_core` library contains logic to assess cryptographic //! primitives against various standards and research publications. //! //! For example, if one wanted to assess whether the [SHA-256] hash //! function is valid based on the [guidance made by the NSA], they //! would execute the following lines of code. //! //! ``` //! use wardstone_core::context::Context; //! use wardstone_core::primitive::hash::{SHA256, SHA384}; //! use wardstone_core::standard::cnsa::Cnsa; //! use wardstone_core::standard::Standard; //! //! let ctx = Context::default(); //! assert_eq!(Cnsa::validate_hash(ctx, SHA256), Err(SHA384)); //! ``` //! //! Since the NSA no longer recommends the use of the SHA-256 algorithm, //! an alternative, the SHA-384 hash function, is suggested as the value //! contained in the returned result `Err` based on the //! [`Context`](crate::context::Context) which the user can customise to //! specify parameters such as the year in which they expect the //! primitive to stay secure according to estimates about cryptanalytic //! progress and the minimum overall security that they might require //! for their use case. //! //! [SHA-256]: https://doi.org/10.6028/NIST.FIPS.180-4 //! [guidance made by the NSA]: https://media.defense.gov/2022/Sep/07/2003071834/-1/-1/0/CSA_CNSA_2.0_ALGORITHMS_.PDF pub mod context; pub mod primitive; pub mod standard; 07070100000085000041ED0000000000000000000000026537CEF400000000000000000000000000000000000000000000002C00000000wardstone-0.2.0~0/crates/core/src/primitive07070100000086000081A40000000000000000000000016537CEF4000001A1000000000000000000000000000000000000002F00000000wardstone-0.2.0~0/crates/core/src/primitive.rs//! Specifies a cryptographic primitive. pub mod asymmetric; pub mod ecc; pub mod ffc; pub mod hash; pub mod ifc; pub mod symmetric; /// The level of security of a symmetric cryptosystem which is a /// standard measure used to assess the security of all other /// cryptographic primitives. pub type Security = u16; /// Represents a cryptographic primitive. pub trait Primitive { fn security(&self) -> Security; } 07070100000087000081A40000000000000000000000016537CEF4000005E4000000000000000000000000000000000000003A00000000wardstone-0.2.0~0/crates/core/src/primitive/asymmetric.rs//! An asymmetric key primitive. //! //! This is just a thin wrapper around asymmetric key primitives defined //! in other modules that are bridged here to avoid incompatibility with //! C/C++. use std::fmt::{self, Display, Formatter}; use serde::Serialize; use crate::primitive::ecc::Ecc; use crate::primitive::ffc::Ffc; use crate::primitive::ifc::Ifc; use crate::primitive::{Primitive, Security}; /// Represents an asymmetric key primitive. #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub enum Asymmetric { Ecc(Ecc), Ifc(Ifc), Ffc(Ffc), } impl Primitive for Asymmetric { fn security(&self) -> Security { match self { Asymmetric::Ecc(ecc) => ecc.security(), Asymmetric::Ifc(ifc) => ifc.security(), Asymmetric::Ffc(ffc) => ffc.security(), } } } impl Display for Asymmetric { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { Asymmetric::Ecc(ecc) => ecc.fmt(f), Asymmetric::Ifc(ifc) => ifc.fmt(f), Asymmetric::Ffc(ffc) => ffc.fmt(f), } } } impl From<Ecc> for Asymmetric { fn from(ecc: Ecc) -> Self { Self::Ecc(ecc) } } impl From<Ifc> for Asymmetric { fn from(ifc: Ifc) -> Self { Self::Ifc(ifc) } } impl From<Ffc> for Asymmetric { fn from(ffc: Ffc) -> Self { Self::Ffc(ffc) } } impl Serialize for Asymmetric { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer, { let s = format!("{}", self); serializer.serialize_str(&s) } } 07070100000088000081A40000000000000000000000016537CEF400005D19000000000000000000000000000000000000003300000000wardstone-0.2.0~0/crates/core/src/primitive/ecc.rs//! Elliptic curve primitive and some common instances. use std::collections::HashMap; use std::fmt::{Display, Formatter, Result}; use once_cell::sync::Lazy; use crate::primitive::{Primitive, Security}; /// Represents an elliptic curve cryptography primitive used for digital /// signatures and key establishment where f is the key size (the size /// of n, where n is the order of the base point G). #[repr(C)] #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub struct Ecc { pub id: u16, pub f: u16, } impl Ecc { pub const fn new(id: u16, f: u16) -> Self { Self { id, f } } } // The name is kept in a lookup table instead of being embedded in the // type because sharing strings across language boundaries is a bit // dicey. pub static REPR: Lazy<HashMap<Ecc, &str>> = Lazy::new(|| { let mut m = HashMap::new(); m.insert(SM2, "SM2"); m.insert(B163, "nistb163 or sect163r2"); m.insert(B233, "nistb233, sect233r1, or wap-wsg-idm-ecid-wtls11"); m.insert(B283, "nistb283 or sect283r1"); m.insert(B409, "nistb409 or sect409r1"); m.insert(B571, "nistb571 or sect571r1"); m.insert(BRAINPOOLP160R1, "brainpoolP160r1"); m.insert(BRAINPOOLP160T1, "brainpoolP160t1"); m.insert(BRAINPOOLP192R1, "brainpoolP192r1"); m.insert(BRAINPOOLP192T1, "brainpoolP192t1"); m.insert(BRAINPOOLP224R1, "brainpoolP224r1"); m.insert(BRAINPOOLP224T1, "brainpoolP224t1"); m.insert(BRAINPOOLP256R1, "brainpoolP256r1"); m.insert(BRAINPOOLP256T1, "brainpoolP256t1"); m.insert(BRAINPOOLP320R1, "brainpoolP320r1"); m.insert(BRAINPOOLP320T1, "brainpoolP320t1"); m.insert(BRAINPOOLP384R1, "brainpoolP384r1"); m.insert(BRAINPOOLP384T1, "brainpoolP384t1"); m.insert(BRAINPOOLP512R1, "brainpoolP512r1"); m.insert(BRAINPOOLP512T1, "brainpoolP512t1"); m.insert(C2PNB163V1, "c2pnb163v1 or wap-wsg-idm-ecid-wtls5"); m.insert(C2PNB163V2, "c2pnb163v2"); m.insert(C2PNB163V3, "c2pnb163v3"); m.insert(C2PNB176V1, "c2pnb176v1"); m.insert(C2PNB208W1, "c2pnb208w1"); m.insert(C2PNB272W1, "c2pnb272w1"); m.insert(C2PNB304W1, "c2pnb304w1"); m.insert(C2PNB368W1, "c2pnb368w1"); m.insert(C2TNB191V1, "c2tnb191v1"); m.insert(C2TNB191V2, "c2tnb191v2"); m.insert(C2TNB191V3, "c2tnb191v3"); m.insert(C2TNB239V1, "c2tnb239v1"); m.insert(C2TNB239V2, "c2tnb239v2"); m.insert(C2TNB239V3, "c2tnb239v3"); m.insert(C2TNB359V1, "c2tnb359v1"); m.insert(C2TNB431R1, "c2tnb431r1"); m.insert(ECC_NOT_ALLOWED, "not allowed"); m.insert(ED25519, "ed25519"); m.insert(ED448, "ed448"); m.insert(K163, "nistk163, sect163k1, or wap-wsg-idm-ecid-wtls3"); m.insert(K233, "nistk233, sect233k1, or wap-wsg-idm-ecid-wtls10"); m.insert(K283, "nistk283 or sect283k1"); m.insert(K409, "nistk409 or sect409k1"); m.insert(K571, "nistk571"); m.insert(P192, "nistp192, prime192v1, or secp192r1"); m.insert(P224, "nistp224, secp224r1, or wap-wsg-idm-ecid-wtls12"); m.insert(P256, "nistp256, prime256v1, or secp256r1"); m.insert(P384, "nistp384 or secp384r1"); m.insert(P521, "nistp521 or secp521r1"); m.insert(PRIME192V2, "prime192v2"); m.insert(PRIME192V3, "prime192v3"); m.insert(PRIME239V1, "prime239v1"); m.insert(PRIME239V2, "prime239v2"); m.insert(PRIME239V3, "prime239v3"); m.insert(SECP112R1, "secp112r1 or wap-wsg-idm-ecid-wtls6"); m.insert(SECP112R2, "secp112r2"); m.insert(SECP128R1, "secp128r1"); m.insert(SECP128R2, "secp128r2"); m.insert(SECP160K1, "secp160k1"); m.insert(SECP160R1, "secp160r1 or wap-wsg-idm-ecid-wtls7"); m.insert(SECP160R2, "secp160r2"); m.insert(SECP192K1, "secp192k1"); m.insert(SECP224K1, "secp224k1"); m.insert(SECP256K1, "secp256k1"); m.insert(SECT113R1, "sect113r1 or wap-wsg-idm-ecid-wtls4"); m.insert(SECT113R2, "sect113r2"); m.insert(SECT131R1, "sect131r1"); m.insert(SECT131R2, "sect131r2"); m.insert(SECT163R1, "sect163r1"); m.insert(SECT193R1, "sect193r1"); m.insert(SECT193R2, "sect193r2"); m.insert(SECT239K1, "sect239k1"); m.insert(SM2, "sm2"); m.insert(WAP_WSG_IDM_ECID_WTLS1, "wap-wsg-idm-ecid-wtls1"); m.insert(WAP_WSG_IDM_ECID_WTLS8, "wap-wsg-idm-ecid-wtls8"); m.insert(WAP_WSG_IDM_ECID_WTLS9, "wap-wsg-idm-ecid-wtls9"); m.insert(X25519, "x25519"); m.insert(X448, "x448"); m.insert(ECC_224, "any approved 224-bit elliptic curve"); m.insert(ECC_256, "any approved 256-bit elliptic curve"); m.insert(ECC_384, "any approved 384-bit elliptic curve"); m.insert(ECC_512, "any approved 512-bit elliptic curve"); m }); impl Display for Ecc { fn fmt(&self, f: &mut Formatter<'_>) -> Result { let unrecognised = "unrecognised"; let name = REPR.get(self).unwrap_or(&unrecognised); write!(f, "{name}") } } impl Primitive for Ecc { /// Returns the security level of an elliptic curve key (which is /// approximately len(n)/2). fn security(&self) -> Security { self.f >> 1 } } /// Represents the Weierstrass curve B-163 over a prime field. Also /// known as sect163r2. #[no_mangle] pub static B163: Ecc = Ecc::new(1, 163); /// Represents the Weierstrass curve B-223 over a prime field. Also /// known as sect233r1 and wap-wsg-idm-ecid-wtls11. #[no_mangle] pub static B233: Ecc = Ecc::new(2, 233); /// Represents the Weierstrass curve B-283 over a prime field. Also /// known as sect283r1. #[no_mangle] pub static B283: Ecc = Ecc::new(3, 283); /// Represents the Weierstrass curve B-409 over a prime field. Also /// known as sect409r1. #[no_mangle] pub static B409: Ecc = Ecc::new(4, 409); /// Represents the Weierstrass curve B-571 over a prime field. Also /// known as sect571r1. #[no_mangle] pub static B571: Ecc = Ecc::new(5, 571); /// Represents the curve brainpoolP160r1 specified in [RFC 5639]. /// /// [RFC 5639]: https://datatracker.ietf.org/doc/rfc5639 #[no_mangle] pub static BRAINPOOLP160R1: Ecc = Ecc::new(6, 160); /// Represents the curve brainpoolP160t1 specified in [RFC 5639]. /// /// [RFC 5639]: https://datatracker.ietf.org/doc/rfc5639 #[no_mangle] pub static BRAINPOOLP160T1: Ecc = Ecc::new(7, 160); /// Represents the curve brainpoolP192r1 specified in [RFC 5639]. /// /// [RFC 5639]: https://datatracker.ietf.org/doc/rfc5639 #[no_mangle] pub static BRAINPOOLP192R1: Ecc = Ecc::new(8, 192); /// Represents the curve brainpoolP160r1 specified in [RFC 5639]. /// /// [RFC 5639]: https://datatracker.ietf.org/doc/rfc5639 #[no_mangle] pub static BRAINPOOLP192T1: Ecc = Ecc::new(9, 192); /// Represents the curve brainpoolP224r1 specified in [RFC 5639]. /// /// [RFC 5639]: https://datatracker.ietf.org/doc/rfc5639 #[no_mangle] pub static BRAINPOOLP224R1: Ecc = Ecc::new(10, 224); /// Represents the curve brainpoolP224r1 specified in [RFC 5639]. /// /// [RFC 5639]: https://datatracker.ietf.org/doc/rfc5639 #[no_mangle] pub static BRAINPOOLP224T1: Ecc = Ecc::new(11, 224); /// Represents the curve brainpoolP256r1 specified in [RFC 5639]. /// /// [RFC 5639]: https://datatracker.ietf.org/doc/rfc5639 #[no_mangle] pub static BRAINPOOLP256R1: Ecc = Ecc::new(12, 256); /// Represents the curve brainpoolP256r1 specified in [RFC 5639]. /// /// [RFC 5639]: https://datatracker.ietf.org/doc/rfc5639 #[no_mangle] pub static BRAINPOOLP256T1: Ecc = Ecc::new(13, 256); /// Represents the curve brainpoolP320r1 specified in [RFC 5639]. /// /// [RFC 5639]: https://datatracker.ietf.org/doc/rfc5639 #[no_mangle] pub static BRAINPOOLP320R1: Ecc = Ecc::new(14, 320); /// Represents the curve brainpoolP320r1 specified in [RFC 5639]. /// /// [RFC 5639]: https://datatracker.ietf.org/doc/rfc5639 #[no_mangle] pub static BRAINPOOLP320T1: Ecc = Ecc::new(15, 320); /// Represents the curve brainpoolP384r1 specified in [RFC 5639]. /// /// [RFC 5639]: https://datatracker.ietf.org/doc/rfc5639 #[no_mangle] pub static BRAINPOOLP384R1: Ecc = Ecc::new(16, 384); /// Represents the curve brainpoolP384r1 specified in [RFC 5639]. /// /// [RFC 5639]: https://datatracker.ietf.org/doc/rfc5639 #[no_mangle] pub static BRAINPOOLP384T1: Ecc = Ecc::new(17, 384); /// Represents the curve brainpoolP512r1 specified in [RFC 5639]. /// /// [RFC 5639]: https://datatracker.ietf.org/doc/rfc5639 #[no_mangle] pub static BRAINPOOLP512R1: Ecc = Ecc::new(18, 512); /// Represents the curve brainpoolP512r1 specified in [RFC 5639]. /// /// [RFC 5639]: https://datatracker.ietf.org/doc/rfc5639 #[no_mangle] pub static BRAINPOOLP512T1: Ecc = Ecc::new(19, 512); /// Represents the c2pnb163v1 curve as specified in ANSI x9.62. Also /// known as wap-wsg-idm-ecid-wtls5. #[no_mangle] pub static C2PNB163V1: Ecc = Ecc::new(20, 163); /// Represents the c2pnb163v2 curve as specified in ANSI x9.62. #[no_mangle] pub static C2PNB163V2: Ecc = Ecc::new(21, 163); /// Represents the c2pnb163v3 curve as specified in ANSI x9.62. #[no_mangle] pub static C2PNB163V3: Ecc = Ecc::new(22, 163); /// Represents the c2pnb176v1 curve as specified in ANSI x9.62. #[no_mangle] pub static C2PNB176V1: Ecc = Ecc::new(23, 176); /// Represents the c2pnb208w1 curve as specified in ANSI x9.62. #[no_mangle] pub static C2PNB208W1: Ecc = Ecc::new(24, 208); /// Represents the c2pnb272w1 curve as specified in ANSI x9.62. #[no_mangle] pub static C2PNB272W1: Ecc = Ecc::new(25, 272); /// Represents the c2pnb304w1 curve as specified in ANSI x9.62. #[no_mangle] pub static C2PNB304W1: Ecc = Ecc::new(26, 304); /// Represents the c2pnb368w1 curve as specified in ANSI x9.62. #[no_mangle] pub static C2PNB368W1: Ecc = Ecc::new(27, 368); /// Represents the c2tnb191v1 curve as specified in ANSI x9.62. #[no_mangle] pub static C2TNB191V1: Ecc = Ecc::new(28, 191); /// Represents the c2tnb191v2 curve as specified in ANSI x9.62. #[no_mangle] pub static C2TNB191V2: Ecc = Ecc::new(29, 191); /// Represents the c2tnb191v3 curve as specified in ANSI x9.62. #[no_mangle] pub static C2TNB191V3: Ecc = Ecc::new(30, 191); /// Represents the c2tnb239v1 curve as specified in ANSI x9.62. #[no_mangle] pub static C2TNB239V1: Ecc = Ecc::new(31, 239); /// Represents the c2tnb239v2 curve as specified in ANSI x9.62. #[no_mangle] pub static C2TNB239V2: Ecc = Ecc::new(32, 239); /// Represents the c2tnb239v3 curve as specified in ANSI x9.62. #[no_mangle] pub static C2TNB239V3: Ecc = Ecc::new(33, 239); /// Represents the c2tnb359v1 curve as specified in ANSI x9.62. #[no_mangle] pub static C2TNB359V1: Ecc = Ecc::new(34, 359); /// Represents the c2tnb431r1 curve as specified in ANSI x9.62. #[no_mangle] pub static C2TNB431R1: Ecc = Ecc::new(35, 359); /// Represents the Ed25519 signature algorithm as specified in the paper /// [High-speed high-security signatures]. /// /// [High-speed high-security signatures]: https://eprint.iacr.org/2011/368 #[no_mangle] pub static ED25519: Ecc = Ecc::new(36, 256); /// Represents the Ed448 signature algorithm as specified in the paper /// [High-speed high-security signatures]. /// /// [High-speed high-security signatures]: https://eprint.iacr.org/2011/368 #[no_mangle] pub static ED448: Ecc = Ecc::new(37, 448); /// Represents the Weierstrass curve K-163 over a prime field. Also /// known as sect163k1 and wap-wsg-idm-ecid-wtls3. #[no_mangle] pub static K163: Ecc = Ecc::new(38, 192); /// Represents the Weierstrass curve K-223 over a prime field. Also /// known as sect233k1 and wap-wsg-idm-ecid-wtls10. #[no_mangle] pub static K233: Ecc = Ecc::new(39, 223); /// Represents the Weierstrass curve K-283 over a prime field. Also /// known as sect283k1. #[no_mangle] pub static K283: Ecc = Ecc::new(40, 192); /// Represents the Weierstrass curve K-409 over a prime field. Also /// known as sect409k1. #[no_mangle] pub static K409: Ecc = Ecc::new(41, 409); /// Represents the Weierstrass curve K-571 over a prime field. #[no_mangle] pub static K571: Ecc = Ecc::new(42, 571); /// Represents the Weierstrass curve P-192 over a prime field. Also /// known as prime192v1 and secp192r1. #[no_mangle] pub static P192: Ecc = Ecc::new(43, 192); /// Represents the Weierstrass curve P-224 over a prime field. Also /// known as secp224r1. #[no_mangle] pub static P224: Ecc = Ecc::new(44, 224); /// Represents the Weierstrass curve P-256 over a prime field. Also /// known as prime256v1 and secp256r1. #[no_mangle] pub static P256: Ecc = Ecc::new(45, 256); /// Represents the Weierstrass curve P-384 over a prime field. Also /// known as secp384r1. #[no_mangle] pub static P384: Ecc = Ecc::new(46, 384); /// Represents the Weierstrass curve P-521 over a prime field. Also /// known as secp521r1. #[no_mangle] pub static P521: Ecc = Ecc::new(47, 521); /// Represents the prime192v1 curve as specified in ANSI x9.62. Also /// known as secp192r1 and P-192. #[no_mangle] pub static PRIME192V1: Ecc = P192; /// Represents the prime192v2 curve as specified in ANSI x9.62. #[no_mangle] pub static PRIME192V2: Ecc = Ecc::new(48, 192); /// Represents the prime192v3 curve as specified in ANSI x9.62. #[no_mangle] pub static PRIME192V3: Ecc = Ecc::new(49, 192); /// Represents the prime239v1 curve as specified in ANSI x9.62. #[no_mangle] pub static PRIME239V1: Ecc = Ecc::new(50, 239); /// Represents the prime239v2 curve as specified in ANSI x9.62. #[no_mangle] pub static PRIME239V2: Ecc = Ecc::new(51, 239); /// Represents the prime239v3 curve as specified in ANSI x9.62. #[no_mangle] pub static PRIME239V3: Ecc = Ecc::new(52, 239); /// Represents the prime256v1 curve as specified in ANSI x9.62. Also /// known as P-256 and secp256r1. #[no_mangle] pub static PRIME256V1: Ecc = P256; /// Represents the secp112r1 curve as defined in [SEC 2]. Also known /// as wap-wsg-idm-ecid-wtls6. /// /// [SEC 2]: https://www.secg.org/SEC2-Ver-1.0.pdf #[no_mangle] pub static SECP112R1: Ecc = Ecc::new(53, 112); /// Represents the secp112r2 curve as defined in [SEC 2]. /// /// [SEC 2]: https://www.secg.org/SEC2-Ver-1.0.pdf #[no_mangle] pub static SECP112R2: Ecc = Ecc::new(54, 112); /// Represents the secp128r1 curve as defined in [SEC 2]. /// /// [SEC 2]: https://www.secg.org/SEC2-Ver-1.0.pdf #[no_mangle] pub static SECP128R1: Ecc = Ecc::new(55, 128); /// Represents the secp128r2 curve as defined in [SEC 2]. /// /// [SEC 2]: https://www.secg.org/SEC2-Ver-1.0.pdf #[no_mangle] pub static SECP128R2: Ecc = Ecc::new(56, 128); /// Represents the secp160k1 curve as defined in [SEC 2]. /// /// [SEC 2]: https://www.secg.org/SEC2-Ver-1.0.pdf #[no_mangle] pub static SECP160K1: Ecc = Ecc::new(58, 160); /// Represents the secp160r1 curve as defined in [SEC 2]. Also known as /// wap-wsg-idm-ecid-wtls7. /// /// [SEC 2]: https://www.secg.org/SEC2-Ver-1.0.pdf #[no_mangle] pub static SECP160R1: Ecc = Ecc::new(57, 160); /// Represents the secp160r2 curve as defined in [SEC 2]. /// /// [SEC 2]: https://www.secg.org/SEC2-Ver-1.0.pdf #[no_mangle] pub static SECP160R2: Ecc = Ecc::new(59, 160); /// Represents the secp192r1 curve as defined in [SEC 2]. Also known as /// prime192v1 and P-192. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static SECP192R1: Ecc = P192; /// Represents the secp192k1 curve as defined in [SEC 2]. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static SECP192K1: Ecc = Ecc::new(60, 192); /// Represents the secp224r1 curve as defined in [SEC 2]. Also known as /// P-224, secp224r1, and wap-wsg-idm-ecid-wtls12. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static SECP224R1: Ecc = P224; /// Represents the secp224k1 curve as defined in [SEC 2]. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static SECP224K1: Ecc = Ecc::new(61, 224); /// Represents the curve secp256k1 specified in [SEC 2]. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static SECP256K1: Ecc = Ecc::new(62, 256); /// Represents the secp256r1 curve as defined in [SEC 2]. Also known as /// prime256v1 and P-256. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static SECP256R1: Ecc = P256; /// Represents the secp384r1 curve as defined in [SEC 2]. Also known as /// P-384. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static SECP384R1: Ecc = P384; /// Represents the secp521r1 curve as defined in [SEC 2]. Also known as /// P-521. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static SECP521R1: Ecc = P521; /// Represents the sect113r1 curve as defined in [SEC 2]. Also known as /// wap-wsg-idm-ecid-wtls4. /// /// [SEC 2]: https://www.secg.org/SEC2-Ver-1.0.pdf #[no_mangle] pub static SECT113R1: Ecc = Ecc::new(63, 113); /// Represents the sect113r2 curve as defined in [SEC 2]. /// /// [SEC 2]: https://www.secg.org/SEC2-Ver-1.0.pdf #[no_mangle] pub static SECT113R2: Ecc = Ecc::new(64, 113); /// Represents the sect131r1 curve as defined in [SEC 2]. /// /// [SEC 2]: https://www.secg.org/SEC2-Ver-1.0.pdf #[no_mangle] pub static SECT131R1: Ecc = Ecc::new(65, 131); /// Represents the sect131r2 curve as defined in [SEC 2]. /// /// [SEC 2]: https://www.secg.org/SEC2-Ver-1.0.pdf #[no_mangle] pub static SECT131R2: Ecc = Ecc::new(66, 131); /// Represents the sect163k1 curve as defined in [SEC 2]. Also known as /// K-163 and wap-wsg-idm-ecid-wtls3. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static SECT163K1: Ecc = K163; /// Represents the sect163r1 curve as defined in [SEC 2]. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static SECT163R1: Ecc = Ecc::new(67, 163); /// Represents the sect163r2 curve as defined in [SEC 2]. Also known as /// B-163. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static SECT163R2: Ecc = B163; /// Represents the sect193r1 curve as defined in [SEC 2]. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static SECT193R1: Ecc = Ecc::new(68, 193); /// Represents the sect193r2 curve as defined in [SEC 2]. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static SECT193R2: Ecc = Ecc::new(69, 193); /// Represents the sect233k1 curve as defined in [SEC 2]. Also known as /// K-233 and wap-wsg-idm-ecid-wtls10. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static SECT233K1: Ecc = K233; /// Represents the sect233r1 curve as defined in [SEC 2]. Also known as /// B-233 and wap-wsg-idm-ecid-wtls11. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static SECT233R1: Ecc = B233; /// Represents the sect239k1 curve as defined in [SEC 2]. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static SECT239K1: Ecc = Ecc::new(70, 239); /// Represents the sect283r1 curve as defined in [SEC 2]. Also known as /// B-283. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static SECT283R1: Ecc = B283; /// Represents the sect283k1 curve as defined in [SEC 2]. Also known as /// K-283. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static SECT283K1: Ecc = K283; /// Represents the sect409k1 curve as defined in [SEC 2]. Also known as /// K-409. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static SECT409K1: Ecc = K409; /// Represents the sect409r1 curve as defined in [SEC 2]. Also known as /// B-409. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static SECT409R1: Ecc = B409; /// Represents the sect571k1 curve as defined in [SEC 2]. Also known as /// K-571. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static SECT571K1: Ecc = K571; /// Represents the sect571r1 curve as defined in [SEC 2]. Also known as /// B-571. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static SECT571R1: Ecc = B571; /// Represents the SM2 digital signature algorithm as defined in /// draft-shen-sm2-ecdsa-02. /// /// [draft-shen-sm2-ecdsa-02]: https://datatracker.ietf.org/doc/html/draft-shen-sm2-ecdsa-02 #[no_mangle] pub static SM2: Ecc = Ecc::new(71, 256); /// Represents the wap-wsg-idm-ecid-wtls1 curve as specified in /// [WAP-WTLS curves]. /// /// [WAP-WTLS curves]: https://www.wapforum.org/tech/documents/WAP-199-WTLS-20000218-a.pdf #[no_mangle] pub static WAP_WSG_IDM_ECID_WTLS1: Ecc = Ecc::new(72, 113); /// Represents the wap-wsg-idm-ecid-wtls3 curve as specified in /// [WAP-WTLS curves]. Also known as sect163k1. /// /// [WAP-WTLS curves]: https://www.wapforum.org/tech/documents/WAP-199-WTLS-20000218-a.pdf #[no_mangle] pub static WAP_WSG_IDM_ECID_WTLS3: Ecc = K163; /// Represents the wap-wsg-idm-ecid-wtls4 curve as specified in /// [WAP-WTLS curves]. Also known as sect113r1. /// /// [WAP-WTLS curves]: https://www.wapforum.org/tech/documents/WAP-199-WTLS-20000218-a.pdf #[no_mangle] pub static WAP_WSG_IDM_ECID_WTLS4: Ecc = SECT113R1; /// Represents the wap-wsg-idm-ecid-wtls5 curve as specified in /// [WAP-WTLS curves]. Also known as c2pnb163v1. /// /// [WAP-WTLS curves]: https://www.wapforum.org/tech/documents/WAP-199-WTLS-20000218-a.pdf #[no_mangle] pub static WAP_WSG_IDM_ECID_WTLS5: Ecc = C2PNB163V1; /// Represents the wap-wsg-idm-ecid-wtls6 curve as specified in /// [WAP-WTLS curves]. Also known as secp112r1. /// /// [WAP-WTLS curves]: https://www.wapforum.org/tech/documents/WAP-199-WTLS-20000218-a.pdf #[no_mangle] pub static WAP_WSG_IDM_ECID_WTLS6: Ecc = SECP112R1; /// Represents the wap-wsg-idm-ecid-wtls7 curve as specified in /// [WAP-WTLS curves]. Also known as secp160r1. /// /// [WAP-WTLS curves]: https://www.wapforum.org/tech/documents/WAP-199-WTLS-20000218-a.pdf #[no_mangle] pub static WAP_WSG_IDM_ECID_WTLS7: Ecc = SECP160R1; /// Represents the wap-wsg-idm-ecid-wtls8 curve as specified in /// [WAP-WTLS curves]. /// /// [WAP-WTLS curves]: https://www.wapforum.org/tech/documents/WAP-199-WTLS-20000218-a.pdf #[no_mangle] pub static WAP_WSG_IDM_ECID_WTLS8: Ecc = Ecc::new(73, 112); /// Represents the wap-wsg-idm-ecid-wtls9 curve as specified in /// [WAP-WTLS curves]. /// /// [WAP-WTLS curves]: https://www.wapforum.org/tech/documents/WAP-199-WTLS-20000218-a.pdf #[no_mangle] pub static WAP_WSG_IDM_ECID_WTLS9: Ecc = Ecc::new(74, 160); /// Represents the wap-wsg-idm-ecid-wtls10 curve as specified in /// [WAP-WTLS curves]. Also known as K-233 and sect233k1. /// /// [WAP-WTLS curves]: https://www.wapforum.org/tech/documents/WAP-199-WTLS-20000218-a.pdf #[no_mangle] pub static WAP_WSG_IDM_ECID_WTLS10: Ecc = K233; /// Represents the wap-wsg-idm-ecid-wtls11 curve as specified in /// [WAP-WTLS curves]. Also known as B-233 and sect233r1. /// /// [WAP-WTLS curves]: https://www.wapforum.org/tech/documents/WAP-199-WTLS-20000218-a.pdf #[no_mangle] pub static WAP_WSG_IDM_ECID_WTLS11: Ecc = B233; /// Represents the wap-wsg-idm-ecid-wtls12 curve as specified in /// [WAP-WTLS curves]. Also known as P-224 and secp224r1. /// /// [WAP-WTLS curves]: https://www.wapforum.org/tech/documents/WAP-199-WTLS-20000218-a.pdf #[no_mangle] pub static WAP_WSG_IDM_ECID_WTLS12: Ecc = P224; /// Represents the X25519 algorithm as it appears in [RFC 7748]. /// /// [RFC 7748]: https://datatracker.ietf.org/doc/html/rfc7748 #[no_mangle] pub static X25519: Ecc = Ecc::new(75, 256); /// Represents the X448 algorithm as it appears in [RFC 7748]. /// /// [RFC 7748]: https://datatracker.ietf.org/doc/html/rfc7748 #[no_mangle] pub static X448: Ecc = Ecc::new(76, 448); /// Generic instance that represents a choice of f = 224 for an elliptic /// curve primitive. #[no_mangle] pub static ECC_224: Ecc = Ecc::new(65531, 224); /// Generic instance that represents a choice of f = 256 for an elliptic /// curve primitive. #[no_mangle] pub static ECC_256: Ecc = Ecc::new(65532, 256); /// Generic instance that represents a choice of f = 384 for an elliptic /// curve primitive. #[no_mangle] pub static ECC_384: Ecc = Ecc::new(65533, 384); /// Generic instance that represents a choice of f = 512 for an elliptic /// curve primitive. #[no_mangle] pub static ECC_512: Ecc = Ecc::new(65534, 512); /// Placeholder for use in where this primitive or the security level it /// implies is not allowed. #[no_mangle] pub static ECC_NOT_ALLOWED: Ecc = Ecc::new(u16::MAX, u16::MAX); 07070100000089000081A40000000000000000000000016537CEF400000B55000000000000000000000000000000000000003300000000wardstone-0.2.0~0/crates/core/src/primitive/ffc.rs//! Finite field primitive and some common instances. use std::fmt::{Display, Formatter, Result}; use crate::primitive::{Primitive, Security}; /// Represents a finite field cryptography primitive used to implement /// discrete logarithm cryptography. /// /// The choices l and n represents the bit lengths of the prime modulus /// p and the prime divisor q. /// /// Some of the primitives that fall under this category include /// signature algorithms such as DSA and key establishment algorithms /// such as Diffie-Hellman and MQV. #[repr(C)] #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub struct Ffc { pub id: u16, pub l: u16, pub n: u16, } impl Primitive for Ffc { /// The security of a finite field cryptography primitive defined as /// the minimum of the (L, N) pair where the hash function used /// provides at least the same level of security. fn security(&self) -> Security { // FIPS-186-4 cites that the security strength associated with the // DSA digital signature process is no greater than the minimum of // the security strength of the (L, N) pair (2013, p. 15). The // public keys are usually the shorter of the two and this value is // divided by 2 to produce the security value (see page 54 of // SP-800-57 Part 1 Rev. 5). self.l.min(self.n) >> 1 } } impl Ffc { pub const fn new(id: u16, l: u16, n: u16) -> Self { Self { id, l, n } } } impl Display for Ffc { fn fmt(&self, f: &mut Formatter<'_>) -> Result { write!(f, "dsa_{}_{}", self.l, self.n) } } /// An identifier for custom DSA keys. #[no_mangle] pub static ID_DSA: u16 = 65534; /// Generic instance that represents a choice of L = 1024 and N = 160 /// for a finite field cryptography primitive. #[no_mangle] pub static DSA_1024_160: Ffc = Ffc::new(1, 1024, 160); /// Generic instance that represents a choice of L = 2048 and N = 224 /// for a finite field cryptography primitive. #[no_mangle] pub static DSA_2048_224: Ffc = Ffc::new(2, 2048, 224); /// Generic instance that represents a choice of L = 2048 and N = 256 /// for a finite field cryptography primitive. #[no_mangle] pub static DSA_2048_256: Ffc = Ffc::new(3, 2048, 256); /// Generic instance that represents a choice of L = 3072 and N = 256 /// for a finite field cryptography primitive. #[no_mangle] pub static DSA_3072_256: Ffc = Ffc::new(4, 3072, 256); /// Generic instance that represents a choice of L = 7680 and N = 384 /// for a finite field cryptography primitive. #[no_mangle] pub static DSA_7680_384: Ffc = Ffc::new(5, 7680, 384); /// Generic instance that represents a choice of L = 15360 and N = 512 /// for a finite field cryptography primitive. #[no_mangle] pub static DSA_15360_512: Ffc = Ffc::new(6, 15360, 512); /// Placeholder for use in where this primitive is not supported. #[no_mangle] pub static FFC_NOT_SUPPORTED: Ffc = Ffc::new(u16::MAX, u16::MAX, u16::MAX); 0707010000008A000081A40000000000000000000000016537CEF400001E65000000000000000000000000000000000000003400000000wardstone-0.2.0~0/crates/core/src/primitive/hash.rs//! Hash function primitive and some common instances. use std::collections::HashMap; use std::fmt::{self, Display, Formatter}; use once_cell::sync::Lazy; use serde::Serialize; use crate::primitive::{Primitive, Security}; /// Represents a hash or hash-based function cryptographic primitive /// where `id` is a unique identifier and `n` the digest length. #[repr(C)] #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub struct Hash { pub id: u16, pub n: u16, } impl Hash { pub const fn new(id: u16, n: u16) -> Self { Self { id, n } } } // The name is kept in a lookup table instead of being embedded in the // type because sharing strings across language boundaries is a bit // dicey. static REPR: Lazy<HashMap<Hash, &str>> = Lazy::new(|| { let mut m = HashMap::new(); m.insert(BLAKE_224, "blake224"); m.insert(BLAKE_256, "blake256"); m.insert(BLAKE_384, "blake384"); m.insert(BLAKE_512, "blake512"); m.insert(BLAKE2B_256, "blake2b256"); m.insert(BLAKE2B_384, "blake2b384"); m.insert(BLAKE2B_512, "blake2b512"); m.insert(BLAKE2S_256, "blake2s256"); m.insert(BLAKE3, "blake3"); m.insert(MD4, "md4"); m.insert(MD5, "md5"); m.insert(RIPEMD160, "ripemd160"); m.insert(SHA1, "sha1"); m.insert(SHA224, "sha224"); m.insert(SHA256, "sha256"); m.insert(SHA384, "sha384"); m.insert(SHA512, "sha512"); m.insert(SHA3_224, "sha3_224"); m.insert(SHA3_256, "sha3_256"); m.insert(SHA3_384, "sha3_384"); m.insert(SHA3_512, "sha3_512"); m.insert(SHA512_224, "sha512/224"); m.insert(SHA512_256, "sha512/256"); m.insert(SHAKE128, "shake128"); m.insert(SHAKE256, "shake256"); m.insert(WHIRLPOOL, "whirlpool"); m }); impl Display for Hash { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { let unrecognised = "unrecognised"; let name = REPR.get(self).unwrap_or(&unrecognised); write!(f, "{name}") } } impl Primitive for Hash { /// Returns the security of a hash function measured as the collision /// resistance strength of a hash function. /// /// For an L-bit hash function, the expected security strength for /// collision resistance is L/2 bits (see page 6 of NIST SP-800-107). /// /// Some applications that use hash functions only require pre-image /// resistance which imposes a less stringent security requirement of /// just L (see page 7 of NIST SP-800-107). fn security(&self) -> Security { self.n >> 1 } } impl Serialize for Hash { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer, { let s = format!("{}", self); serializer.serialize_str(&s) } } /// The BLAKE-224 hash function. #[no_mangle] pub static BLAKE_224: Hash = Hash::new(1, 224); /// The BLAKE-256 hash function. #[no_mangle] pub static BLAKE_256: Hash = Hash::new(2, 256); /// The BLAKE-384 hash function. #[no_mangle] pub static BLAKE_384: Hash = Hash::new(3, 384); /// The BLAKE-512 hash function. #[no_mangle] pub static BLAKE_512: Hash = Hash::new(4, 512); /// The BLAKE2b hash function as defined in [RFC 7693]. /// /// [RFC 7693]: https://www.rfc-editor.org/rfc/rfc7693.html #[no_mangle] pub static BLAKE2B_256: Hash = Hash::new(5, 256); /// The BLAKE2b hash function as defined in [RFC 7693]. /// /// [RFC 7693]: https://www.rfc-editor.org/rfc/rfc7693.html #[no_mangle] pub static BLAKE2B_384: Hash = Hash::new(6, 384); /// The BLAKE2b hash function as defined in [RFC 7693]. /// /// [RFC 7693]: https://www.rfc-editor.org/rfc/rfc7693.html #[no_mangle] pub static BLAKE2B_512: Hash = Hash::new(7, 512); /// The BLAKE2s hash function as defined in [RFC 7693]. /// /// [RFC 7693]: https://www.rfc-editor.org/rfc/rfc7693.html #[no_mangle] pub static BLAKE2S_256: Hash = Hash::new(8, 256); /// The BLAKE3 hash function. #[no_mangle] pub static BLAKE3: Hash = Hash::new(9, 256); /// The MD4 hash function as defined in [RFC 1320]. /// /// **Warning:** This algorithm has been shown to be broken. It should /// only be used where compatibility with legacy systems, not security, /// is the goal. /// /// [RFC 1320]: https://www.rfc-editor.org/rfc/rfc1320.html #[no_mangle] pub static MD4: Hash = Hash::new(10, 128); /// The MD5 hash function as defined in [RFC 1321]. /// /// **Warning:** This algorithm has been shown to lack collision /// resistance and should generally not be used for secure applications. /// /// [RFC 1321]: https://www.rfc-editor.org/rfc/rfc1321.html #[no_mangle] pub static MD5: Hash = Hash::new(11, 128); /// The RIPEMD-160 hash function. /// /// **Warning:** This algorithm has been shown to be broken. It should /// only be used where compatibility with legacy systems, not security, /// is the goal. #[no_mangle] pub static RIPEMD160: Hash = Hash::new(12, 160); /// The SHA1 hash function as defined in [RFC 3174]. /// /// **Warning:** This algorithm has been shown to lack collision /// resistance and should generally not be used for secure applications. /// /// While this algorithm produced a digest length of 160 bits, it's /// security is believed to be lower. Here it is recorded to be 105 per /// page 8 of NIST SP 800-107. /// /// [RFC 3174]: https://www.rfc-editor.org/rfc/rfc3174.html #[no_mangle] pub static SHA1: Hash = Hash::new(13, 160); /// The SHA224 hash function as defined in [FIPS 180-4]. /// /// [FIPS 180-4]: https://doi.org/10.6028/NIST.FIPS.180-4 #[no_mangle] pub static SHA224: Hash = Hash::new(14, 224); /// The SHA256 hash function as defined in [FIPS 180-4]. /// /// [FIPS 180-4]: https://doi.org/10.6028/NIST.FIPS.180-4 #[no_mangle] pub static SHA256: Hash = Hash::new(15, 256); /// The SHA384 hash function as defined in [FIPS 180-4]. /// /// [FIPS 180-4]: https://doi.org/10.6028/NIST.FIPS.180-4 #[no_mangle] pub static SHA384: Hash = Hash::new(16, 384); /// The SHA3-224 hash function as defined in [FIPS 202]. /// /// [FIPS 202]: https://doi.org/10.6028/NIST.FIPS.202 #[no_mangle] pub static SHA3_224: Hash = Hash::new(17, 224); /// The SHA3-256 hash function as defined in [FIPS 202]. /// /// [FIPS 202]: https://doi.org/10.6028/NIST.FIPS.202 #[no_mangle] pub static SHA3_256: Hash = Hash::new(18, 256); /// The SHA3-384 hash function as defined in [FIPS 202]. /// /// [FIPS 202]: https://doi.org/10.6028/NIST.FIPS.202 #[no_mangle] pub static SHA3_384: Hash = Hash::new(19, 384); /// The SHA3-512 hash function as defined in [FIPS 202]. /// /// [FIPS 202]: https://doi.org/10.6028/NIST.FIPS.202 #[no_mangle] pub static SHA3_512: Hash = Hash::new(20, 512); /// The SHA512 hash function as defined in [FIPS 180-4]. /// /// [FIPS 180-4]: https://doi.org/10.6028/NIST.FIPS.180-4 #[no_mangle] pub static SHA512: Hash = Hash::new(21, 512); /// The SHA512/224 hash function as defined in [FIPS 180-4]. /// /// [FIPS 180-4]: https://doi.org/10.6028/NIST.FIPS.180-4 #[no_mangle] pub static SHA512_224: Hash = Hash::new(22, 224); /// The SHA512/256 hash function as defined in [FIPS 180-4]. /// /// [FIPS 180-4]: https://doi.org/10.6028/NIST.FIPS.180-4 #[no_mangle] pub static SHA512_256: Hash = Hash::new(23, 256); /// The SHAKE128 extendable-output function as defined in [FIPS 202]. /// This assumes an output length of 128-bits. /// /// [FIPS 202]: https://doi.org/10.6028/NIST.FIPS.202 #[no_mangle] pub static SHAKE128: Hash = Hash::new(24, 128); /// The SHAKE256 extendable-output function as defined in [FIPS 202]. /// This assumes an output length of 256-bits. /// /// [FIPS 202]: https://doi.org/10.6028/NIST.FIPS.202 #[no_mangle] pub static SHAKE256: Hash = Hash::new(25, 256); /// The WHIRLPOOL hash function as defined in ISO/IEC 10118-3. #[no_mangle] pub static WHIRLPOOL: Hash = Hash::new(26, 512); /// Placeholder for use in where this primitive is not supported. #[no_mangle] pub static HASH_NOT_SUPPORTED: Hash = Hash::new(u16::MAX, u16::MAX); 0707010000008B000081A40000000000000000000000016537CEF400000FE0000000000000000000000000000000000000003300000000wardstone-0.2.0~0/crates/core/src/primitive/ifc.rs//! Integer factorisation primitive and some common instances. use std::fmt::{self, Display, Formatter}; use crate::primitive::{Primitive, Security}; /// Represents an integer factorisation cryptography primitive the most /// common of which is the RSA signature algorithm where k indicates the /// key size. #[repr(C)] #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub struct Ifc { pub id: u16, pub k: u16, } impl Ifc { pub const fn new(id: u16, k: u16) -> Self { Self { id, k } } } impl Display for Ifc { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { if self.id == ID_RSA_PKCS1 || matches!(self.id, 1..=8) { write!(f, "rsa_pkcs1_{}", self.k) } else if self.id == ID_RSA_PSS || matches!(self.id, 9..=17) { write!(f, "rsa_pss_{}", self.k) } else if self.id == u16::MAX { write!(f, "not allowed") } else { write!(f, "unrecognised") } } } impl Primitive for Ifc { /// Returns the approximate *minimum* security provided by a key of /// the size `k`. fn security(&self) -> Security { match self.k { ..=1023 => 0, 1024..=2047 => 80, 2048..=3071 => 112, 3072..=7679 => 128, 7680..=15359 => 192, 15360.. => 256, } } } /// An identifier for custom RSA with PKCS #1 v1.5 padding keys. /// /// This for use in creating custom keys in that can be used in /// standards that make a distinction between RSA padding schemes. #[no_mangle] pub static ID_RSA_PKCS1: u16 = 65533; /// An identifier for custom RSA with PSS encoding keys. /// /// This for use in creating custom keys in that can be used in /// standards that make a distinction between RSA padding schemes. #[no_mangle] pub static ID_RSA_PSS: u16 = 65534; /// 1024-bit RSA with PKCS #1 v1.5 padding as defined in RFC 8446. #[no_mangle] pub static RSA_PKCS1_1024: Ifc = Ifc::new(1, 1024); /// 1536-bit RSA with PKCS #1 v1.5 padding as defined in RFC 8446. #[no_mangle] pub static RSA_PKCS1_1536: Ifc = Ifc::new(2, 1536); /// 2048-bit RSA with PKCS #1 v1.5 padding as defined in RFC 8446. #[no_mangle] pub static RSA_PKCS1_2048: Ifc = Ifc::new(3, 2048); /// 3072-bit RSA with PKCS #1 v1.5 padding as defined in RFC 8446. #[no_mangle] pub static RSA_PKCS1_3072: Ifc = Ifc::new(4, 3072); /// 4096-bit RSA with PKCS #1 v1.5 padding as defined in RFC 8446. #[no_mangle] pub static RSA_PKCS1_4096: Ifc = Ifc::new(5, 4096); /// 7680-bit RSA with PKCS #1 v1.5 padding as defined in RFC 8446. #[no_mangle] pub static RSA_PKCS1_7680: Ifc = Ifc::new(6, 7680); /// 8192-bit RSA with PKCS #1 v1.5 padding as defined in RFC 8446. #[no_mangle] pub static RSA_PKCS1_8192: Ifc = Ifc::new(7, 8192); /// 15360-bit RSA with PKCS #1 v1.5 padding as defined in RFC 8446. #[no_mangle] pub static RSA_PKCS1_15360: Ifc = Ifc::new(8, 15360); /// 1024-bit RSA with PSS encoding as defined in RFC 8446. #[no_mangle] pub static RSA_PSS_1024: Ifc = Ifc::new(9, 1024); /// 1280-bit RSA with PSS encoding as defined in RFC 8446. #[no_mangle] pub static RSA_PSS_1280: Ifc = Ifc::new(10, 1280); /// 1536-bit RSA with PSS encoding as defined in RFC 8446. #[no_mangle] pub static RSA_PSS_1536: Ifc = Ifc::new(11, 1536); /// 2048-bit RSA with PSS encoding as defined in RFC 8446.. #[no_mangle] pub static RSA_PSS_2048: Ifc = Ifc::new(12, 2048); /// 3072-bit RSA with PSS encoding as defined in RFC 8446. #[no_mangle] pub static RSA_PSS_3072: Ifc = Ifc::new(13, 3072); /// 4096-bit RSA with PSS encoding as defined in RFC 8446. #[no_mangle] pub static RSA_PSS_4096: Ifc = Ifc::new(14, 4096); /// 7680-bit RSA with PSS encoding as defined in RFC 8446. #[no_mangle] pub static RSA_PSS_7680: Ifc = Ifc::new(15, 7680); /// 7680-bit RSA with PSS encoding as defined in RFC 8446. #[no_mangle] pub static RSA_PSS_8192: Ifc = Ifc::new(16, 8192); /// 15360-bit RSA with PSS encoding as defined in RFC 8446. #[no_mangle] pub static RSA_PSS_15360: Ifc = Ifc::new(17, 15360); /// Placeholder for use in where this primitive is not allowed. #[no_mangle] pub static IFC_NOT_ALLOWED: Ifc = Ifc::new(u16::MAX, u16::MAX); 0707010000008C000081A40000000000000000000000016537CEF400000B32000000000000000000000000000000000000003900000000wardstone-0.2.0~0/crates/core/src/primitive/symmetric.rs//! Symmetric key primitive and some common instances. use crate::primitive::{Primitive, Security}; /// Represents a symmetric key cryptography primitive. #[repr(C)] #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub struct Symmetric { pub id: u16, pub security: u16, } impl Symmetric { pub const fn new(id: u16, security: u16) -> Self { Self { id, security } } } impl Primitive for Symmetric { /// Indicates the security provided by a symmetric key primitive. fn security(&self) -> Security { self.security } } /// The Advanced Encryption Standard algorithm as defined in [FIPS 197]. /// /// [FIPS 197]: https://doi.org/10.6028/NIST.FIPS.197 #[no_mangle] pub static AES128: Symmetric = Symmetric::new(1, 128); /// The Advanced Encryption Standard algorithm as defined in [FIPS 197]. /// /// [FIPS 197]: https://doi.org/10.6028/NIST.FIPS.197 #[no_mangle] pub static AES192: Symmetric = Symmetric::new(2, 192); /// The Advanced Encryption Standard algorithm as defined in [FIPS 197]. /// /// [FIPS 197]: https://doi.org/10.6028/NIST.FIPS.197 #[no_mangle] pub static AES256: Symmetric = Symmetric::new(3, 256); /// The Camellia encryption algorithm as defined in [RFC 3713]. /// /// [RFC 3713]: https://datatracker.ietf.org/doc/html/rfc3713 #[no_mangle] pub static CAMELLIA128: Symmetric = Symmetric::new(4, 128); /// The Camellia encryption algorithm as defined in [RFC 3713]. /// /// [RFC 3713]: https://datatracker.ietf.org/doc/html/rfc3713 #[no_mangle] pub static CAMELLIA192: Symmetric = Symmetric::new(5, 192); /// The Camellia encryption algorithm as defined in [RFC 3713]. /// /// [RFC 3713]: https://datatracker.ietf.org/doc/html/rfc3713 #[no_mangle] pub static CAMELLIA256: Symmetric = Symmetric::new(6, 256); /// The Data Encryption Standard algorithm. #[no_mangle] pub static DES: Symmetric = Symmetric::new(8, 56); /// The DES-X encryption algorithm. #[no_mangle] pub static DESX: Symmetric = Symmetric::new(9, 120); /// The International Data Encryption algorithm. #[no_mangle] pub static IDEA: Symmetric = Symmetric::new(10, 126 /* See Wikipedia article. */); /// The Serpent encryption algorithm. #[no_mangle] pub static SERPENT128: Symmetric = Symmetric::new(11, 128); /// The Serpent encryption algorithm. #[no_mangle] pub static SERPENT192: Symmetric = Symmetric::new(12, 192); /// The Serpent encryption algorithm. #[no_mangle] pub static SERPENT256: Symmetric = Symmetric::new(13, 256); /// The two-key Triple Data Encryption Algorithm as defined in /// [SP800-67]. /// /// [SP800-67]: https://doi.org/10.6028/NIST.SP.800-67r2 #[no_mangle] pub static TDEA2: Symmetric = Symmetric::new(14, 95); /// The three-key Triple Data Encryption Algorithm as defined in /// [SP800-67]. /// /// [SP800-67]: https://doi.org/10.6028/NIST.SP.800-67r2 #[no_mangle] pub static TDEA3: Symmetric = Symmetric::new(15, 112); 0707010000008D000041ED0000000000000000000000026537CEF400000000000000000000000000000000000000000000002B00000000wardstone-0.2.0~0/crates/core/src/standard0707010000008E000081A40000000000000000000000016537CEF4000005BB000000000000000000000000000000000000002E00000000wardstone-0.2.0~0/crates/core/src/standard.rs//! Assess the security of a cryptographic primitive against a standard //! or research publication. pub mod bsi; pub mod cnsa; pub mod ecrypt; pub mod lenstra; pub mod nist; pub mod testing; mod utilities; use crate::context::Context; use crate::primitive::asymmetric::Asymmetric; use crate::primitive::ecc::Ecc; use crate::primitive::ffc::Ffc; use crate::primitive::hash::Hash; use crate::primitive::ifc::Ifc; use crate::primitive::symmetric::Symmetric; /// Represents a cryptographic standard or research publication. /// /// The functions are used to assess the validity of various /// cryptographic primitives against the standard. pub trait Standard { fn validate_asymmetric(ctx: Context, key: Asymmetric) -> Result<Asymmetric, Asymmetric> { match key { Asymmetric::Ecc(ecc) => Self::validate_ecc(ctx, ecc) .map(Into::into) .map_err(Into::into), Asymmetric::Ifc(ifc) => Self::validate_ifc(ctx, ifc) .map(Into::into) .map_err(Into::into), Asymmetric::Ffc(ffc) => Self::validate_ffc(ctx, ffc) .map(Into::into) .map_err(Into::into), } } fn validate_ecc(ctx: Context, key: Ecc) -> Result<Ecc, Ecc>; fn validate_ffc(ctx: Context, key: Ffc) -> Result<Ffc, Ffc>; fn validate_ifc(ctx: Context, key: Ifc) -> Result<Ifc, Ifc>; fn validate_hash(ctx: Context, hash: Hash) -> Result<Hash, Hash>; fn validate_symmetric(ctx: Context, key: Symmetric) -> Result<Symmetric, Symmetric>; } 0707010000008F000081A40000000000000000000000016537CEF400004381000000000000000000000000000000000000003200000000wardstone-0.2.0~0/crates/core/src/standard/bsi.rs//! Validate cryptographic primitives against the [BSI TR-02102-1 //! Cryptographic Mechanisms: Recommendations and Key Lengths] technical //! guide. //! //! [BSI TR-02102-1 Cryptographic Mechanisms: Recommendations and Key Lengths]: https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/TechGuidelines/TG02102/BSI-TR-02102-1.html use std::collections::HashSet; use once_cell::sync::Lazy; use crate::context::Context; use crate::primitive::ecc::*; use crate::primitive::ffc::*; use crate::primitive::hash::*; use crate::primitive::ifc::*; use crate::primitive::symmetric::*; use crate::primitive::Primitive; use crate::standard::Standard; const CUTOFF_YEAR_RSA: u16 = 2023; // See p. 17. static SPECIFIED_CURVES: Lazy<HashSet<Ecc>> = Lazy::new(|| { let mut s = HashSet::new(); s.insert(SECP256R1); s.insert(SECP384R1); s.insert(SECP521R1); s.insert(BRAINPOOLP256R1); s.insert(BRAINPOOLP320R1); s.insert(BRAINPOOLP384R1); s.insert(BRAINPOOLP512R1); s }); static SPECIFIED_HASH_FUNCTIONS: Lazy<HashSet<Hash>> = Lazy::new(|| { let mut s = HashSet::new(); s.insert(SHA256); s.insert(SHA384); s.insert(SHA3_256); s.insert(SHA3_384); s.insert(SHA3_512); s.insert(SHA512); s.insert(SHA512_256); s }); // "The present version of this Technical Guideline does not recommend // any other block ciphers besides AES" (2023, p. 24). static SPECIFIED_SYMMETRIC_KEYS: Lazy<HashSet<Symmetric>> = Lazy::new(|| { let mut s = HashSet::new(); s.insert(AES128); s.insert(AES192); s.insert(AES256); s }); /// [`Standard`] implementation for the /// [BSI TR-02102-1 Cryptographic Mechanisms: Recommendations and Key /// Lengths] technical guide. /// /// [BSI TR-02102-1 Cryptographic Mechanisms: Recommendations and Key Lengths]: https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/TechGuidelines/TG02102/BSI-TR-02102-1.html pub struct Bsi; impl Bsi { /// Validates a hash function. The reference is made with regards to /// applications that primarily require pre-image resistance such as /// message authentication codes (MACs), key derivation functions /// (KDFs), and random bit generation. /// /// For applications that require collision resistance such digital /// signatures use /// [`validate_hash`](crate::standard::bsi::Bsi::validate_hash). /// /// If the hash function is not compliant then `Err` will contain the /// recommended primitive that one should use instead. /// /// If the hash function is compliant but the context specifies a /// higher security level, `Ok` will also hold the recommended /// primitive with the desired security level. /// /// **Note:** For an HMAC the minimum security required is ≥ 128 (see /// p. 45) but the minimum digest length for a hash function that can /// be used with this primitive is 256 (see p. 41). This means any /// recommendation from this function will be likely too conservative. /// /// An alternative might also be suggested for a compliant hash /// functions with a similar security level in which a switch to the /// recommended primitive would likely be unwarranted. For example, /// when evaluating compliance for the `SHA3-256`, a recommendation /// to use `SHA256` will be made but switching to this as a result /// is likely unnecessary. /// /// # Example /// /// The following illustrates a call to validate a non-compliant hash /// function. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::hash::{SHA1, SHA256}; /// use wardstone_core::standard::bsi::Bsi; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// let hmac_sha1 = SHA1; /// let hmac_sha256 = SHA256; /// assert_eq!(Bsi::validate_hash_based(ctx, hmac_sha1), Err(hmac_sha256)); /// ``` pub fn validate_hash_based(ctx: Context, hash: Hash) -> Result<Hash, Hash> { if SPECIFIED_HASH_FUNCTIONS.contains(&hash) { let pre_image_resistance = hash.security() << 1; let security = ctx.security().max(pre_image_resistance); match security { ..=127 => Err(SHA256), 128..=256 => Ok(SHA256), 257..=384 => Ok(SHA384), 385.. => Ok(SHA512), } } else { Err(SHA256) } } } impl Standard for Bsi { /// Validate an elliptic curve cryptography primitive used for digital /// signatures and key establishment where f is the key size. /// /// If the key is not compliant then `Err` will contain the /// recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher /// security level, `Ok` will also hold the recommended primitive /// with the desired security level. /// /// **Note:** While the guide allows for elliptic curve system /// parameters "that are provided by a trustworthy authority" /// (see p. 73), this function conservatively deems any curve that is /// not explicitly stated as non-compliant. This means only the /// Brainpool and NIST curves that satisfy minimum security /// requirements are considered compliant. /// /// # Example /// /// The following illustrates a call to validate a compliant key. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::ecc::BRAINPOOLP256R1; /// use wardstone_core::standard::bsi::Bsi; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// assert_eq!(Bsi::validate_ecc(ctx, BRAINPOOLP256R1), Ok(BRAINPOOLP256R1)); /// ``` fn validate_ecc(ctx: Context, key: Ecc) -> Result<Ecc, Ecc> { if SPECIFIED_CURVES.contains(&key) { let security = ctx.security().max(key.security()); match security { ..=124 => Err(BRAINPOOLP256R1), 125..=128 => Ok(BRAINPOOLP256R1), 129..=160 => Ok(BRAINPOOLP320R1), 161..=192 => Ok(BRAINPOOLP384R1), 193.. => Ok(BRAINPOOLP512R1), } } else { Err(BRAINPOOLP256R1) } } /// Validates a finite field cryptography primitive. /// /// Examples include the DSA and key establishment algorithms such as /// Diffie-Hellman. /// /// If the key is not compliant then `Err` will contain the /// recommended key sizes L and N that one should use instead. /// /// If the key is compliant but the context specifies a higher /// security level, `Ok` will also hold the recommended key sizes L /// and N with the desired security level. /// /// # Example /// /// The following illustrates a call to validate a non-compliant key. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::ffc::{DSA_2048_224, DSA_3072_256}; /// use wardstone_core::standard::bsi::Bsi; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// let dsa_2048 = DSA_2048_224; /// let dsa_3072 = DSA_3072_256; /// assert_eq!(Bsi::validate_ffc(ctx, dsa_2048), Err(dsa_3072)); /// ``` fn validate_ffc(ctx: Context, key: Ffc) -> Result<Ffc, Ffc> { let security = ctx.security().max(key.security()); match security { // Page 48 says q > 2²⁵⁰. ..=124 => Err(DSA_3072_256), 125..=128 => Ok(DSA_3072_256), 129..=192 => Ok(DSA_7680_384), 193.. => Ok(DSA_15360_512), } } /// Validates a hash function according to page 41 of the guide. The /// reference is made with regards to applications that require /// collision resistance such as digital signatures. /// /// For applications that primarily require pre-image resistance such /// as message authentication codes (MACs), key derivation functions /// (KDFs), and random bit generation use /// [`validate_hash_based`](crate::standard::bsi::Bsi::validate_hash_based). /// /// If the hash function is not compliant then `Err` will contain the /// recommended primitive that one should use instead. /// /// If the hash function is compliant but the context specifies a /// higher security level, `Ok` will also hold the recommended /// primitive with the desired security level. /// /// **Note:** An alternative might be suggested for a compliant hash /// function with a similar security level in which a switch to the /// recommended primitive would likely be unwarranted. For example, /// when evaluating compliance for the `SHA3-256`, a recommendation /// to use `SHA256` will be made but switching to this as a result /// is likely unnecessary. /// /// # Example /// /// The following illustrates a call to validate a non-compliant hash /// function. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::hash::{SHA1, SHA256}; /// use wardstone_core::standard::bsi::Bsi; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// assert_eq!(Bsi::validate_hash(ctx, SHA1), Err(SHA256)); /// ``` fn validate_hash(ctx: Context, hash: Hash) -> Result<Hash, Hash> { if SPECIFIED_HASH_FUNCTIONS.contains(&hash) { let security = ctx.security().max(hash.security()); match security { ..=119 => Err(SHA256), 120..=128 => Ok(SHA256), 129..=192 => Ok(SHA384), 193.. => Ok(SHA512), } } else { Err(SHA256) } } /// Validates an integer factorisation cryptography primitive the /// most common of which is the RSA signature algorithm. /// /// If the key is not compliant then `Err` will contain the /// recommended key size that one should use instead. /// /// If the key is compliant but the context specifies a higher /// security level, `Ok` will also hold the recommended key size /// with the desired security level. /// /// **Note:** Unlike other functions in this module, this will return /// a generic structure that specifies minimum private and public /// key sizes. /// /// # Example /// /// The following illustrates a call to validate a compliant key. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::ifc::RSA_PSS_2048; /// use wardstone_core::standard::bsi::Bsi; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// assert_eq!(Bsi::validate_ifc(ctx, RSA_PSS_2048), Ok(RSA_PSS_2048)); /// ``` fn validate_ifc(ctx: Context, key: Ifc) -> Result<Ifc, Ifc> { let security = ctx.security().max(key.security()); match security { ..=111 => { if ctx.year() > CUTOFF_YEAR_RSA { Err(RSA_PSS_3072) } else { Err(RSA_PSS_2048) } }, 112..=127 => { if ctx.year() > CUTOFF_YEAR_RSA { Err(RSA_PSS_3072) } else { Ok(RSA_PSS_2048) } }, 128..=191 => Ok(RSA_PSS_3072), 192..=255 => Ok(RSA_PSS_7680), 256.. => Ok(RSA_PSS_15360), } } /// Validates a symmetric key primitive according to page 24 of the /// guide. /// /// If the key is not compliant then `Err` will contain the /// recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher /// security level, `Ok` will also hold the recommended primitive /// with the desired security level. /// /// # Example /// /// The following illustrates a call to validate a three-key Triple /// DES key (which is not recommended by the guide). /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::symmetric::{AES128, TDEA3}; /// use wardstone_core::standard::bsi::Bsi; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// assert_eq!(Bsi::validate_symmetric(ctx, TDEA3), Err(AES128)); /// ``` fn validate_symmetric(ctx: Context, key: Symmetric) -> Result<Symmetric, Symmetric> { if SPECIFIED_SYMMETRIC_KEYS.contains(&key) { let security = ctx.security().max(key.security()); match security { ..=119 => Err(AES128), 120..=128 => Ok(AES128), 129..=192 => Ok(AES192), 193.. => Ok(AES256), } } else { Err(AES128) } } } #[cfg(test)] mod tests { use super::*; use crate::{test_ecc, test_ffc, test_hash, test_hash_based, test_ifc, test_symmetric}; test_ecc!(p224, Bsi, P224, Err(BRAINPOOLP256R1)); test_ecc!(p256, Bsi, P256, Ok(BRAINPOOLP256R1)); test_ecc!(p384, Bsi, P384, Ok(BRAINPOOLP384R1)); test_ecc!(p521, Bsi, P521, Ok(BRAINPOOLP512R1)); test_ecc!(x25519, Bsi, X25519, Err(BRAINPOOLP256R1)); test_ecc!(x448, Bsi, X448, Err(BRAINPOOLP256R1)); test_ecc!(ed25519, Bsi, ED25519, Err(BRAINPOOLP256R1)); test_ecc!(ed448, Bsi, ED448, Err(BRAINPOOLP256R1)); test_ecc!(brainpoolp224r1, Bsi, BRAINPOOLP224R1, Err(BRAINPOOLP256R1)); test_ecc!(brainpoolp256r1, Bsi, BRAINPOOLP256R1, Ok(BRAINPOOLP256R1)); test_ecc!(brainpoolp320r1, Bsi, BRAINPOOLP320R1, Ok(BRAINPOOLP320R1)); test_ecc!(brainpoolp384r1, Bsi, BRAINPOOLP384R1, Ok(BRAINPOOLP384R1)); test_ecc!(brainpoolp512r1, Bsi, BRAINPOOLP512R1, Ok(BRAINPOOLP512R1)); test_ecc!(secp256k1, Bsi, SECP256K1, Err(BRAINPOOLP256R1)); test_ffc!(ffc_1024_160, Bsi, DSA_1024_160, Err(DSA_3072_256)); test_ffc!(ffc_2048_224, Bsi, DSA_2048_224, Err(DSA_3072_256)); test_ffc!(ffc_3072_256, Bsi, DSA_3072_256, Ok(DSA_3072_256)); test_ffc!(ffc_7680_384, Bsi, DSA_7680_384, Ok(DSA_7680_384)); test_ffc!(ffc_15360_512, Bsi, DSA_15360_512, Ok(DSA_15360_512)); test_ifc!(ifc_1024, Bsi, RSA_PSS_1024, Err(RSA_PSS_2048)); test_ifc!(ifc_2048, Bsi, RSA_PSS_2048, Ok(RSA_PSS_2048)); test_ifc!(ifc_3072, Bsi, RSA_PSS_3072, Ok(RSA_PSS_3072)); test_ifc!(ifc_7680, Bsi, RSA_PSS_7680, Ok(RSA_PSS_7680)); test_ifc!(ifc_15360, Bsi, RSA_PSS_15360, Ok(RSA_PSS_15360)); test_hash!( blake2b_256_collision_resistance, Bsi, BLAKE2B_256, Err(SHA256) ); test_hash!( blake2b_384_collision_resistance, Bsi, BLAKE2B_384, Err(SHA256) ); test_hash!( blake2b_512_collision_resistance, Bsi, BLAKE2B_512, Err(SHA256) ); test_hash!( blake2s_256_collision_resistance, Bsi, BLAKE2S_256, Err(SHA256) ); test_hash!(md4_collision_resistance, Bsi, MD4, Err(SHA256)); test_hash!(md5_collision_resistance, Bsi, MD5, Err(SHA256)); test_hash!(ripemd160_collision_resistance, Bsi, RIPEMD160, Err(SHA256)); test_hash!(sha1_collision_resistance, Bsi, SHA1, Err(SHA256)); test_hash!(sha224_collision_resistance, Bsi, SHA224, Err(SHA256)); test_hash!(sha256_collision_resistance, Bsi, SHA256, Ok(SHA256)); test_hash!(sha384_collision_resistance, Bsi, SHA384, Ok(SHA384)); test_hash!(sha3_224_collision_resistance, Bsi, SHA3_224, Err(SHA256)); test_hash!(sha3_256_collision_resistance, Bsi, SHA3_256, Ok(SHA256)); test_hash!(sha3_384_collision_resistance, Bsi, SHA3_384, Ok(SHA384)); test_hash!(sha3_512_collision_resistance, Bsi, SHA3_512, Ok(SHA512)); test_hash!(sha512_collision_resistance, Bsi, SHA512, Ok(SHA512)); test_hash!( sha512_224_collision_resistance, Bsi, SHA512_224, Err(SHA256) ); test_hash!(sha512_256_collision_resistance, Bsi, SHA512_256, Ok(SHA256)); test_hash!(shake128_collision_resistance, Bsi, SHAKE128, Err(SHA256)); test_hash!(shake256_collision_resistance, Bsi, SHAKE256, Err(SHA256)); test_hash_based!( blake2b_256_pre_image_resistance, Bsi, BLAKE2B_256, Err(SHA256) ); test_hash_based!( blake2b_384_pre_image_resistance, Bsi, BLAKE2B_384, Err(SHA256) ); test_hash_based!( blake2b_512_pre_image_resistance, Bsi, BLAKE2B_512, Err(SHA256) ); test_hash_based!( blake2s_256_pre_image_resistance, Bsi, BLAKE2S_256, Err(SHA256) ); test_hash_based!(md4_pre_image_resistance, Bsi, MD4, Err(SHA256)); test_hash_based!(md5_pre_image_resistance, Bsi, MD5, Err(SHA256)); test_hash_based!(ripemd160_pre_image_resistance, Bsi, RIPEMD160, Err(SHA256)); test_hash_based!(sha1_pre_image_resistance, Bsi, SHA1, Err(SHA256)); test_hash_based!(sha224_pre_image_resistance, Bsi, SHA224, Err(SHA256)); test_hash_based!(sha256_pre_image_resistance, Bsi, SHA256, Ok(SHA256)); test_hash_based!(sha384_pre_image_resistance, Bsi, SHA384, Ok(SHA384)); test_hash_based!(sha3_224_pre_image_resistance, Bsi, SHA3_224, Err(SHA256)); test_hash_based!(sha3_256_pre_image_resistance, Bsi, SHA3_256, Ok(SHA256)); test_hash_based!(sha3_384_pre_image_resistance, Bsi, SHA3_384, Ok(SHA384)); test_hash_based!(sha3_512_pre_image_resistance, Bsi, SHA3_512, Ok(SHA512)); test_hash_based!(sha512_pre_image_resistance, Bsi, SHA512, Ok(SHA512)); test_hash_based!( sha512_224_pre_image_resistance, Bsi, SHA512_224, Err(SHA256) ); test_hash_based!(sha512_256_pre_image_resistance, Bsi, SHA512_256, Ok(SHA256)); test_hash_based!(shake128_pre_image_resistance, Bsi, SHAKE128, Err(SHA256)); test_hash_based!(shake256_pre_image_resistance, Bsi, SHAKE256, Err(SHA256)); test_symmetric!(two_key_tdea, Bsi, TDEA2, Err(AES128)); test_symmetric!(three_key_tdea, Bsi, TDEA3, Err(AES128)); test_symmetric!(aes128, Bsi, AES128, Ok(AES128)); test_symmetric!(aes192, Bsi, AES192, Ok(AES192)); test_symmetric!(aes256, Bsi, AES256, Ok(AES256)); } 07070100000090000081A40000000000000000000000016537CEF400002788000000000000000000000000000000000000003300000000wardstone-0.2.0~0/crates/core/src/standard/cnsa.rs//! Validate cryptographic primitives against the Commercial National //! Security Algorithm Suites, [CNSA 1.0] and [CNSA 2.0]. //! //! [CNSA 1.0]: https://media.defense.gov/2021/Sep/27/2002862527/-1/-1/0/CNSS%20WORKSHEET.PDF //! [CNSA 2.0]: https://media.defense.gov/2022/Sep/07/2003071834/-1/-1/0/CSA_CNSA_2.0_ALGORITHMS_.PDF use std::collections::HashSet; use once_cell::sync::Lazy; use super::Standard; use crate::context::Context; use crate::primitive::ecc::*; use crate::primitive::ffc::*; use crate::primitive::hash::*; use crate::primitive::ifc::*; use crate::primitive::symmetric::*; use crate::primitive::Primitive; // Exclusive use of CNSA 2.0 by then. const CUTOFF_YEAR: u16 = 2030; static SPECIFIED_HASH_FUNCTIONS: Lazy<HashSet<Hash>> = Lazy::new(|| { let mut s = HashSet::new(); s.insert(SHA384); s.insert(SHA512); s }); /// [`Standard`] implementation of the Commercial National Security /// Algorithm Suites, [CNSA 1.0] and [CNSA 2.0]. /// /// [CNSA 1.0]: https://media.defense.gov/2021/Sep/27/2002862527/-1/-1/0/CNSS%20WORKSHEET.PDF /// [CNSA 2.0]: https://media.defense.gov/2022/Sep/07/2003071834/-1/-1/0/CSA_CNSA_2.0_ALGORITHMS_.PDF pub struct Cnsa; impl Standard for Cnsa { /// Validate an elliptic curve cryptography primitive used for digital /// signatures and key establishment. /// /// If the key is not compliant then `Err` will contain the /// recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher /// security level, `Ok` will also hold the recommended primitive /// with the desired security level. /// /// # Example /// /// The following illustrates a call to validate a non-compliant key. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::ecc::{P256, P384}; /// use wardstone_core::standard::cnsa::Cnsa; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// assert_eq!(Cnsa::validate_ecc(ctx, P256), Err(P384)); /// ``` fn validate_ecc(ctx: Context, key: Ecc) -> Result<Ecc, Ecc> { if ctx.year() > CUTOFF_YEAR { return Err(ECC_NOT_ALLOWED); } if key == P384 { Ok(P384) } else { Err(P384) } } /// Validates a finite field cryptography primitive. /// /// Examples include the DSA and key establishment algorithms such as /// Diffie-Hellman and MQV which can also be implemented as such. /// /// This primitive is not supported by either version of the CNSA /// guidance. /// /// If the key is not compliant then `Err` will contain the /// recommended key sizes L and N that one should use instead. /// /// If the key is compliant but the context specifies a higher /// security level, `Ok` will also hold the recommended key sizes L /// and N with the desired security level. /// /// # Example /// /// The following illustrates a call to validate a non-compliant key. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::ffc::{DSA_7680_384, FFC_NOT_SUPPORTED}; /// use wardstone_core::standard::cnsa::Cnsa; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// let dsa_7680 = DSA_7680_384; /// assert_eq!(Cnsa::validate_ffc(ctx, dsa_7680), Err(FFC_NOT_SUPPORTED)); /// ``` fn validate_ffc(_ctx: Context, _key: Ffc) -> Result<Ffc, Ffc> { Err(FFC_NOT_SUPPORTED) } /// Validates a hash function. /// /// Unlike other functions in this module, there is no distinction in /// security based on the application. As such this module does not /// have a corresponding `validate_hash_based` function. All hash /// function and hash based application are assessed by this single /// function. /// /// If the hash function is not compliant then `Err` will contain the /// recommended primitive that one should use instead. /// /// If the hash function is compliant but the context specifies a /// higher security level, `Ok` will also hold the recommended /// primitive with the desired security level. /// /// # Example /// /// The following illustrates a call to validate a non-compliant hash /// function. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::hash::{SHA1, SHA384}; /// use wardstone_core::standard::cnsa::Cnsa; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// assert_eq!(Cnsa::validate_hash(ctx, SHA1), Err(SHA384)); /// ``` fn validate_hash(ctx: Context, hash: Hash) -> Result<Hash, Hash> { if SPECIFIED_HASH_FUNCTIONS.contains(&hash) { let security = ctx.security().max(hash.security()); match security { ..=191 => Err(SHA384), 192..=255 => Ok(SHA384), 256.. => Ok(SHA512), } } else { Err(SHA384) } } /// Validates an integer factorisation cryptography primitive the /// most common of which is the RSA signature algorithm. /// /// If the key is not compliant then `Err` will contain the /// recommended key size that one should use instead. /// /// If the key is compliant but the context specifies a higher /// security level, `Ok` will also hold the recommended key size /// with the desired security level. /// /// **Note:** Unlike other functions in this module, this will return /// a generic structure that specifies minimum private and public /// key sizes. /// /// # Example /// /// The following illustrates a call to validate a non-compliant key. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::ifc::{RSA_PSS_2048, RSA_PSS_3072}; /// use wardstone_core::standard::cnsa::Cnsa; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// assert_eq!(Cnsa::validate_ifc(ctx, RSA_PSS_2048), Err(RSA_PSS_3072)); /// ``` fn validate_ifc(ctx: Context, key: Ifc) -> Result<Ifc, Ifc> { if ctx.year() > CUTOFF_YEAR { return Err(IFC_NOT_ALLOWED); } let security = ctx.security().max(key.security()); match security { ..=127 => Err(RSA_PSS_3072), 128..=191 => Ok(RSA_PSS_3072), 192..=255 => Ok(RSA_PSS_7680), 256.. => Ok(RSA_PSS_15360), } } /// Validates a symmetric key primitive. /// /// If the key is not compliant then `Err` will contain the /// recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher /// security level, `Ok` will also hold the recommended primitive /// with the desired security level. /// /// # Example /// /// The following illustrates a call to validate a non-compliant key. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::symmetric::{AES256, TDEA3}; /// use wardstone_core::standard::cnsa::Cnsa; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// assert_eq!(Cnsa::validate_symmetric(ctx, TDEA3), Err(AES256)); /// ``` fn validate_symmetric(_ctx: Context, key: Symmetric) -> Result<Symmetric, Symmetric> { if key != AES256 { Err(AES256) } else { Ok(AES256) } } } #[cfg(test)] mod tests { use super::*; use crate::{test_ecc, test_ffc, test_hash, test_ifc, test_symmetric}; test_ecc!(p224, Cnsa, P224, Err(P384)); test_ecc!(p256, Cnsa, P256, Err(P384)); test_ecc!(p384, Cnsa, P384, Ok(P384)); test_ecc!(p521, Cnsa, P521, Err(P384)); test_ecc!(ed25519, Cnsa, ED25519, Err(P384)); test_ecc!(ed448, Cnsa, ED448, Err(P384)); test_ecc!(x25519, Cnsa, X25519, Err(P384)); test_ecc!(x448, Cnsa, X448, Err(P384)); test_ecc!(brainpoolp224r1, Cnsa, BRAINPOOLP224R1, Err(P384)); test_ecc!(brainpoolp256r1, Cnsa, BRAINPOOLP256R1, Err(P384)); test_ecc!(brainpoolp320r1, Cnsa, BRAINPOOLP320R1, Err(P384)); test_ecc!(brainpoolp384r1, Cnsa, BRAINPOOLP384R1, Err(P384)); test_ecc!(brainpoolp512r1, Cnsa, BRAINPOOLP512R1, Err(P384)); test_ecc!(secp256k1, Cnsa, SECP256K1, Err(P384)); test_hash!(blake2b_256, Cnsa, BLAKE2B_256, Err(SHA384)); test_hash!(blake2b_384, Cnsa, BLAKE2B_384, Err(SHA384)); test_hash!(blake2b_512, Cnsa, BLAKE2B_512, Err(SHA384)); test_hash!(blake2s_256, Cnsa, BLAKE2S_256, Err(SHA384)); test_hash!(md4, Cnsa, MD4, Err(SHA384)); test_hash!(md5, Cnsa, MD5, Err(SHA384)); test_hash!(ripemd160, Cnsa, RIPEMD160, Err(SHA384)); test_hash!(sha1, Cnsa, SHA1, Err(SHA384)); test_hash!(sha224, Cnsa, SHA224, Err(SHA384)); test_hash!(sha256, Cnsa, SHA256, Err(SHA384)); test_hash!(sha384, Cnsa, SHA384, Ok(SHA384)); test_hash!(sha3_224, Cnsa, SHA3_224, Err(SHA384)); test_hash!(sha3_256, Cnsa, SHA3_256, Err(SHA384)); test_hash!(sha3_384, Cnsa, SHA3_384, Err(SHA384)); test_hash!(sha3_512, Cnsa, SHA3_512, Err(SHA384)); test_hash!(sha512, Cnsa, SHA512, Ok(SHA512)); test_hash!(sha512_224, Cnsa, SHA512_224, Err(SHA384)); test_hash!(sha512_256, Cnsa, SHA512_256, Err(SHA384)); test_hash!(shake128, Cnsa, SHAKE128, Err(SHA384)); test_hash!(shake256, Cnsa, SHAKE256, Err(SHA384)); test_ffc!(ffc_1024_160, Cnsa, DSA_1024_160, Err(FFC_NOT_SUPPORTED)); test_ffc!(ffc_2048_224, Cnsa, DSA_2048_224, Err(FFC_NOT_SUPPORTED)); test_ffc!(ffc_3072_256, Cnsa, DSA_3072_256, Err(FFC_NOT_SUPPORTED)); test_ffc!(ffc_7680_384, Cnsa, DSA_7680_384, Err(FFC_NOT_SUPPORTED)); test_ffc!(ffc_15360_512, Cnsa, DSA_15360_512, Err(FFC_NOT_SUPPORTED)); test_ifc!(ifc_1024, Cnsa, RSA_PSS_1024, Err(RSA_PSS_3072)); test_ifc!(ifc_2048, Cnsa, RSA_PSS_2048, Err(RSA_PSS_3072)); test_ifc!(ifc_3072, Cnsa, RSA_PSS_3072, Ok(RSA_PSS_3072)); test_ifc!(ifc_7680, Cnsa, RSA_PSS_7680, Ok(RSA_PSS_7680)); test_ifc!(ifc_15360, Cnsa, RSA_PSS_15360, Ok(RSA_PSS_15360)); test_symmetric!(two_key_tdea, Cnsa, TDEA2, Err(AES256)); test_symmetric!(three_key_tdea, Cnsa, TDEA3, Err(AES256)); test_symmetric!(aes128, Cnsa, AES128, Err(AES256)); test_symmetric!(aes192, Cnsa, AES192, Err(AES256)); test_symmetric!(aes256, Cnsa, AES256, Ok(AES256)); } 07070100000091000081A40000000000000000000000016537CEF400003407000000000000000000000000000000000000003500000000wardstone-0.2.0~0/crates/core/src/standard/ecrypt.rs//! Validate cryptographic primitives against the [ECRYPT-CSA D5.4 //! Algorithms, Key Size and Protocols Report]. //! //! [ECRYPT-CSA D5.4 Algorithms, Key Size and Protocols Report]: https://www.ecrypt.eu.org/csa/documents/D5.4-FinalAlgKeySizeProt.pdf use std::collections::HashSet; use once_cell::sync::Lazy; use super::Standard; use crate::context::Context; use crate::primitive::ecc::*; use crate::primitive::ffc::*; use crate::primitive::hash::*; use crate::primitive::ifc::*; use crate::primitive::symmetric::*; use crate::primitive::Primitive; // "Thus the key take home message is that decision makers now make // plans and preparations for the phasing out of what we term legacy // mechanisms over a period of say 5-10 years." (2018, p. 12). See p. 11 // about the criteria made to distinguish between the different // categories of legacy algorithms. const CUTOFF_YEAR: u16 = 2023; static SPECIFIED_HASH_FUNCTIONS: Lazy<HashSet<Hash>> = Lazy::new(|| { let mut s = HashSet::new(); s.insert(BLAKE2B_256); s.insert(BLAKE2B_384); s.insert(BLAKE2B_512); s.insert(BLAKE2S_256); s.insert(BLAKE_224); s.insert(BLAKE_256); s.insert(BLAKE_384); s.insert(BLAKE_512); s.insert(RIPEMD160); s.insert(SHA224); s.insert(SHA256); s.insert(SHA384); s.insert(SHA3_224); s.insert(SHA3_256); s.insert(SHA3_384); s.insert(SHA3_512); s.insert(SHA512); s.insert(SHA512_224); s.insert(SHA512_256); s.insert(SHAKE128); s.insert(SHAKE256); s.insert(WHIRLPOOL); s }); static SPECIFIED_SYMMETRIC_KEYS: Lazy<HashSet<Symmetric>> = Lazy::new(|| { let mut s = HashSet::new(); s.insert(AES128); s.insert(AES192); s.insert(AES256); s.insert(CAMELLIA128); s.insert(CAMELLIA192); s.insert(CAMELLIA256); s.insert(SERPENT128); s.insert(SERPENT192); s.insert(SERPENT256); s.insert(TDEA2); s.insert(TDEA3); s }); /// [`Standard`] implementation for the /// [ECRYPT-CSA D5.4 Algorithms, Key Size and Protocols Report]. /// /// [ECRYPT-CSA D5.4 Algorithms, Key Size and Protocols Report]: https://www.ecrypt.eu.org/csa/documents/D5.4-FinalAlgKeySizeProt.pdf pub struct Ecrypt; impl Standard for Ecrypt { /// Validate an elliptic curve cryptography primitive used for digital /// signatures and key establishment where f is the key size according /// to page 47 of the report. /// /// If the key is not compliant then `Err` will contain the /// recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher /// security level, `Ok` will also hold the recommended primitive /// with the desired security level. /// /// **Note:** This will return a generic structure that specifies key /// sizes. /// /// # Example /// /// The following illustrates a call to validate a compliant key. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::ecc::{ECC_256, P224}; /// use wardstone_core::standard::ecrypt::Ecrypt; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// assert_eq!(Ecrypt::validate_ecc(ctx, P224), Ok(ECC_256)); /// ``` fn validate_ecc(ctx: Context, key: Ecc) -> Result<Ecc, Ecc> { let security = ctx.security().max(key.security()); match security { ..=79 => Err(ECC_256), 80..=127 => { if ctx.year() > CUTOFF_YEAR { Err(ECC_256) } else { Ok(ECC_256) } }, 128 => Ok(ECC_256), 129..=192 => Ok(ECC_384), 193.. => Ok(ECC_512), } } /// Validates a finite field cryptography primitive according to page /// 47 of the report. /// /// Examples include the DSA and key establishment algorithms such as /// Diffie-Hellman and MQV which can also be implemented as such, /// according to page 47 of the report. /// /// If the key is not compliant then `Err` will contain the /// recommended key sizes L and N that one should use instead. /// /// If the key is compliant but the context specifies a higher /// security level, `Ok` will also hold the recommended key sizes L /// and N with the desired security level. /// /// # Example /// /// The following illustrates a call to validate a compliant key. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::ffc::{DSA_2048_224, DSA_3072_256}; /// use wardstone_core::standard::ecrypt::Ecrypt; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// let dsa_2048 = DSA_2048_224; /// let dsa_3072 = DSA_3072_256; /// assert_eq!(Ecrypt::validate_ffc(ctx, dsa_2048), Ok(dsa_3072)); /// ``` fn validate_ffc(ctx: Context, key: Ffc) -> Result<Ffc, Ffc> { let security = ctx.security().max(key.security()); match security { ..=79 => Err(DSA_3072_256), 80..=127 => { if ctx.year() > CUTOFF_YEAR { Err(DSA_3072_256) } else { Ok(DSA_3072_256) } }, 128 => Ok(DSA_3072_256), 129..=192 => Ok(DSA_7680_384), 193.. => Ok(DSA_15360_512), } } /// Validates a hash function according to pages 40-43 of the report. /// /// If the hash function is not compliant then `Err` will contain the /// recommended primitive that one should use instead. /// /// If the hash function is compliant but the context specifies a /// higher security level, `Ok` will also hold the recommended /// primitive with the desired security level. /// /// **Note:** An alternative might be suggested for a compliant hash /// function with a similar security level in which a switch to the /// recommended primitive would likely be unwarranted. For example, /// when evaluating compliance for the `SHA3-256`, a recommendation /// to use `SHA256` will be made but switching to this as a result /// is likely unnecessary. /// /// # Example /// /// The following illustrates a call to validate a non-compliant hash /// function. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::hash::{SHA1, SHA256}; /// use wardstone_core::standard::ecrypt::Ecrypt; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// assert_eq!(Ecrypt::validate_hash(ctx, SHA1), Err(SHA256)); /// ``` fn validate_hash(ctx: Context, hash: Hash) -> Result<Hash, Hash> { if SPECIFIED_HASH_FUNCTIONS.contains(&hash) { let security = ctx.security().max(hash.security()); match security { ..=79 => Err(SHA256), 80..=127 => { if ctx.year() > CUTOFF_YEAR { Err(SHA256) } else { Ok(SHA256) } }, 128 => Ok(SHA256), 129..=192 => Ok(SHA384), 193.. => Ok(SHA512), } } else { Err(SHA256) } } /// Validates an integer factorisation cryptography primitive the /// most common of which is the RSA signature algorithm according to /// pages 47-48. /// /// If the key is not compliant then `Err` will contain the /// recommended key size that one should use instead. /// /// If the key is compliant but the context specifies a higher /// security level, `Ok` will also hold the recommended key size /// with the desired security level. /// /// **Note:** Unlike other functions in this module, this will return /// a generic structure that specifies minimum private and public /// key sizes. /// /// # Example /// /// The following illustrates a call to validate a compliant key. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::ifc::RSA_PSS_3072; /// use wardstone_core::standard::ecrypt::Ecrypt; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// assert_eq!(Ecrypt::validate_ifc(ctx, RSA_PSS_3072), Ok(RSA_PSS_3072)); /// ``` fn validate_ifc(ctx: Context, key: Ifc) -> Result<Ifc, Ifc> { let security = ctx.security().max(key.security()); match security { ..=79 => Err(RSA_PSS_3072), 80..=127 => { if ctx.year() > CUTOFF_YEAR { Err(RSA_PSS_3072) } else { Ok(RSA_PSS_3072) } }, 128..=191 => Ok(RSA_PSS_3072), 192..=255 => Ok(RSA_PSS_7680), 256.. => Ok(RSA_PSS_15360), } } /// Validates a symmetric key primitive according to pages 37 to 40 of /// the report. /// /// If the key is not compliant then `Err` will contain the /// recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher /// security level, `Ok` will also hold the recommended primitive /// with the desired security level. /// /// # Example /// /// The following illustrates a call to validate a compliant key. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::symmetric::{AES128, TDEA3}; /// use wardstone_core::standard::ecrypt::Ecrypt; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// assert_eq!(Ecrypt::validate_symmetric(ctx, TDEA3), Ok(AES128)); /// ``` fn validate_symmetric(ctx: Context, key: Symmetric) -> Result<Symmetric, Symmetric> { if SPECIFIED_SYMMETRIC_KEYS.contains(&key) { let security = ctx.security().max(key.security()); match security { ..=79 => Err(AES128), 80..=127 => { if ctx.year() > CUTOFF_YEAR { Err(AES128) } else { Ok(AES128) } }, 128 => Ok(AES128), 129..=192 => Ok(AES192), 193.. => Ok(AES256), } } else { Err(AES128) } } } #[cfg(test)] mod tests { use super::*; use crate::{test_ecc, test_ffc, test_hash, test_ifc, test_symmetric}; test_ecc!(p224, Ecrypt, P224, Ok(ECC_256)); test_ecc!(p256, Ecrypt, P256, Ok(ECC_256)); test_ecc!(p384, Ecrypt, P384, Ok(ECC_384)); test_ecc!(p521, Ecrypt, P521, Ok(ECC_512)); test_ecc!(ed25519, Ecrypt, ED25519, Ok(ECC_256)); test_ecc!(ed448, Ecrypt, ED448, Ok(ECC_512)); test_ecc!(x25519, Ecrypt, X25519, Ok(ECC_256)); test_ecc!(x448, Ecrypt, X448, Ok(ECC_512)); test_ecc!(brainpoolp224r1, Ecrypt, BRAINPOOLP224R1, Ok(ECC_256)); test_ecc!(brainpoolp256r1, Ecrypt, BRAINPOOLP256R1, Ok(ECC_256)); test_ecc!(brainpoolp320r1, Ecrypt, BRAINPOOLP320R1, Ok(ECC_384)); test_ecc!(brainpoolp384r1, Ecrypt, BRAINPOOLP384R1, Ok(ECC_384)); test_ecc!(brainpoolp512r1, Ecrypt, BRAINPOOLP512R1, Ok(ECC_512)); test_ecc!(secp256k1, Ecrypt, SECP256K1, Ok(ECC_256)); test_ffc!(ffc_1024_160, Ecrypt, DSA_1024_160, Ok(DSA_3072_256)); test_ffc!(ffc_2048_224, Ecrypt, DSA_2048_224, Ok(DSA_3072_256)); test_ffc!(ffc_3072_256, Ecrypt, DSA_3072_256, Ok(DSA_3072_256)); test_ffc!(ffc_7680_384, Ecrypt, DSA_7680_384, Ok(DSA_7680_384)); test_ffc!(ffc_15360_512, Ecrypt, DSA_15360_512, Ok(DSA_15360_512)); test_hash!(blake_224, Ecrypt, BLAKE_224, Ok(SHA256)); test_hash!(blake_256, Ecrypt, BLAKE_256, Ok(SHA256)); test_hash!(blake_384, Ecrypt, BLAKE_384, Ok(SHA384)); test_hash!(blake_512, Ecrypt, BLAKE_512, Ok(SHA512)); test_hash!(blake2b_256, Ecrypt, BLAKE2B_256, Ok(SHA256)); test_hash!(blake2b_384, Ecrypt, BLAKE2B_384, Ok(SHA384)); test_hash!(blake2b_512, Ecrypt, BLAKE2B_512, Ok(SHA512)); test_hash!(blake2s_256, Ecrypt, BLAKE2S_256, Ok(SHA256)); test_hash!(md4, Ecrypt, MD4, Err(SHA256)); test_hash!(md5, Ecrypt, MD5, Err(SHA256)); test_hash!(ripemd160, Ecrypt, RIPEMD160, Ok(SHA256)); test_hash!(sha1, Ecrypt, SHA1, Err(SHA256)); test_hash!(sha224, Ecrypt, SHA224, Ok(SHA256)); test_hash!(sha256, Ecrypt, SHA256, Ok(SHA256)); test_hash!(sha384, Ecrypt, SHA384, Ok(SHA384)); test_hash!(sha3_224, Ecrypt, SHA3_224, Ok(SHA256)); test_hash!(sha3_256, Ecrypt, SHA3_256, Ok(SHA256)); test_hash!(sha3_384, Ecrypt, SHA3_384, Ok(SHA384)); test_hash!(sha3_512, Ecrypt, SHA3_512, Ok(SHA512)); test_hash!(sha512, Ecrypt, SHA512, Ok(SHA512)); test_hash!(sha512_224, Ecrypt, SHA512_224, Ok(SHA256)); test_hash!(sha512_256, Ecrypt, SHA512_256, Ok(SHA256)); test_hash!(shake128, Ecrypt, SHAKE128, Err(SHA256)); test_hash!(shake256, Ecrypt, SHAKE256, Ok(SHA256)); test_hash!(whirlpool, Ecrypt, WHIRLPOOL, Ok(SHA512)); test_ifc!(ifc_1024, Ecrypt, RSA_PSS_1024, Ok(RSA_PSS_3072)); test_ifc!(ifc_2048, Ecrypt, RSA_PSS_2048, Ok(RSA_PSS_3072)); test_ifc!(ifc_3072, Ecrypt, RSA_PSS_3072, Ok(RSA_PSS_3072)); test_ifc!(ifc_7680, Ecrypt, RSA_PSS_7680, Ok(RSA_PSS_7680)); test_ifc!(ifc_15360, Ecrypt, RSA_PSS_15360, Ok(RSA_PSS_15360)); test_symmetric!(aes128, Ecrypt, AES128, Ok(AES128)); test_symmetric!(aes192, Ecrypt, AES192, Ok(AES192)); test_symmetric!(aes256, Ecrypt, AES256, Ok(AES256)); test_symmetric!(camellia128, Ecrypt, CAMELLIA128, Ok(AES128)); test_symmetric!(camellia192, Ecrypt, CAMELLIA192, Ok(AES192)); test_symmetric!(camellia256, Ecrypt, CAMELLIA256, Ok(AES256)); test_symmetric!(serpent128, Ecrypt, SERPENT128, Ok(AES128)); test_symmetric!(serpent192, Ecrypt, SERPENT192, Ok(AES192)); test_symmetric!(serpent256, Ecrypt, SERPENT256, Ok(AES256)); test_symmetric!(three_key_tdea, Ecrypt, TDEA3, Ok(AES128)); test_symmetric!(two_key_tdea, Ecrypt, TDEA2, Ok(AES128)); } 07070100000092000081A40000000000000000000000016537CEF400003A81000000000000000000000000000000000000003600000000wardstone-0.2.0~0/crates/core/src/standard/lenstra.rs//! Validate cryptographic primitives against the levels of security //! mentioned in the paper Key Lengths, Arjen K. Lenstra, The Handbook //! of Information Security, 06/2004. use std::collections::HashSet; use once_cell::sync::Lazy; use crate::context::Context; use crate::primitive::ecc::*; use crate::primitive::ffc::*; use crate::primitive::hash::*; use crate::primitive::ifc::*; use crate::primitive::symmetric::*; use crate::primitive::Primitive; use crate::standard::Standard; #[derive(PartialEq, Eq, Debug)] pub enum ValidationError { SecurityLevelTooLow, } const BASE_YEAR: u16 = 1982; const BASE_SECURITY: u16 = 56; static SPECIFIED_HASH_FUNCTIONS: Lazy<HashSet<Hash>> = Lazy::new(|| { let mut s = HashSet::new(); s.insert(RIPEMD160); s.insert(SHA1); s.insert(SHA256); s.insert(SHA384); s.insert(SHA512); s }); static SPECIFIED_SYMMETRIC_KEYS: Lazy<HashSet<Symmetric>> = Lazy::new(|| { let mut s = HashSet::new(); s.insert(AES128); s.insert(AES192); s.insert(AES256); s.insert(DES); s.insert(DESX); s.insert(IDEA); s.insert(TDEA2); s.insert(TDEA3); s }); /// [`Standard`] implementation of the paper Key Lengths, /// Arjen K. Lenstra, The Handbook of Information Security, 06/2004. pub struct Lenstra; impl Lenstra { /// Calculates the security according to the formula on page 7. If the /// year is less than the BASE_YEAR, a ValidationError is returned. fn calculate_security(year: u16) -> Result<u16, ValidationError> { if year < BASE_YEAR { Err(ValidationError::SecurityLevelTooLow) } else { let mut lambda = (year - BASE_YEAR) << 1; lambda /= 3; lambda += BASE_SECURITY; Ok(lambda) } } } impl Standard for Lenstra { /// Validate an elliptic curve cryptography primitive used for digital /// signatures and key establishment where f is the key size. /// /// If the key is not compliant then `Err` will contain the /// recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher /// security level, `Ok` will also hold the recommended primitive /// with the desired security level. /// /// # Example /// /// The following illustrates a call to validate a compliant key. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::ecc::{BRAINPOOLP256R1, ECC_256}; /// use wardstone_core::standard::lenstra::Lenstra; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// assert_eq!(Lenstra::validate_ecc(ctx, BRAINPOOLP256R1), Ok(ECC_256)); /// ``` fn validate_ecc(ctx: Context, key: Ecc) -> Result<Ecc, Ecc> { let implied_security = ctx.security().max(key.security()); let min_security = match Lenstra::calculate_security(ctx.year()) { Ok(security) => security, Err(_) => return Err(ECC_NOT_ALLOWED), }; let recommendation = match implied_security.max(min_security) { ..=111 => ECC_NOT_ALLOWED, 112 => ECC_224, 113..=128 => ECC_256, 129..=192 => ECC_384, 193.. => ECC_512, }; if implied_security < min_security { Err(recommendation) } else { Ok(recommendation) } } /// Validates a finite field cryptography primitive. /// /// Examples include the DSA and key establishment algorithms such as /// Diffie-Hellman and MQV which can also be implemented as such. /// /// If the key is not compliant then `Err` will contain the /// recommended key sizes L and N that one should use instead. /// /// If the key is compliant but the context specifies a higher /// security level, `Ok` will also hold the recommended key sizes L /// and N with the desired security level. /// /// # Example /// /// The following illustrates a call to validate a compliant key. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::ffc::DSA_3072_256; /// use wardstone_core::standard::lenstra::Lenstra; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// let dsa_3072 = DSA_3072_256; /// assert_eq!(Lenstra::validate_ffc(ctx, dsa_3072), Ok(dsa_3072)); /// ``` fn validate_ffc(ctx: Context, key: Ffc) -> Result<Ffc, Ffc> { let implied_security = ctx.security().max(key.security()); let min_security = match Lenstra::calculate_security(ctx.year()) { Ok(security) => security, Err(_) => return Err(FFC_NOT_SUPPORTED), }; let recommendation = match implied_security.max(min_security) { ..=79 => FFC_NOT_SUPPORTED, 80 => DSA_1024_160, 81..=112 => DSA_2048_224, 113..=128 => DSA_3072_256, 129..=192 => DSA_7680_384, 193.. => DSA_15360_512, }; if implied_security < min_security { Err(recommendation) } else { Ok(recommendation) } } /// Validates a hash function according to pages 12-14 of the paper. /// /// Unlike other functions in this module, there is no distinction in /// security based on the application. As such this module does not /// have a corresponding `validate_hash_based` function. All hash /// function and hash based application are assessed by this single /// function. /// /// If the hash function is not compliant then `Err` will contain the /// recommended primitive that one should use instead. /// /// If the hash function is compliant but the context specifies a /// higher security level, `Ok` will also hold the recommended /// primitive with the desired security level. /// /// **Note:** An alternative might be suggested for a compliant hash /// function with a similar security level in which a switch to the /// recommended primitive would likely be unwarranted. For example, /// when evaluating compliance for the `SHA3-256`, a recommendation /// to use `SHA256` will be made but switching to this as a result /// is likely unnecessary. /// /// # Example /// /// The following illustrates a call to validate a non-compliant hash /// function. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::hash::{SHA1, SHA256}; /// use wardstone_core::standard::lenstra::Lenstra; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// assert_eq!(Lenstra::validate_hash(ctx, SHA1), Err(SHA256)); /// ``` fn validate_hash(ctx: Context, hash: Hash) -> Result<Hash, Hash> { if SPECIFIED_HASH_FUNCTIONS.contains(&hash) { let implied_security = ctx.security().max(hash.security()); let min_security = match Lenstra::calculate_security(ctx.year()) { Ok(security) => security, Err(_) => return Err(SHA256), }; let recommendation = match implied_security.max(min_security) { // SHA1 and RIPEMD-160 offer less security than their digest // length so they are omitted even though they might cover the // range ..=80. ..=128 => SHA256, 129..=192 => SHA384, 193.. => SHA512, }; if implied_security < min_security { Err(recommendation) } else { Ok(recommendation) } } else { Err(SHA256) } } /// Validates an integer factorisation cryptography primitive the /// most common of which is the RSA signature algorithm based on /// pages 17-25. /// /// If the key is not compliant then `Err` will contain the /// recommended key size that one should use instead. /// /// If the key is compliant but the context specifies a higher /// security level, `Ok` will also hold the recommended key size /// with the desired security level. /// /// **Note:** Unlike other functions in this module, this will return /// a generic structure that specifies minimum private and public /// key sizes. /// /// # Example /// /// The following illustrates a call to validate a compliant key. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::ifc::RSA_PSS_2048; /// use wardstone_core::standard::lenstra::Lenstra; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// assert_eq!(Lenstra::validate_ifc(ctx, RSA_PSS_2048), Ok(RSA_PSS_2048)); /// ``` fn validate_ifc(ctx: Context, key: Ifc) -> Result<Ifc, Ifc> { // Per Table 4 on page 25. let (implied_year, implied_security) = match key.k { ..=1023 => (u16::MIN, u16::MIN), 1024 => (2006, 72), 1025..=1280 => (2014, 78), 1281..=1536 => (2020, 82), 1537..=2048 => (2030, 88), 2049..=3072 => (2046, 99), 3073..=4096 => (2060, 108), 4097.. => (2100, 135), }; let year = implied_year.max(ctx.year()); let (security_range, recommendation) = match year { ..=2006 => (0..=72, RSA_PSS_1024), 2007..=2014 => (73..=78, RSA_PSS_1280), 2015..=2020 => (79..=82, RSA_PSS_1536), 2021..=2030 => (83..=88, RSA_PSS_2048), 2031..=2046 => (89..=99, RSA_PSS_3072), 2047..=2060 => (100..=108, RSA_PSS_4096), 2061.. => (109..=135, RSA_PSS_8192), }; let security = ctx.security().max(implied_security); if !security_range.contains(&security) { Err(recommendation) } else { Ok(recommendation) } } /// Validates a symmetric key primitive according to pages 9-12 of the /// paper. /// /// If the key is not compliant then `Err` will contain the /// recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher /// security level, `Ok` will also hold the recommended primitive /// with the desired security level. /// /// # Example /// /// The following illustrates a call to validate a compliant key. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::symmetric::TDEA3; /// use wardstone_core::standard::lenstra::Lenstra; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// assert_eq!(Lenstra::validate_symmetric(ctx, TDEA3), Ok(TDEA3)); /// ``` fn validate_symmetric(ctx: Context, key: Symmetric) -> Result<Symmetric, Symmetric> { if SPECIFIED_SYMMETRIC_KEYS.contains(&key) { let implied_security = ctx.security().max(key.security()); let min_security = match Lenstra::calculate_security(ctx.year()) { Ok(security) => security, Err(_) => return Err(AES128), }; let recommendation = match implied_security.max(min_security) { ..=95 => TDEA2, 96..=112 => TDEA3, 113..=120 => DESX, 121..=128 => AES128, 129..=192 => AES192, 193.. => AES256, }; if implied_security < min_security { Err(recommendation) } else { Ok(recommendation) } } else { Err(AES128) } } } #[cfg(test)] mod tests { use super::*; use crate::{test_ecc, test_ffc, test_hash, test_ifc, test_symmetric}; test_ecc!(p224, Lenstra, P224, Ok(ECC_224)); test_ecc!(p256, Lenstra, P256, Ok(ECC_256)); test_ecc!(p384, Lenstra, P384, Ok(ECC_384)); test_ecc!(p521, Lenstra, P521, Ok(ECC_512)); test_ecc!(ed25519, Lenstra, ED25519, Ok(ECC_256)); test_ecc!(ed448, Lenstra, ED448, Ok(ECC_512)); test_ecc!(x25519, Lenstra, X25519, Ok(ECC_256)); test_ecc!(x448, Lenstra, X448, Ok(ECC_512)); test_ecc!(brainpoolp224r1, Lenstra, BRAINPOOLP224R1, Ok(ECC_224)); test_ecc!(brainpoolp256r1, Lenstra, BRAINPOOLP256R1, Ok(ECC_256)); test_ecc!(brainpoolp320r1, Lenstra, BRAINPOOLP320R1, Ok(ECC_384)); test_ecc!(brainpoolp384r1, Lenstra, BRAINPOOLP384R1, Ok(ECC_384)); test_ecc!(brainpoolp512r1, Lenstra, BRAINPOOLP512R1, Ok(ECC_512)); test_ecc!(secp256k1, Lenstra, SECP256K1, Ok(ECC_256)); test_ffc!(ffc_1024_160, Lenstra, DSA_1024_160, Err(DSA_2048_224)); test_ffc!(ffc_2048_224, Lenstra, DSA_2048_224, Ok(DSA_2048_224)); test_ffc!(ffc_3072_256, Lenstra, DSA_3072_256, Ok(DSA_3072_256)); test_ffc!(ffc_7680_384, Lenstra, DSA_7680_384, Ok(DSA_7680_384)); test_ffc!(ffc_15360_512, Lenstra, DSA_15360_512, Ok(DSA_15360_512)); test_ifc!(ifc_1024, Lenstra, RSA_PSS_1024, Err(RSA_PSS_2048)); test_ifc!(ifc_1280, Lenstra, RSA_PSS_1280, Err(RSA_PSS_2048)); test_ifc!(ifc_1536, Lenstra, RSA_PSS_1536, Err(RSA_PSS_2048)); test_ifc!(ifc_2048, Lenstra, RSA_PSS_2048, Ok(RSA_PSS_2048)); test_ifc!(ifc_3072, Lenstra, RSA_PSS_3072, Ok(RSA_PSS_3072)); test_ifc!(ifc_4096, Lenstra, RSA_PSS_4096, Ok(RSA_PSS_4096)); test_ifc!(ifc_7680, Lenstra, RSA_PSS_7680, Ok(RSA_PSS_8192)); test_ifc!(ifc_8192, Lenstra, RSA_PSS_8192, Ok(RSA_PSS_8192)); test_ifc!(ifc_15360, Lenstra, RSA_PSS_15360, Ok(RSA_PSS_8192)); test_hash!(blake_224, Lenstra, BLAKE_224, Err(SHA256)); test_hash!(blake_256, Lenstra, BLAKE_256, Err(SHA256)); test_hash!(blake_384, Lenstra, BLAKE_384, Err(SHA256)); test_hash!(blake_512, Lenstra, BLAKE_512, Err(SHA256)); test_hash!(blake2b_256, Lenstra, BLAKE2B_256, Err(SHA256)); test_hash!(blake2b_384, Lenstra, BLAKE2B_384, Err(SHA256)); test_hash!(blake2b_512, Lenstra, BLAKE2B_512, Err(SHA256)); test_hash!(blake2s_256, Lenstra, BLAKE2S_256, Err(SHA256)); test_hash!(md4, Lenstra, MD4, Err(SHA256)); test_hash!(md5, Lenstra, MD5, Err(SHA256)); test_hash!(ripemd160, Lenstra, RIPEMD160, Err(SHA256)); test_hash!(sha1, Lenstra, SHA1, Err(SHA256)); test_hash!(sha224, Lenstra, SHA224, Err(SHA256)); test_hash!(sha256, Lenstra, SHA256, Ok(SHA256)); test_hash!(sha384, Lenstra, SHA384, Ok(SHA384)); test_hash!(sha3_224, Lenstra, SHA3_224, Err(SHA256)); test_hash!(sha3_256, Lenstra, SHA3_256, Err(SHA256)); test_hash!(sha3_384, Lenstra, SHA3_384, Err(SHA256)); test_hash!(sha3_512, Lenstra, SHA3_512, Err(SHA256)); test_hash!(sha512, Lenstra, SHA512, Ok(SHA512)); test_hash!(sha512_224, Lenstra, SHA512_224, Err(SHA256)); test_hash!(sha512_256, Lenstra, SHA512_256, Err(SHA256)); test_hash!(shake128, Lenstra, SHAKE128, Err(SHA256)); test_hash!(shake256, Lenstra, SHAKE256, Err(SHA256)); test_hash!(whirlpool, Lenstra, WHIRLPOOL, Err(SHA256)); test_symmetric!(aes128, Lenstra, AES128, Ok(AES128)); test_symmetric!(aes192, Lenstra, AES192, Ok(AES192)); test_symmetric!(aes256, Lenstra, AES256, Ok(AES256)); test_symmetric!(camellia128, Lenstra, CAMELLIA128, Err(AES128)); test_symmetric!(camellia192, Lenstra, CAMELLIA192, Err(AES128)); test_symmetric!(camellia256, Lenstra, CAMELLIA256, Err(AES128)); test_symmetric!(des, Lenstra, DES, Err(TDEA2)); test_symmetric!(desx, Lenstra, DESX, Ok(DESX)); test_symmetric!(idea, Lenstra, IDEA, Ok(AES128)); test_symmetric!(serpent128, Lenstra, SERPENT128, Err(AES128)); test_symmetric!(serpent192, Lenstra, SERPENT192, Err(AES128)); test_symmetric!(serpent256, Lenstra, SERPENT256, Err(AES128)); test_symmetric!(three_key_tdea, Lenstra, TDEA3, Ok(TDEA3)); test_symmetric!(two_key_tdea, Lenstra, TDEA2, Ok(TDEA2)); } 07070100000093000081A40000000000000000000000016537CEF40000480A000000000000000000000000000000000000003300000000wardstone-0.2.0~0/crates/core/src/standard/nist.rs//! Validate cryptographic primitives against the [NIST Special //! Publication 800-57 Part 1 Revision 5 standard]. //! //! [NIST Special Publication 800-57 Part 1 Revision 5 standard]: https://doi.org/10.6028/NIST.SP.800-57pt1r5 use std::collections::HashSet; use once_cell::sync::Lazy; use super::Standard; use crate::context::Context; use crate::primitive::ecc::*; use crate::primitive::ffc::*; use crate::primitive::hash::*; use crate::primitive::ifc::*; use crate::primitive::symmetric::*; use crate::primitive::Primitive; const CUTOFF_YEAR: u16 = 2031; // See p. 59. const CUTOFF_YEAR_3TDEA: u16 = 2023; // See footnote on p. 54. const CUTOFF_YEAR_DSA: u16 = 2023; // See FIPS-186-5 p. 16. static SPECIFIED_CURVES: Lazy<HashSet<Ecc>> = Lazy::new(|| { let mut s = HashSet::new(); s.insert(ED25519); s.insert(ED448); s.insert(P224); s.insert(P256); s.insert(P384); s.insert(P521); s.insert(BRAINPOOLP224R1); s.insert(BRAINPOOLP256R1); s.insert(BRAINPOOLP320R1); s.insert(BRAINPOOLP384R1); s.insert(BRAINPOOLP512R1); s.insert(SECP256K1); s }); static SPECIFIED_HASH_FUNCTIONS: Lazy<HashSet<Hash>> = Lazy::new(|| { let mut s = HashSet::new(); s.insert(SHA1); s.insert(SHA224); s.insert(SHA256); s.insert(SHA384); s.insert(SHA3_224); s.insert(SHA3_256); s.insert(SHA3_384); s.insert(SHA3_512); s.insert(SHA512); s.insert(SHA512_224); s.insert(SHA512_256); s.insert(SHAKE128); s.insert(SHAKE256); s }); static SPECIFIED_SYMMETRIC_KEYS: Lazy<HashSet<Symmetric>> = Lazy::new(|| { let mut s = HashSet::new(); s.insert(AES128); s.insert(AES192); s.insert(AES256); s.insert(TDEA2); s.insert(TDEA3); s }); /// [`Standard`] implementation of the [NIST Special Publication 800-57 /// Part 1 Revision 5 standard]. /// /// [NIST Special Publication 800-57 Part 1 Revision 5 standard]: https://doi.org/10.6028/NIST.SP.800-57pt1r5 pub struct Nist; impl Nist { /// Validates a hash function according to page 56 of the standard. /// The reference is made with regards to applications that /// primarily require pre-image resistance such as message /// authentication codes (MACs), key derivation functions (KDFs), /// and random bit generation. /// /// For applications that require collision resistance such digital /// signatures use /// [`validate_hash`](crate::standard::nist::Nist::validate_hash). /// /// If the hash function is not compliant then `Err` will contain the /// recommended primitive that one should use instead. /// /// If the hash function is compliant but the context specifies a /// higher security level, `Ok` will also hold the recommended /// primitive with the desired security level. /// /// **Note:** that this means an alternative might be suggested for a /// compliant hash functions with a similar security level in which a /// switch to the recommended primitive would likely be unwarranted. /// For example, when evaluating compliance for the `SHA3-256`, a /// recommendation to use `SHA256` will be made but switching to this /// as a result is likely unnecessary. /// /// # Example /// /// The following illustrates a call to validate a compliant hash /// function. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::hash::{SHA1, SHAKE128}; /// use wardstone_core::standard::nist::Nist; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// let hmac_sha1 = SHA1; /// assert_eq!(Nist::validate_hash_based(ctx, hmac_sha1), Ok(hmac_sha1)); /// ``` pub fn validate_hash_based(ctx: Context, hash: Hash) -> Result<Hash, Hash> { if SPECIFIED_HASH_FUNCTIONS.contains(&hash) { let pre_image_resistance = hash.security() << 1; let security = ctx.security().max(pre_image_resistance); match security { ..=111 => Err(SHAKE128), 112..=127 => { if ctx.year() > CUTOFF_YEAR { Err(SHAKE128) } else { Ok(SHAKE128) } }, 128 => Ok(SHAKE128), 129..=160 => Ok(SHA1), 161..=224 => Ok(SHA224), 225..=256 => Ok(SHA256), 257..=394 => Ok(SHA384), 395.. => Ok(SHA512), } } else { Err(SHAKE128) } } } impl Standard for Nist { /// Validate an elliptic curve cryptography primitive used for digital /// signatures and key establishment where f is the key size according /// to page 54-55 of the standard. /// /// If the key is not compliant then `Err` will contain the /// recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher /// security level, `Ok` will also hold the recommended primitive /// with the desired security level. /// /// # Example /// /// The following illustrates a call to validate a compliant key. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::ecc::P224; /// use wardstone_core::standard::nist::Nist; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// assert_eq!(Nist::validate_ecc(ctx, P224), Ok(P224)); /// ``` fn validate_ecc(ctx: Context, key: Ecc) -> Result<Ecc, Ecc> { if SPECIFIED_CURVES.contains(&key) { let security = ctx.security().max(key.security()); match security { ..=111 => { if ctx.year() > CUTOFF_YEAR { Err(P256) } else { Err(P224) } }, 112..=127 => { if ctx.year() > CUTOFF_YEAR { Err(P256) } else { Ok(P224) } }, 128..=191 => Ok(P256), 192..=255 => Ok(P384), 256.. => Ok(P521), } } else { Err(P256) } } /// Validates a finite field cryptography primitive. /// /// Examples include the DSA and key establishment algorithms such as /// Diffie-Hellman and MQV which can also be implemented as such, /// according to page 54-55 of the standard. /// /// A newer revision of FIPS-186, FIPS-186-5 no longer approves the /// DSA. /// /// If the key is not compliant then `Err` will contain the /// recommended key sizes L and N that one should use instead. /// /// If the key is compliant but the context specifies a higher /// security level, `Ok` will also hold the recommended key sizes L /// and N with the desired security level. /// /// **Note:** The standard specifies the choices for the pair l and n /// and so primitives that do not strictly conform to this will be /// deemed non-compliant. This restricts the choice of security /// specified in the `Context` to the values 160, 224, 256, 384, and /// 512. /// /// # Example /// /// The following illustrates a call to validate a compliant key. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::ffc::DSA_2048_224; /// use wardstone_core::standard::nist::Nist; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// let dsa_2048 = DSA_2048_224; /// assert_eq!(Nist::validate_ffc(ctx, dsa_2048), Ok(dsa_2048)); /// ``` fn validate_ffc(ctx: Context, key: Ffc) -> Result<Ffc, Ffc> { if ctx.year() > CUTOFF_YEAR_DSA { return Err(FFC_NOT_SUPPORTED); } let security = ctx.security().max(key.security()); match security { 80 => { if ctx.year() > CUTOFF_YEAR { Err(DSA_3072_256) } else { Err(DSA_2048_224) } }, 112 => { if ctx.year() > CUTOFF_YEAR { Err(DSA_3072_256) } else { Ok(DSA_2048_224) } }, 128 => Ok(DSA_3072_256), 192 => Ok(DSA_7680_384), 256 => Ok(DSA_15360_512), _ => Err(FFC_NOT_SUPPORTED), } } /// Validates a hash function according to page 56 of the standard. /// The reference is made with regards to applications that require /// collision resistance such as digital signatures. /// /// For applications that primarily require pre-image resistance such /// as message authentication codes (MACs), key derivation functions /// (KDFs), and random bit generation use /// [`validate_hash_based`](crate::standard::nist::Nist::validate_hash_based). /// /// If the hash function is not compliant then `Err` will contain the /// recommended primitive that one should use instead. /// /// If the hash function is compliant but the context specifies a /// higher security level, `Ok` will also hold the recommended /// primitive with the desired security level. /// /// **Note:** An alternative might be suggested for a compliant hash /// functions with a similar security level in which a switch to the /// recommended primitive would likely be unwarranted. For example, /// when evaluating compliance for the `SHA3-256`, a recommendation /// to use `SHA256` will be made but switching to this as a result /// is likely unnecessary. /// /// # Example /// /// The following illustrates a call to validate a non-compliant hash /// function. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::hash::{SHA1, SHA224}; /// use wardstone_core::standard::nist::Nist; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// assert_eq!(Nist::validate_hash(ctx, SHA1), Err(SHA224)); /// ``` fn validate_hash(ctx: Context, hash: Hash) -> Result<Hash, Hash> { if SPECIFIED_HASH_FUNCTIONS.contains(&hash) { let security = ctx.security().max(hash.security()); match security { ..=111 => { if ctx.year() > CUTOFF_YEAR { Err(SHA256) } else { Err(SHA224) } }, 112..=127 => { if ctx.year() > CUTOFF_YEAR { Err(SHA256) } else { Ok(SHA224) } }, 128..=191 => Ok(SHA256), 192..=255 => Ok(SHA384), 256.. => Ok(SHA512), } } else { Err(SHA256) } } /// Validates an integer factorisation cryptography primitive the /// most common of which is the RSA signature algorithm where k /// indicates the key size according to page 54-55 of the standard. /// /// If the key is not compliant then `Err` will contain the /// recommended key size that one should use instead. /// /// If the key is compliant but the context specifies a higher /// security level, `Ok` will also hold the recommended key size /// with the desired security level. /// /// **Note:** This will return a generic structure that specifies /// minimum private and public key sizes. /// /// # Example /// /// The following illustrates a call to validate a compliant key. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::ifc::RSA_PSS_2048; /// use wardstone_core::standard::nist::Nist; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// assert_eq!(Nist::validate_ifc(ctx, RSA_PSS_2048), Ok(RSA_PSS_2048)); /// ``` fn validate_ifc(ctx: Context, key: Ifc) -> Result<Ifc, Ifc> { let security = ctx.security().max(key.security()); match security { ..=111 => { if ctx.year() > CUTOFF_YEAR { Err(RSA_PSS_3072) } else { Err(RSA_PSS_2048) } }, 112..=127 => { if ctx.year() > CUTOFF_YEAR { Err(RSA_PSS_3072) } else { Ok(RSA_PSS_2048) } }, 128..=191 => Ok(RSA_PSS_3072), 192..=255 => Ok(RSA_PSS_7680), 256.. => Ok(RSA_PSS_15360), } } /// Validates a symmetric key primitive according to pages 54-55 of /// the standard. /// /// If the key is not compliant then `Err` will contain the /// recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher /// security level, `Ok` will also hold the recommended primitive /// with the desired security level. /// /// # Example /// /// The following illustrates a call to validate a three-key Triple /// DES key (which is deprecated through the year 2023). /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::symmetric::{AES128, TDEA3}; /// use wardstone_core::standard::nist::Nist; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// assert_eq!(Nist::validate_symmetric(ctx, TDEA3), Ok(AES128)); /// ``` fn validate_symmetric(ctx: Context, key: Symmetric) -> Result<Symmetric, Symmetric> { if SPECIFIED_SYMMETRIC_KEYS.contains(&key) { let security = ctx.security().max(key.security()); match security { ..=111 => Err(AES128), 112 => { // See SP 800-131Ar2 p. 7. let cutoff = if key.id == TDEA3.id { CUTOFF_YEAR_3TDEA } else { CUTOFF_YEAR }; if ctx.year() > cutoff { Err(AES128) } else { Ok(AES128) } }, 113..=128 => Ok(AES128), 129..=192 => Ok(AES192), 193.. => Ok(AES256), } } else { Err(AES128) } } } #[cfg(test)] mod tests { use super::*; use crate::{test_ecc, test_ffc, test_hash, test_hash_based, test_ifc, test_symmetric}; test_ecc!(p224, Nist, P224, Ok(P224)); test_ecc!(p256, Nist, P256, Ok(P256)); test_ecc!(p384, Nist, P384, Ok(P384)); test_ecc!(p521, Nist, P521, Ok(P521)); test_ecc!(ed25519, Nist, ED25519, Ok(P256)); test_ecc!(ed448, Nist, ED448, Ok(P384)); test_ecc!(x25519, Nist, X25519, Err(P256)); test_ecc!(x448, Nist, X448, Err(P256)); test_ecc!(brainpoolp224r1, Nist, BRAINPOOLP224R1, Ok(P224)); test_ecc!(brainpoolp256r1, Nist, BRAINPOOLP256R1, Ok(P256)); test_ecc!(brainpoolp320r1, Nist, BRAINPOOLP320R1, Ok(P256)); test_ecc!(brainpoolp384r1, Nist, BRAINPOOLP384R1, Ok(P384)); test_ecc!(brainpoolp512r1, Nist, BRAINPOOLP512R1, Ok(P521)); test_ecc!(secp256k1, Nist, SECP256K1, Ok(P256)); test_ffc!(ffc_1024_160, Nist, DSA_1024_160, Err(DSA_2048_224)); test_ffc!(ffc_2048_224, Nist, DSA_2048_224, Ok(DSA_2048_224)); test_ffc!(ffc_3072_256, Nist, DSA_3072_256, Ok(DSA_3072_256)); test_ffc!(ffc_7680_384, Nist, DSA_7680_384, Ok(DSA_7680_384)); test_ffc!(ffc_15360_512, Nist, DSA_15360_512, Ok(DSA_15360_512)); test_ifc!(ifc_1024, Nist, RSA_PSS_1024, Err(RSA_PSS_2048)); test_ifc!(ifc_2048, Nist, RSA_PSS_2048, Ok(RSA_PSS_2048)); test_ifc!(ifc_3072, Nist, RSA_PSS_3072, Ok(RSA_PSS_3072)); test_ifc!(ifc_7680, Nist, RSA_PSS_7680, Ok(RSA_PSS_7680)); test_ifc!(ifc_15360, Nist, RSA_PSS_15360, Ok(RSA_PSS_15360)); test_hash!( blake2b_256_collision_resistance, Nist, BLAKE2B_256, Err(SHA256) ); test_hash!( blake2b_384_collision_resistance, Nist, BLAKE2B_384, Err(SHA256) ); test_hash!( blake2b_512_collision_resistance, Nist, BLAKE2B_512, Err(SHA256) ); test_hash!( blake2s_256_collision_resistance, Nist, BLAKE2S_256, Err(SHA256) ); test_hash!(md4_collision_resistance, Nist, MD4, Err(SHA256)); test_hash!(md5_collision_resistance, Nist, MD5, Err(SHA256)); test_hash!(ripemd160_collision_resistance, Nist, RIPEMD160, Err(SHA256)); test_hash!(sha1_collision_resistance, Nist, SHA1, Err(SHA224)); test_hash!(sha224_collision_resistance, Nist, SHA224, Ok(SHA224)); test_hash!(sha256_collision_resistance, Nist, SHA256, Ok(SHA256)); test_hash!(sha384_collision_resistance, Nist, SHA384, Ok(SHA384)); test_hash!(sha3_224_collision_resistance, Nist, SHA3_224, Ok(SHA224)); test_hash!(sha3_256_collision_resistance, Nist, SHA3_256, Ok(SHA256)); test_hash!(sha3_384_collision_resistance, Nist, SHA3_384, Ok(SHA384)); test_hash!(sha3_512_collision_resistance, Nist, SHA3_512, Ok(SHA512)); test_hash!(sha512_collision_resistance, Nist, SHA512, Ok(SHA512)); test_hash!( sha512_224_collision_resistance, Nist, SHA512_224, Ok(SHA224) ); test_hash!( sha512_256_collision_resistance, Nist, SHA512_256, Ok(SHA256) ); test_hash!(shake128_collision_resistance, Nist, SHAKE128, Err(SHA224)); test_hash!(shake256_collision_resistance, Nist, SHAKE256, Ok(SHA256)); test_hash_based!( blake2b_256_pre_image_resistance, Nist, BLAKE2B_256, Err(SHAKE128) ); test_hash_based!( blake2b_384_pre_image_resistance, Nist, BLAKE2B_384, Err(SHAKE128) ); test_hash_based!( blake2b_512_pre_image_resistance, Nist, BLAKE2B_512, Err(SHAKE128) ); test_hash_based!( blake2s_256_pre_image_resistance, Nist, BLAKE2S_256, Err(SHAKE128) ); test_hash_based!(md4_pre_image_resistance, Nist, MD4, Err(SHAKE128)); test_hash_based!(md5_pre_image_resistance, Nist, MD5, Err(SHAKE128)); test_hash_based!( ripemd160_pre_image_resistance, Nist, RIPEMD160, Err(SHAKE128) ); test_hash_based!(sha1_pre_image_resistance, Nist, SHA1, Ok(SHA1)); test_hash_based!(sha224_pre_image_resistance, Nist, SHA224, Ok(SHA224)); test_hash_based!(sha256_pre_image_resistance, Nist, SHA256, Ok(SHA256)); test_hash_based!(sha384_pre_image_resistance, Nist, SHA384, Ok(SHA384)); test_hash_based!(sha3_224_pre_image_resistance, Nist, SHA3_224, Ok(SHA224)); test_hash_based!(sha3_256_pre_image_resistance, Nist, SHA3_256, Ok(SHA256)); test_hash_based!(sha3_384_pre_image_resistance, Nist, SHA3_384, Ok(SHA384)); test_hash_based!(sha3_512_pre_image_resistance, Nist, SHA3_512, Ok(SHA512)); test_hash_based!(sha512_pre_image_resistance, Nist, SHA512, Ok(SHA512)); test_hash_based!( sha512_224_pre_image_resistance, Nist, SHA512_224, Ok(SHA224) ); test_hash_based!( sha512_256_pre_image_resistance, Nist, SHA512_256, Ok(SHA256) ); test_hash_based!(shake128_pre_image_resistance, Nist, SHAKE128, Ok(SHAKE128)); test_hash_based!(shake256_pre_image_resistance, Nist, SHAKE256, Ok(SHA256)); test_symmetric!(two_key_tdea, Nist, TDEA2, Err(AES128)); test_symmetric!(three_key_tdea, Nist, TDEA3, Ok(AES128)); test_symmetric!(aes128, Nist, AES128, Ok(AES128)); test_symmetric!(aes192, Nist, AES192, Ok(AES192)); test_symmetric!(aes256, Nist, AES256, Ok(AES256)); } 07070100000094000041ED0000000000000000000000026537CEF400000000000000000000000000000000000000000000003300000000wardstone-0.2.0~0/crates/core/src/standard/testing07070100000095000081A40000000000000000000000016537CEF400000032000000000000000000000000000000000000003600000000wardstone-0.2.0~0/crates/core/src/standard/testing.rs//! Mock standards. pub mod strong; pub mod weak; 07070100000096000081A40000000000000000000000016537CEF400002A00000000000000000000000000000000000000003D00000000wardstone-0.2.0~0/crates/core/src/standard/testing/strong.rs//! A mock standard with a minimum security requirement of at least //! 256-bits. //! //! This is the level of security estimated to be enough to resist an //! attack using Grover's algorithm enabled by quantum computers which //! as of writing does not appear to be a practical concern. However, //! bumping the security parameter may not be enough for some signature //! schemes such as those that use elliptic curves. use crate::context::Context; use crate::primitive::ecc::*; use crate::primitive::ffc::*; use crate::primitive::hash::*; use crate::primitive::ifc::*; use crate::primitive::symmetric::*; use crate::primitive::Primitive; use crate::standard::Standard; /// [`Standard`] implementation of a mock standard that is intended to /// be relatively strong compared to all the other standards defined in /// this crate. pub struct Strong; impl Standard for Strong { /// Validate an elliptic curve cryptography primitive used for digital /// signatures and key establishment. /// /// If the key is not compliant then `Err` will contain the /// recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher /// security level, `Ok` will also hold the recommended primitive /// with the desired security level. /// /// # Example /// /// The following illustrates a call to validate a non-compliant key. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::ecc::{ECC_NOT_ALLOWED, ED25519}; /// use wardstone_core::standard::testing::strong::Strong; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// assert_eq!(Strong::validate_ecc(ctx, ED25519), Err(ECC_NOT_ALLOWED)); /// ``` fn validate_ecc(_ctx: Context, _key: Ecc) -> Result<Ecc, Ecc> { Err(ECC_NOT_ALLOWED) } /// Validates a finite field cryptography primitive. /// /// Examples include the DSA and key establishment algorithms such as /// Diffie-Hellman. /// /// If the key is not compliant then `Err` will contain the /// recommended key sizes L and N that one should use instead. /// /// If the key is compliant but the context specifies a higher /// security level, `Ok` will also hold the recommended key sizes L /// and N with the desired security level. /// /// # Example /// /// The following illustrates a call to validate a non-compliant key. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::ffc::{DSA_2048_224, FFC_NOT_SUPPORTED}; /// use wardstone_core::standard::testing::strong::Strong; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// let dsa_2048 = DSA_2048_224; /// assert_eq!(Strong::validate_ffc(ctx, dsa_2048), Err(FFC_NOT_SUPPORTED)); /// ``` fn validate_ffc(_ctx: Context, _key: Ffc) -> Result<Ffc, Ffc> { Err(FFC_NOT_SUPPORTED) } /// Validates a hash function. /// /// If the hash function is not compliant then `Err` will contain the /// recommended primitive that one should use instead. /// /// If the hash function is compliant but the context specifies a /// higher security level, `Ok` will also hold the recommended /// primitive with the desired security level. /// /// **Note:** An alternative might be suggested for a compliant hash /// function with a similar security level in which a switch to the /// recommended primitive would likely be unwarranted. For example, /// when evaluating compliance for the `SHA3-256`, a recommendation /// to use `SHA256` will be made but switching to this as a result /// is likely unnecessary. /// /// # Example /// /// The following illustrates a call to validate a compliant hash /// function. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::hash::{SHA256, SHA512}; /// use wardstone_core::standard::testing::strong::Strong; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// assert_eq!(Strong::validate_hash(ctx, SHA256), Err(SHA512)); /// ``` fn validate_hash(ctx: Context, hash: Hash) -> Result<Hash, Hash> { let security = ctx.security().max(hash.security()); match security { ..=255 => Err(SHA512), 256.. => Ok(SHA512), } } /// Validates an integer factorisation cryptography primitive the /// most common of which is the RSA signature algorithm. /// /// If the key is not compliant then `Err` will contain the /// recommended key size that one should use instead. /// /// If the key is compliant but the context specifies a higher /// security level, `Ok` will also hold the recommended key size /// with the desired security level. /// /// **Note:** Unlike other functions in this module, this will return /// a generic structure that specifies minimum private and public /// key sizes. /// /// # Example /// /// The following illustrates a call to validate a compliant key. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::ifc::{IFC_NOT_ALLOWED, RSA_PSS_2048}; /// use wardstone_core::standard::testing::strong::Strong; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// assert_eq!( /// Strong::validate_ifc(ctx, RSA_PSS_2048), /// Err(IFC_NOT_ALLOWED) /// ); /// ``` fn validate_ifc(_ctx: Context, _key: Ifc) -> Result<Ifc, Ifc> { Err(IFC_NOT_ALLOWED) } /// Validates a symmetric key primitive. /// /// If the key is compliant but the context specifies a higher /// security level, `Ok` will also hold the recommended primitive /// with the desired security level. /// /// # Example /// /// The following illustrates a call to validate a three-key Triple /// DES key. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::symmetric::{AES256, TDEA3}; /// use wardstone_core::standard::testing::strong::Strong; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// assert_eq!(Strong::validate_symmetric(ctx, TDEA3), Err(AES256)); /// ``` fn validate_symmetric(ctx: Context, key: Symmetric) -> Result<Symmetric, Symmetric> { let security = ctx.security().max(key.security()); match security { ..=255 => Err(AES256), 256.. => Ok(AES256), } } } #[cfg(test)] mod tests { use super::*; use crate::{test_ecc, test_ffc, test_hash, test_ifc, test_symmetric}; test_ecc!(p224, Strong, P224, Err(ECC_NOT_ALLOWED)); test_ecc!(p256, Strong, P256, Err(ECC_NOT_ALLOWED)); test_ecc!(p384, Strong, P384, Err(ECC_NOT_ALLOWED)); test_ecc!(p521, Strong, P521, Err(ECC_NOT_ALLOWED)); test_ecc!(ed25519, Strong, ED25519, Err(ECC_NOT_ALLOWED)); test_ecc!(ed448, Strong, ED448, Err(ECC_NOT_ALLOWED)); test_ecc!(x25519, Strong, X25519, Err(ECC_NOT_ALLOWED)); test_ecc!(x488, Strong, X448, Err(ECC_NOT_ALLOWED)); test_ecc!( brainpoolp224r1, Strong, BRAINPOOLP224R1, Err(ECC_NOT_ALLOWED) ); test_ecc!( brainpoolp256r1, Strong, BRAINPOOLP256R1, Err(ECC_NOT_ALLOWED) ); test_ecc!( brainpoolp320r1, Strong, BRAINPOOLP320R1, Err(ECC_NOT_ALLOWED) ); test_ecc!( brainpoolp384r1, Strong, BRAINPOOLP384R1, Err(ECC_NOT_ALLOWED) ); test_ecc!( brainpoolp512r1, Strong, BRAINPOOLP512R1, Err(ECC_NOT_ALLOWED) ); test_ecc!(secp256k1, Strong, SECP256K1, Err(ECC_NOT_ALLOWED)); test_ffc!(ffc_1024_160, Strong, DSA_1024_160, Err(FFC_NOT_SUPPORTED)); test_ffc!(ffc_2048_224, Strong, DSA_2048_224, Err(FFC_NOT_SUPPORTED)); test_ffc!(ffc_3072_256, Strong, DSA_3072_256, Err(FFC_NOT_SUPPORTED)); test_ffc!(ffc_7680_384, Strong, DSA_7680_384, Err(FFC_NOT_SUPPORTED)); test_ffc!(ffc_15360_512, Strong, DSA_15360_512, Err(FFC_NOT_SUPPORTED)); test_ifc!(ifc_1024, Strong, RSA_PSS_1024, Err(IFC_NOT_ALLOWED)); test_ifc!(ifc_1280, Strong, RSA_PSS_1280, Err(IFC_NOT_ALLOWED)); test_ifc!(ifc_1536, Strong, RSA_PSS_1536, Err(IFC_NOT_ALLOWED)); test_ifc!(ifc_2048, Strong, RSA_PSS_2048, Err(IFC_NOT_ALLOWED)); test_ifc!(ifc_3072, Strong, RSA_PSS_3072, Err(IFC_NOT_ALLOWED)); test_ifc!(ifc_4096, Strong, RSA_PSS_4096, Err(IFC_NOT_ALLOWED)); test_ifc!(ifc_7680, Strong, RSA_PSS_7680, Err(IFC_NOT_ALLOWED)); test_ifc!(ifc_8192, Strong, RSA_PSS_8192, Err(IFC_NOT_ALLOWED)); test_ifc!(ifc_15360, Strong, RSA_PSS_15360, Err(IFC_NOT_ALLOWED)); test_hash!(blake_224, Strong, BLAKE_224, Err(SHA512)); test_hash!(blake_256, Strong, BLAKE_256, Err(SHA512)); test_hash!(blake_384, Strong, BLAKE_384, Err(SHA512)); test_hash!(blake_512, Strong, BLAKE_512, Ok(SHA512)); test_hash!(blake2b_256, Strong, BLAKE2B_256, Err(SHA512)); test_hash!(blake2b_384, Strong, BLAKE2B_384, Err(SHA512)); test_hash!(blake2b_512, Strong, BLAKE2B_512, Ok(SHA512)); test_hash!(blake2s_256, Strong, BLAKE2S_256, Err(SHA512)); test_hash!(md4, Strong, MD4, Err(SHA512)); test_hash!(md5, Strong, MD5, Err(SHA512)); test_hash!(ripemd160, Strong, RIPEMD160, Err(SHA512)); test_hash!(sha1, Strong, SHA1, Err(SHA512)); test_hash!(sha224, Strong, SHA224, Err(SHA512)); test_hash!(sha256, Strong, SHA256, Err(SHA512)); test_hash!(sha384, Strong, SHA384, Err(SHA512)); test_hash!(sha3_224, Strong, SHA3_224, Err(SHA512)); test_hash!(sha3_256, Strong, SHA3_256, Err(SHA512)); test_hash!(sha3_384, Strong, SHA3_384, Err(SHA512)); test_hash!(sha3_512, Strong, SHA3_512, Ok(SHA512)); test_hash!(sha512, Strong, SHA512, Ok(SHA512)); test_hash!(sha512_224, Strong, SHA512_224, Err(SHA512)); test_hash!(sha512_256, Strong, SHA512_256, Err(SHA512)); test_hash!(shake128, Strong, SHAKE128, Err(SHA512)); test_hash!(shake256, Strong, SHAKE256, Err(SHA512)); test_hash!(whirlpool, Strong, WHIRLPOOL, Ok(SHA512)); test_symmetric!(aes128, Strong, AES128, Err(AES256)); test_symmetric!(aes192, Strong, AES192, Err(AES256)); test_symmetric!(aes256, Strong, AES256, Ok(AES256)); test_symmetric!(camellia128, Strong, CAMELLIA128, Err(AES256)); test_symmetric!(camellia192, Strong, CAMELLIA192, Err(AES256)); test_symmetric!(camellia256, Strong, CAMELLIA256, Ok(AES256)); test_symmetric!(des, Strong, DES, Err(AES256)); test_symmetric!(desx, Strong, DESX, Err(AES256)); test_symmetric!(idea, Strong, IDEA, Err(AES256)); test_symmetric!(serpent128, Strong, SERPENT128, Err(AES256)); test_symmetric!(serpent192, Strong, SERPENT192, Err(AES256)); test_symmetric!(serpent256, Strong, SERPENT256, Ok(AES256)); test_symmetric!(three_key_tdea, Strong, TDEA3, Err(AES256)); test_symmetric!(two_key_tdea, Strong, TDEA2, Err(AES256)); } 07070100000097000081A40000000000000000000000016537CEF400002BF5000000000000000000000000000000000000003B00000000wardstone-0.2.0~0/crates/core/src/standard/testing/weak.rs//! A mock standard with a minimum security requirement of at least //! 64-bits. //! //! **Caution:** This might return recommendations for primitives that //! are considered unsafe when used in some applications such as MD5 and //! SHA1. For secure applications use any of the other standards defined //! in this crate. use crate::context::Context; use crate::primitive::ecc::*; use crate::primitive::ffc::*; use crate::primitive::hash::*; use crate::primitive::ifc::*; use crate::primitive::symmetric::*; use crate::primitive::Primitive; use crate::standard::Standard; /// [`Standard`] implementation of a mock standard that is intended to /// be relatively weak compared to all the other standards defined in /// this crate. pub struct Weak; impl Standard for Weak { /// Validate an elliptic curve cryptography primitive used for digital /// signatures and key establishment. /// /// If the key is not compliant then `Err` will contain the /// recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher /// security level, `Ok` will also hold the recommended primitive /// with the desired security level. /// /// # Example /// /// The following illustrates a call to validate a compliant key. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::ecc::ED25519; /// use wardstone_core::standard::testing::weak::Weak; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// assert_eq!(Weak::validate_ecc(ctx, ED25519), Ok(ED25519)); /// ``` fn validate_ecc(ctx: Context, key: Ecc) -> Result<Ecc, Ecc> { let security = ctx.security().max(key.security()); match security { ..=63 => Err(P224), 64..=112 => Ok(P224), 113..=128 => Ok(ED25519), 129..=160 => Ok(BRAINPOOLP320R1), 161..=192 => Ok(P384), 193..=244 => Ok(ED448), 245..=256 => Ok(BRAINPOOLP512R1), 257.. => Ok(P521), } } /// Validates a finite field cryptography primitive. /// /// Examples include the DSA and key establishment algorithms such as /// Diffie-Hellman. /// /// If the key is not compliant then `Err` will contain the /// recommended key sizes L and N that one should use instead. /// /// If the key is compliant but the context specifies a higher /// security level, `Ok` will also hold the recommended key sizes L /// and N with the desired security level. /// /// # Example /// /// The following illustrates a call to validate a compliant key. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::ffc::{DSA_2048_224, DSA_3072_256}; /// use wardstone_core::standard::testing::weak::Weak; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// let dsa_2048 = DSA_2048_224; /// assert_eq!(Weak::validate_ffc(ctx, dsa_2048), Ok(dsa_2048)); /// ``` fn validate_ffc(ctx: Context, key: Ffc) -> Result<Ffc, Ffc> { let security = ctx.security().max(key.security()); match security { ..=63 => Err(DSA_1024_160), 64..=80 => Ok(DSA_1024_160), 81..=112 => Ok(DSA_2048_224), 113..=128 => Ok(DSA_3072_256), 129..=192 => Ok(DSA_7680_384), 193.. => Ok(DSA_15360_512), } } /// Validates a hash function. /// /// If the hash function is not compliant then `Err` will contain the /// recommended primitive that one should use instead. /// /// If the hash function is compliant but the context specifies a /// higher security level, `Ok` will also hold the recommended /// primitive with the desired security level. /// /// **Note:** An alternative might be suggested for a compliant hash /// function with a similar security level in which a switch to the /// recommended primitive would likely be unwarranted. For example, /// when evaluating compliance for the `SHA3-256`, a recommendation /// to use `SHA256` will be made but switching to this as a result /// is likely unnecessary. /// /// # Example /// /// The following illustrates a call to validate a compliant hash /// function. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::hash::{SHA1, SHA256}; /// use wardstone_core::standard::testing::weak::Weak; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// assert_eq!(Weak::validate_hash(ctx, SHA1), Ok(SHA1)); /// ``` fn validate_hash(ctx: Context, hash: Hash) -> Result<Hash, Hash> { let security = ctx.security().max(hash.security()); match security { ..=63 => Err(SHAKE128), 64 => Ok(SHAKE128), 65..=80 => Ok(SHA1), 81..=112 => Ok(SHA224), 113..=128 => Ok(BLAKE3), 129..=192 => Ok(BLAKE2B_384), 193.. => Ok(BLAKE2B_512), } } /// Validates an integer factorisation cryptography primitive the /// most common of which is the RSA signature algorithm. /// /// If the key is not compliant then `Err` will contain the /// recommended key size that one should use instead. /// /// If the key is compliant but the context specifies a higher /// security level, `Ok` will also hold the recommended key size /// with the desired security level. /// /// **Note:** Unlike other functions in this module, this will return /// a generic structure that specifies minimum private and public /// key sizes. /// /// # Example /// /// The following illustrates a call to validate a compliant key. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::ifc::RSA_PSS_2048; /// use wardstone_core::standard::testing::weak::Weak; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// assert_eq!(Weak::validate_ifc(ctx, RSA_PSS_2048), Ok(RSA_PSS_2048)); /// ``` fn validate_ifc(ctx: Context, key: Ifc) -> Result<Ifc, Ifc> { let security = ctx.security().max(key.security()); match security { ..=63 => Err(RSA_PSS_1024), 64..=80 => Ok(RSA_PSS_1024), 81..=112 => Ok(RSA_PSS_2048), 113..=128 => Ok(RSA_PSS_3072), 129..=192 => Ok(RSA_PSS_7680), 193.. => Ok(RSA_PSS_15360), } } /// Validates a symmetric key primitive. /// /// If the key is compliant but the context specifies a higher /// security level, `Ok` will also hold the recommended primitive /// with the desired security level. /// /// # Example /// /// The following illustrates a call to validate a three-key Triple /// DES key. /// /// ``` /// use wardstone_core::context::Context; /// use wardstone_core::primitive::symmetric::TDEA3; /// use wardstone_core::standard::testing::weak::Weak; /// use wardstone_core::standard::Standard; /// /// let ctx = Context::default(); /// assert_eq!(Weak::validate_symmetric(ctx, TDEA3), Ok(TDEA3)); /// ``` fn validate_symmetric(ctx: Context, key: Symmetric) -> Result<Symmetric, Symmetric> { let security = ctx.security().max(key.security()); match security { ..=63 => Err(TDEA2), 64..=95 => Ok(TDEA2), 96..=112 => Ok(TDEA3), 113..=120 => Ok(DESX), 121..=126 => Ok(IDEA), 127..=128 => Ok(AES128), 129..=192 => Ok(AES192), 193.. => Ok(AES256), } } } #[cfg(test)] mod tests { use super::*; use crate::{test_ecc, test_ffc, test_hash, test_ifc, test_symmetric}; test_ecc!(p224, Weak, P224, Ok(P224)); test_ecc!(p256, Weak, P256, Ok(ED25519)); test_ecc!(p384, Weak, P384, Ok(P384)); test_ecc!(p521, Weak, P521, Ok(P521)); test_ecc!(ed25519, Weak, ED25519, Ok(ED25519)); test_ecc!(ed488, Weak, ED448, Ok(ED448)); test_ecc!(x25519, Weak, X25519, Ok(ED25519)); test_ecc!(x448, Weak, X448, Ok(ED448)); test_ecc!(brainpoolp224r1, Weak, BRAINPOOLP224R1, Ok(P224)); test_ecc!(brainpoolp256r1, Weak, BRAINPOOLP256R1, Ok(ED25519)); test_ecc!(brainpoolp320r1, Weak, BRAINPOOLP320R1, Ok(BRAINPOOLP320R1)); test_ecc!(brainpoolp384r1, Weak, BRAINPOOLP384R1, Ok(P384)); test_ecc!(brainpoolp512r1, Weak, BRAINPOOLP512R1, Ok(BRAINPOOLP512R1)); test_ecc!(secp256k1, Weak, SECP256K1, Ok(ED25519)); test_ffc!(ffc_1024_160, Weak, DSA_1024_160, Ok(DSA_1024_160)); test_ffc!(ffc_2048_224, Weak, DSA_2048_224, Ok(DSA_2048_224)); test_ffc!(ffc_3072_256, Weak, DSA_3072_256, Ok(DSA_3072_256)); test_ffc!(ffc_7680_384, Weak, DSA_7680_384, Ok(DSA_7680_384)); test_ffc!(ffc_15360_512, Weak, DSA_15360_512, Ok(DSA_15360_512)); test_ifc!(ifc_1024, Weak, RSA_PSS_1024, Ok(RSA_PSS_1024)); test_ifc!(ifc_1280, Weak, RSA_PSS_1280, Ok(RSA_PSS_1024)); test_ifc!(ifc_1536, Weak, RSA_PSS_1536, Ok(RSA_PSS_1024)); test_ifc!(ifc_2048, Weak, RSA_PSS_2048, Ok(RSA_PSS_2048)); test_ifc!(ifc_3072, Weak, RSA_PSS_3072, Ok(RSA_PSS_3072)); test_ifc!(ifc_4096, Weak, RSA_PSS_4096, Ok(RSA_PSS_3072)); test_ifc!(ifc_7680, Weak, RSA_PSS_7680, Ok(RSA_PSS_7680)); test_ifc!(ifc_8192, Weak, RSA_PSS_8192, Ok(RSA_PSS_7680)); test_ifc!(ifc_15360, Weak, RSA_PSS_15360, Ok(RSA_PSS_15360)); test_hash!(blake_224, Weak, BLAKE_224, Ok(SHA224)); test_hash!(blake_256, Weak, BLAKE_256, Ok(BLAKE3)); test_hash!(blake_384, Weak, BLAKE_384, Ok(BLAKE2B_384)); test_hash!(blake_512, Weak, BLAKE_512, Ok(BLAKE2B_512)); test_hash!(blake2b_256, Weak, BLAKE2B_256, Ok(BLAKE3)); test_hash!(blake2b_384, Weak, BLAKE2B_384, Ok(BLAKE2B_384)); test_hash!(blake2b_512, Weak, BLAKE2B_512, Ok(BLAKE2B_512)); test_hash!(blake2s_256, Weak, BLAKE2S_256, Ok(BLAKE3)); test_hash!(md4, Weak, MD4, Ok(SHAKE128)); test_hash!(md5, Weak, MD5, Ok(SHAKE128)); test_hash!(ripemd160, Weak, RIPEMD160, Ok(SHA1)); test_hash!(sha1, Weak, SHA1, Ok(SHA1)); test_hash!(sha224, Weak, SHA224, Ok(SHA224)); test_hash!(sha256, Weak, SHA256, Ok(BLAKE3)); test_hash!(sha384, Weak, SHA384, Ok(BLAKE2B_384)); test_hash!(sha3_224, Weak, SHA3_224, Ok(SHA224)); test_hash!(sha3_256, Weak, SHA3_256, Ok(BLAKE3)); test_hash!(sha3_384, Weak, SHA3_384, Ok(BLAKE2B_384)); test_hash!(sha3_512, Weak, SHA3_512, Ok(BLAKE2B_512)); test_hash!(sha512, Weak, SHA512, Ok(BLAKE2B_512)); test_hash!(sha512_224, Weak, SHA512_224, Ok(SHA224)); test_hash!(sha512_256, Weak, SHA512_256, Ok(BLAKE3)); test_hash!(shake128, Weak, SHAKE128, Ok(SHAKE128)); test_hash!(shake256, Weak, SHAKE256, Ok(BLAKE3)); test_hash!(whirlpool, Weak, WHIRLPOOL, Ok(BLAKE2B_512)); test_symmetric!(aes128, Weak, AES128, Ok(AES128)); test_symmetric!(aes192, Weak, AES192, Ok(AES192)); test_symmetric!(aes256, Weak, AES256, Ok(AES256)); test_symmetric!(camellia128, Weak, CAMELLIA128, Ok(AES128)); test_symmetric!(camellia192, Weak, CAMELLIA192, Ok(AES192)); test_symmetric!(camellia256, Weak, CAMELLIA256, Ok(AES256)); test_symmetric!(des, Weak, DES, Err(TDEA2)); test_symmetric!(desx, Weak, DESX, Ok(DESX)); test_symmetric!(idea, Weak, IDEA, Ok(IDEA)); test_symmetric!(serpent128, Weak, SERPENT128, Ok(AES128)); test_symmetric!(serpent192, Weak, SERPENT192, Ok(AES192)); test_symmetric!(serpent256, Weak, SERPENT256, Ok(AES256)); test_symmetric!(three_key_tdea, Weak, TDEA3, Ok(TDEA3)); test_symmetric!(two_key_tdea, Weak, TDEA2, Ok(TDEA2)); } 07070100000098000041ED0000000000000000000000026537CEF400000000000000000000000000000000000000000000003500000000wardstone-0.2.0~0/crates/core/src/standard/utilities07070100000099000081A40000000000000000000000016537CEF400000011000000000000000000000000000000000000003800000000wardstone-0.2.0~0/crates/core/src/standard/utilities.rspub mod testing; 0707010000009A000081A40000000000000000000000016537CEF40000081D000000000000000000000000000000000000004000000000wardstone-0.2.0~0/crates/core/src/standard/utilities/testing.rs//! Testing utilities. /// Expands a unit test for an elliptic curve primitive. #[macro_export] macro_rules! test_ecc { ($name:ident, $standard:ident, $input:expr, $want:expr) => { #[test] fn $name() { use $crate::context::Context; let ctx = Context::default(); assert_eq!($standard::validate_ecc(ctx, $input), $want); } }; } /// Expands a unit test for finite field primitive. #[macro_export] macro_rules! test_ffc { ($name:ident, $standard:ident, $input:expr, $want:expr) => { #[test] fn $name() { use $crate::context::Context; let ctx = Context::default(); assert_eq!($standard::validate_ffc(ctx, $input), $want); } }; } /// Expands a unit test an integer factorisation primitive. #[macro_export] macro_rules! test_ifc { ($name:ident, $standard:ident, $input:expr, $want:expr) => { #[test] fn $name() { use $crate::context::Context; let ctx = Context::default(); assert_eq!($standard::validate_ifc(ctx, $input), $want); } }; } /// Expands a unit test for a hash function primitive. #[macro_export] macro_rules! test_hash { ($name:ident, $standard:ident, $input:expr, $want:expr) => { #[test] fn $name() { use $crate::context::Context; let ctx = Context::default(); assert_eq!($standard::validate_hash(ctx, $input), $want); } }; } /// Expands a unit test for a hash function based primitive. #[macro_export] macro_rules! test_hash_based { ($name:ident, $standard:ident, $input:expr, $want:expr) => { #[test] fn $name() { use $crate::context::Context; let ctx = Context::default(); assert_eq!($standard::validate_hash_based(ctx, $input), $want); } }; } /// Expands a unit test for a symmetric key primitive. #[macro_export] macro_rules! test_symmetric { ($name:ident, $standard:ident, $input:expr, $want:expr) => { #[test] fn $name() { use $crate::context::Context; let ctx = Context::default(); assert_eq!($standard::validate_symmetric(ctx, $input), $want); } }; } 0707010000009B000041ED0000000000000000000000026537CEF400000000000000000000000000000000000000000000001D00000000wardstone-0.2.0~0/crates/ffi0707010000009C000081A40000000000000000000000016537CEF4000000E3000000000000000000000000000000000000002800000000wardstone-0.2.0~0/crates/ffi/Cargo.toml[package] name = "wardstone_ffi" version = "0.2.0" edition = "2021" [lib] name = "wardstone" crate-type = ["cdylib", "staticlib"] [dependencies] wardstone_core = { path = "../core" } [build-dependencies] cbindgen = "0.26.0" 0707010000009D000081A40000000000000000000000016537CEF400000489000000000000000000000000000000000000002700000000wardstone-0.2.0~0/crates/ffi/README.md# Wardstone FFI The `wardstone_ffi` library contains a subset of the [`wardstone_core`](../core/) functionality. It's main purpose is to expose a C API that can be used to interface with other programming languages that support it. It uses [`cbindgen`](https://github.com/mozilla/cbindgen) to generate C/C++ headers and dynamic and static libraries that can be found in the `target` directory after building the crate. The following is a C example that illustrates how this API can be called from other programming languages: ```c #include "wardstone.h" #include <assert.h> #include <stdbool.h> #include <stdint.h> #include <string.h> int main(void) { struct ws_hash got; memset(&got, 0, sizeof(struct ws_hash)); struct ws_hash want = WS_SHA224; struct ws_context ctx = ws_context_default(); assert(ws_nist_validate_hash(ctx, WS_SHA1, &got) == false && "SHA1 should fail"); assert(got.id == want.id && "unexpected hash function recommendation"); assert(ws_nist_validate_hash(ctx, WS_SHA256, NULL) == true && "SHA256 should pass"); } ``` See the [`examples`](/examples/ffi/) directory for more details about how to compile and run this code. 0707010000009E000081A40000000000000000000000016537CEF4000003AF000000000000000000000000000000000000002600000000wardstone-0.2.0~0/crates/ffi/build.rsextern crate cbindgen; use std::env; use std::path::Path; fn main() { let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); let target_dir = Path::new("../../target"); let header = target_dir.join("wardstone.h"); cbindgen::Builder::new() .rename_item("Context", "ws_context") .rename_item("Ecc", "ws_ecc") .rename_item("Ffc", "ws_ffc") .rename_item("Hash", "ws_hash") .rename_item("Ifc", "ws_ifc") .rename_item("Security", "ws_security") .rename_item("Symmetric", "ws_symmetric") .with_cpp_compat(true) .with_crate(crate_dir) .with_parse_deps(true) .with_parse_include(&["wardstone_core"]) .with_header("/* Code generated by cbindgen. DO NOT EDIT. */") .with_include_guard("WARDSTONE_H_") .with_language(cbindgen::Language::C) .with_no_includes() .with_sys_include("stdint.h") .generate() .expect("Unable to generate bindings") .write_to_file(header); } 0707010000009F000041ED0000000000000000000000026537CEF400000000000000000000000000000000000000000000002100000000wardstone-0.2.0~0/crates/ffi/src070701000000A0000081A40000000000000000000000016537CEF400000153000000000000000000000000000000000000002C00000000wardstone-0.2.0~0/crates/ffi/src/context.rs//! Specifies the context in which a cryptographic primitive will be //! assessed against. use wardstone_core::context::Context; /// Creates a context which will default to the year 2023 and will use /// the minimum security defined by the standard. #[no_mangle] pub extern "C" fn ws_context_default() -> Context { Context::default() } 070701000000A1000081A40000000000000000000000016537CEF4000004E5000000000000000000000000000000000000002800000000wardstone-0.2.0~0/crates/ffi/src/lib.rs//! # Wardstone FFI //! //! The `wardstone_ffi` library contains a subset of the //! `wardstone_core` functionality. It's main purpose is to expose a C //! API that can be used to interface with other programming languages //! that support it. //! //! It uses [`cbindgen`] to generate C/C++ headers and dynamic and //! static libraries that can be found in the `target` directory after //! building the crate. //! //! The following is a C example that illustrates how this API can be //! used from other programming languages: //! //! ```c //! #include "wardstone.h" //! #include <assert.h> //! #include <stdbool.h> //! #include <stdint.h> //! #include <string.h> //! //! int main(void) { //! struct ws_hash got; //! memset(&got, 0, sizeof(struct ws_hash)); //! struct ws_hash want = WS_SHA224; //! struct ws_context ctx = ws_context_default(); //! assert(ws_nist_validate_hash(ctx, WS_SHA1, &got) == false && "SHA1 should fail"); //! assert(got.id == want.id && "unexpected hash function recommendation"); //! assert(ws_nist_validate_hash(ctx, WS_SHA256, NULL) == true && "SHA256 should pass"); //! } //! ``` //! //! [`cbindgen`]: https://github.com/mozilla/cbindgen pub mod context; pub mod primitives; pub mod standards; mod utilities; 070701000000A2000041ED0000000000000000000000026537CEF400000000000000000000000000000000000000000000002C00000000wardstone-0.2.0~0/crates/ffi/src/primitives070701000000A3000081A40000000000000000000000016537CEF40000009D000000000000000000000000000000000000002F00000000wardstone-0.2.0~0/crates/ffi/src/primitives.rs//! Submodules that contain common cryptographic primitives and their //! instances. pub mod ecc; pub mod ffc; pub mod hash; pub mod ifc; pub mod symmetric; 070701000000A4000081A40000000000000000000000016537CEF40000480E000000000000000000000000000000000000003300000000wardstone-0.2.0~0/crates/ffi/src/primitives/ecc.rs//! Specifies a set of commonly used elliptic curve cryptography //! instances. use wardstone_core::primitive::ecc::*; /// Represents the Weierstrass curve B-163 over a prime field. Also /// known as sect163r2. #[no_mangle] pub static WS_B163: Ecc = B163; /// Represents the Weierstrass curve B-223 over a prime field. Also /// known as sect233r1 and wap-wsg-idm-ecid-wtls11. #[no_mangle] pub static WS_B233: Ecc = B233; /// Represents the Weierstrass curve B-283 over a prime field. Also /// known as sect283r1. #[no_mangle] pub static WS_B283: Ecc = B283; /// Represents the Weierstrass curve B-409 over a prime field. Also /// known as sect409r1. #[no_mangle] pub static WS_B409: Ecc = B409; /// Represents the Weierstrass curve B-571 over a prime field. Also /// known as sect571r1. #[no_mangle] pub static WS_B571: Ecc = B571; /// Represents the curve brainpoolP160r1 specified in [RFC 5639]. /// /// [RFC 5639]: https://datatracker.ietf.org/doc/rfc5639 #[no_mangle] pub static WS_BRAINPOOLP160R1: Ecc = BRAINPOOLP160R1; /// Represents the curve brainpoolP160t1 specified in [RFC 5639]. /// /// [RFC 5639]: https://datatracker.ietf.org/doc/rfc5639 #[no_mangle] pub static WS_BRAINPOOLP160T1: Ecc = BRAINPOOLP160T1; /// Represents the curve brainpoolP160r1 specified in [RFC 5639]. /// /// [RFC 5639]: https://datatracker.ietf.org/doc/rfc5639 #[no_mangle] pub static WS_BRAINPOOLP192R1: Ecc = BRAINPOOLP192R1; /// Represents the curve brainpoolP160r1 specified in [RFC 5639]. /// /// [RFC 5639]: https://datatracker.ietf.org/doc/rfc5639 #[no_mangle] pub static WS_BRAINPOOLP192T1: Ecc = BRAINPOOLP192T1; /// Represents the curve brainpoolP224r1 specified in [RFC 5639]. /// /// [RFC 5639]: https://datatracker.ietf.org/doc/rfc5639 #[no_mangle] pub static WS_BRAINPOOLP224R1: Ecc = BRAINPOOLP224R1; /// Represents the curve brainpoolP224r1 specified in [RFC 5639]. /// /// [RFC 5639]: https://datatracker.ietf.org/doc/rfc5639 #[no_mangle] pub static WS_BRAINPOOLP224T1: Ecc = BRAINPOOLP224T1; /// Represents the curve brainpoolP256r1 specified in [RFC 5639]. /// /// [RFC 5639]: https://datatracker.ietf.org/doc/rfc5639 #[no_mangle] pub static WS_BRAINPOOLP256R1: Ecc = BRAINPOOLP256R1; /// Represents the curve brainpoolP256r1 specified in [RFC 5639]. /// /// [RFC 5639]: https://datatracker.ietf.org/doc/rfc5639 #[no_mangle] pub static WS_BRAINPOOLP256T1: Ecc = BRAINPOOLP256T1; /// Represents the curve brainpoolP320r1 specified in [RFC 5639]. /// /// [RFC 5639]: https://datatracker.ietf.org/doc/rfc5639 #[no_mangle] pub static WS_BRAINPOOLP320R1: Ecc = BRAINPOOLP320R1; /// Represents the curve brainpoolP320r1 specified in [RFC 5639]. /// /// [RFC 5639]: https://datatracker.ietf.org/doc/rfc5639 #[no_mangle] pub static WS_BRAINPOOLP320T1: Ecc = BRAINPOOLP320T1; /// Represents the curve brainpoolP384r1 specified in [RFC 5639]. /// /// [RFC 5639]: https://datatracker.ietf.org/doc/rfc5639 #[no_mangle] pub static WS_BRAINPOOLP384R1: Ecc = BRAINPOOLP384R1; /// Represents the curve brainpoolP384r1 specified in [RFC 5639]. /// /// [RFC 5639]: https://datatracker.ietf.org/doc/rfc5639 #[no_mangle] pub static WS_BRAINPOOLP384T1: Ecc = BRAINPOOLP384T1; /// Represents the curve brainpoolP512r1 specified in [RFC 5639]. /// /// [RFC 5639]: https://datatracker.ietf.org/doc/rfc5639 #[no_mangle] pub static WS_BRAINPOOLP512R1: Ecc = BRAINPOOLP512R1; /// Represents the curve brainpoolP512r1 specified in [RFC 5639]. /// /// [RFC 5639]: https://datatracker.ietf.org/doc/rfc5639 #[no_mangle] pub static WS_BRAINPOOLP512T1: Ecc = BRAINPOOLP512T1; /// Represents the c2pnb163v1 curve as specified in ANSI x9.62. Also /// known as wap-wsg-idm-ecid-wtls5. #[no_mangle] pub static WS_C2PNB163V1: Ecc = C2PNB163V1; /// Represents the c2pnb163v2 curve as specified in ANSI x9.62. #[no_mangle] pub static WS_C2PNB163V2: Ecc = C2PNB163V2; /// Represents the c2pnb163v3 curve as specified in ANSI x9.62. #[no_mangle] pub static WS_C2PNB163V3: Ecc = C2PNB163V3; /// Represents the c2pnb176v1 curve as specified in ANSI x9.62. #[no_mangle] pub static WS_C2PNB176V1: Ecc = C2PNB176V1; /// Represents the c2pnb208w1 curve as specified in ANSI x9.62. #[no_mangle] pub static WS_C2PNB208W1: Ecc = C2PNB208W1; /// Represents the c2pnb272w1 curve as specified in ANSI x9.62. #[no_mangle] pub static WS_C2PNB272W1: Ecc = C2PNB272W1; /// Represents the c2pnb304w1 curve as specified in ANSI x9.62. #[no_mangle] pub static WS_C2PNB304W1: Ecc = C2PNB304W1; /// Represents the c2pnb368w1 curve as specified in ANSI x9.62. #[no_mangle] pub static WS_C2PNB368W1: Ecc = C2PNB368W1; /// Represents the c2tnb191v1 curve as specified in ANSI x9.62. #[no_mangle] pub static WS_C2TNB191V1: Ecc = C2TNB191V1; /// Represents the c2tnb191v2 curve as specified in ANSI x9.62. #[no_mangle] pub static WS_C2TNB191V2: Ecc = C2TNB191V2; /// Represents the c2tnb191v3 curve as specified in ANSI x9.62. #[no_mangle] pub static WS_C2TNB191V3: Ecc = C2TNB191V3; /// Represents the c2tnb239v1 curve as specified in ANSI x9.62. #[no_mangle] pub static WS_C2TNB239V1: Ecc = C2TNB239V1; /// Represents the c2tnb239v2 curve as specified in ANSI x9.62. #[no_mangle] pub static WS_C2TNB239V2: Ecc = C2TNB239V2; /// Represents the c2tnb239v3 curve as specified in ANSI x9.62. #[no_mangle] pub static WS_C2TNB239V3: Ecc = C2TNB239V3; /// Represents the c2tnb359v1 curve as specified in ANSI x9.62. #[no_mangle] pub static WS_C2TNB359V1: Ecc = C2TNB359V1; /// Represents the c2tnb431r1 curve as specified in ANSI x9.62. #[no_mangle] pub static WS_C2TNB431R1: Ecc = C2TNB431R1; /// Represents the Ed25519 signature algorithm as specified in the paper /// [High-speed high-security signatures]. /// /// [High-speed high-security signatures]: https://eprint.iacr.org/2011/368 #[no_mangle] pub static WS_ED25519: Ecc = ED25519; /// Represents the Ed448 signature algorithm as specified in the paper /// [High-speed high-security signatures]. /// /// [High-speed high-security signatures]: https://eprint.iacr.org/2011/368 #[no_mangle] pub static WS_ED448: Ecc = ED448; /// Represents the Weierstrass curve K-163 over a prime field. Also /// known as wap-wsg-idm-ecid-wtls3. #[no_mangle] pub static WS_K163: Ecc = K163; /// Represents the Weierstrass curve K-223 over a prime field. Also /// known as wap-wsg-idm-ecid-wtls10. #[no_mangle] pub static WS_K233: Ecc = K233; /// Represents the Weierstrass curve K-409 over a prime field. #[no_mangle] pub static WS_K409: Ecc = K409; /// Represents the Weierstrass curve K-571 over a prime field. #[no_mangle] pub static WS_K571: Ecc = K571; /// Represents the Weierstrass curve P-192 over a prime field. Also /// known as prime192v1 and secp192r1. #[no_mangle] pub static WS_P192: Ecc = P192; /// Represents the Weierstrass curve P-224 over a prime field. Also /// known as secp224r1. #[no_mangle] pub static WS_P224: Ecc = P224; /// Represents the Weierstrass curve P-256 over a prime field. Also /// known as secp256r1. #[no_mangle] pub static WS_P256: Ecc = P256; /// Represents the Weierstrass curve P-384 over a prime field. Also /// known as secp384r1. #[no_mangle] pub static WS_P384: Ecc = P384; /// Represents the Weierstrass curve P-521 over a prime field. Also /// known as secp521r1. #[no_mangle] pub static WS_P521: Ecc = P521; /// Represents the prime192v1 curve as specified in ANSI x9.62. Also /// known as secp192r1 and P-192. #[no_mangle] pub static WS_PRIME192V1: Ecc = PRIME192V1; /// Represents the prime192v2 curve as specified in ANSI x9.62. #[no_mangle] pub static WS_PRIME192V2: Ecc = PRIME192V2; /// Represents the prime192v3 curve as specified in ANSI x9.62. #[no_mangle] pub static WS_PRIME192V3: Ecc = PRIME192V3; /// Represents the prime239v1 curve as specified in ANSI x9.62. #[no_mangle] pub static WS_PRIME239V1: Ecc = PRIME239V1; /// Represents the prime239v2 curve as specified in ANSI x9.62. #[no_mangle] pub static WS_PRIME239V2: Ecc = PRIME239V2; /// Represents the prime239v3 curve as specified in ANSI x9.62. #[no_mangle] pub static WS_PRIME239V3: Ecc = PRIME239V3; /// Represents the prime256v1 curve as specified in ANSI x9.62. Also /// known as P-256 and secp256r1. #[no_mangle] pub static WS_PRIME256V1: Ecc = PRIME256V1; /// Represents the secp112r1 curve as defined in [SEC 2]. Also known /// as wap-wsg-idm-ecid-wtls6. /// /// [SEC 2]: https://www.secg.org/SEC2-Ver-1.0.pdf #[no_mangle] pub static WS_SECP112R1: Ecc = SECP112R1; /// Represents the secp112r2 curve as defined in [SEC 2]. /// /// [SEC 2]: https://www.secg.org/SEC2-Ver-1.0.pdf #[no_mangle] pub static WS_SECP112R2: Ecc = SECP112R2; /// Represents the secp128r1 curve as defined in [SEC 2]. /// /// [SEC 2]: https://www.secg.org/SEC2-Ver-1.0.pdf #[no_mangle] pub static WS_SECP128R1: Ecc = SECP128R1; /// Represents the secp128r2 curve as defined in [SEC 2]. /// /// [SEC 2]: https://www.secg.org/SEC2-Ver-1.0.pdf #[no_mangle] pub static WS_SECP128R2: Ecc = SECP128R2; /// Represents the secp160r1 curve as defined in [SEC 2]. Also known as /// wap-wsg-idm-ecid-wtls7. /// /// [SEC 2]: https://www.secg.org/SEC2-Ver-1.0.pdf #[no_mangle] pub static WS_SECP160R1: Ecc = SECP160R1; /// Represents the secp160r2 curve as defined in [SEC 2]. /// /// [SEC 2]: https://www.secg.org/SEC2-Ver-1.0.pdf #[no_mangle] pub static WS_SECP160R2: Ecc = SECP160R2; /// Represents the secp192r1 curve as defined in [SEC 2]. Also known as /// prime192v1 and P-192. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static WS_SECP192R1: Ecc = SECP192R1; /// Represents the secp192k1 curve as defined in [SEC 2]. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static WS_SECP192K1: Ecc = SECP192K1; /// Represents the secp224r1 curve as defined in [SEC 2]. Also known as /// P-224 and wap-wsg-idm-ecid-wtls12. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static WS_SECP224R1: Ecc = SECP224R1; /// Represents the secp224k1 curve as defined in [SEC 2]. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static WS_SECP224K1: Ecc = SECP224K1; /// Represents the curve secp256k1 specified in [SEC 2]. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static WS_SECP256K1: Ecc = SECP256K1; /// Represents the secp256r1 curve as defined in [SEC 2]. Also known as /// prime256v1 and P-256. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static WS_SECP256R1: Ecc = SECP256R1; /// Represents the secp384r1 curve as defined in [SEC 2]. Also known as /// P-384. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static WS_SECP384R1: Ecc = SECP384R1; /// Represents the secp521r1 curve as defined in [SEC 2]. Also known as /// P-521. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static WS_SECP521R1: Ecc = SECP521R1; /// Represents the sect113r1 curve as defined in [SEC 2]. Also known as /// wap-wsg-idm-ecid-wtls4. /// /// [SEC 2]: https://www.secg.org/SEC2-Ver-1.0.pdf #[no_mangle] pub static WS_SECT113R1: Ecc = SECT113R1; /// Represents the sect113r2 curve as defined in [SEC 2]. /// /// [SEC 2]: https://www.secg.org/SEC2-Ver-1.0.pdf #[no_mangle] pub static WS_SECT113R2: Ecc = SECT113R2; /// Represents the sect131r1 curve as defined in [SEC 2]. /// /// [SEC 2]: https://www.secg.org/SEC2-Ver-1.0.pdf #[no_mangle] pub static WS_SECT131R1: Ecc = SECT131R1; /// Represents the sect131r2 curve as defined in [SEC 2]. /// /// [SEC 2]: https://www.secg.org/SEC2-Ver-1.0.pdf #[no_mangle] pub static WS_SECT131R2: Ecc = SECT131R2; /// Represents the sect163k1 curve as defined in [SEC 2]. Also known as /// K-163 and wap-wsg-idm-ecid-wtls3. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static WS_SECT163K1: Ecc = SECT163K1; /// Represents the sect163r1 curve as defined in [SEC 2]. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static WS_SECT163R1: Ecc = SECT163R1; /// Represents the sect163r2 curve as defined in [SEC 2]. Also known as /// B-163. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static WS_SECT163R2: Ecc = SECT163R2; /// Represents the sect193r1 curve as defined in [SEC 2]. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static WS_SECT193R1: Ecc = SECT193R1; /// Represents the sect193r2 curve as defined in [SEC 2]. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static WS_SECT193R2: Ecc = SECT193R2; /// Represents the sect233k1 curve as defined in [SEC 2]. Also known as /// K-233 and wap-wsg-idm-ecid-wtls10. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static WS_SECT233K1: Ecc = SECT233K1; /// Represents the sect233r1 curve as defined in [SEC 2]. Also known as /// B-233 and wap-wsg-idm-ecid-wtls11. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static WS_SECT233R1: Ecc = SECT233R1; /// Represents the sect239k1 curve as defined in [SEC 2]. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static WS_SECT239K1: Ecc = SECT239K1; /// Represents the sect283r1 curve as defined in [SEC 2]. Also known as /// B-283. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static WS_SECT283R1: Ecc = SECT283R1; /// Represents the sect409k1 curve as defined in [SEC 2]. Also known as /// K-409. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static WS_SECT409K1: Ecc = SECT409K1; /// Represents the sect409r1 curve as defined in [SEC 2]. Also known as /// B-409. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static WS_SECT409R1: Ecc = SECT409R1; /// Represents the sect571k1 curve as defined in [SEC 2]. Also known as /// K-571. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static WS_SECT571K1: Ecc = SECT571K1; /// Represents the sect571r1 curve as defined in [SEC 2]. Also known as /// B-571. /// /// [SEC 2]: https://www.secg.org/sec2-v2.pdf #[no_mangle] pub static WS_SECT571R1: Ecc = SECT571R1; /// Represents the SM2 digital signature algorithm as defined in /// draft-shen-sm2-ecdsa-02. /// /// [draft-shen-sm2-ecdsa-02]: https://datatracker.ietf.org/doc/html/draft-shen-sm2-ecdsa-02 #[no_mangle] pub static WS_SM2: Ecc = SM2; /// Represents the wap-wsg-idm-ecid-wtls1 curve as specified in /// [WAP-WTLS curves]. /// /// [WAP-WTLS curves]: https://www.wapforum.org/tech/documents/WAP-199-WTLS-20000218-a.pdf #[no_mangle] pub static WS_WAP_WSG_IDM_ECID_WTLS1: Ecc = WAP_WSG_IDM_ECID_WTLS1; /// Represents the wap-wsg-idm-ecid-wtls3 curve as specified in /// [WAP-WTLS curves]. Also known as sect163k1. /// /// [WAP-WTLS curves]: https://www.wapforum.org/tech/documents/WAP-199-WTLS-20000218-a.pdf #[no_mangle] pub static WS_WAP_WSG_IDM_ECID_WTLS3: Ecc = WAP_WSG_IDM_ECID_WTLS3; /// Represents the wap-wsg-idm-ecid-wtls4 curve as specified in /// [WAP-WTLS curves]. Also known as sect113r1. /// /// [WAP-WTLS curves]: https://www.wapforum.org/tech/documents/WAP-199-WTLS-20000218-a.pdf #[no_mangle] pub static WS_WAP_WSG_IDM_ECID_WTLS4: Ecc = WAP_WSG_IDM_ECID_WTLS4; /// Represents the wap-wsg-idm-ecid-wtls5 curve as specified in /// [WAP-WTLS curves]. Also known as c2pnb163v1. /// /// [WAP-WTLS curves]: https://www.wapforum.org/tech/documents/WAP-199-WTLS-20000218-a.pdf #[no_mangle] pub static WS_WAP_WSG_IDM_ECID_WTLS5: Ecc = WAP_WSG_IDM_ECID_WTLS5; /// Represents the wap-wsg-idm-ecid-wtls6 curve as specified in /// [WAP-WTLS curves]. Also known as secp112r1. /// /// [WAP-WTLS curves]: https://www.wapforum.org/tech/documents/WAP-199-WTLS-20000218-a.pdf #[no_mangle] pub static WS_WAP_WSG_IDM_ECID_WTLS6: Ecc = WAP_WSG_IDM_ECID_WTLS6; /// Represents the wap-wsg-idm-ecid-wtls7 curve as specified in /// [WAP-WTLS curves]. Also known as secp160r1. /// /// [WAP-WTLS curves]: https://www.wapforum.org/tech/documents/WAP-199-WTLS-20000218-a.pdf #[no_mangle] pub static WS_WAP_WSG_IDM_ECID_WTLS7: Ecc = WAP_WSG_IDM_ECID_WTLS7; /// Represents the wap-wsg-idm-ecid-wtls8 curve as specified in /// [WAP-WTLS curves]. /// /// [WAP-WTLS curves]: https://www.wapforum.org/tech/documents/WAP-199-WTLS-20000218-a.pdf #[no_mangle] pub static WS_WAP_WSG_IDM_ECID_WTLS8: Ecc = WAP_WSG_IDM_ECID_WTLS8; /// Represents the wap-wsg-idm-ecid-wtls9 curve as specified in /// [WAP-WTLS curves]. /// /// [WAP-WTLS curves]: https://www.wapforum.org/tech/documents/WAP-199-WTLS-20000218-a.pdf #[no_mangle] pub static WS_WAP_WSG_IDM_ECID_WTLS9: Ecc = WAP_WSG_IDM_ECID_WTLS9; /// Represents the wap-wsg-idm-ecid-wtls10 curve as specified in /// [WAP-WTLS curves]. Also known as K-233 and sect233k1. /// /// [WAP-WTLS curves]: https://www.wapforum.org/tech/documents/WAP-199-WTLS-20000218-a.pdf #[no_mangle] pub static WS_WAP_WSG_IDM_ECID_WTLS10: Ecc = WAP_WSG_IDM_ECID_WTLS10; /// Represents the wap-wsg-idm-ecid-wtls11 curve as specified in /// [WAP-WTLS curves]. Also known as B-233 and sect233r1. /// /// [WAP-WTLS curves]: https://www.wapforum.org/tech/documents/WAP-199-WTLS-20000218-a.pdf #[no_mangle] pub static WS_WAP_WSG_IDM_ECID_WTLS11: Ecc = WAP_WSG_IDM_ECID_WTLS11; /// Represents the wap-wsg-idm-ecid-wtls12 curve as specified in /// [WAP-WTLS curves]. Also known as P-224 and secp224r1. /// /// [WAP-WTLS curves]: https://www.wapforum.org/tech/documents/WAP-199-WTLS-20000218-a.pdf #[no_mangle] pub static WS_WAP_WSG_IDM_ECID_WTLS12: Ecc = WAP_WSG_IDM_ECID_WTLS12; /// Represents the X25519 algorithm as it appears in [RFC 7748]. /// /// [RFC 7748]: https://datatracker.ietf.org/doc/html/rfc7748 #[no_mangle] pub static WS_X25519: Ecc = X25519; /// Represents the X448 algorithm as it appears in [RFC 7748]. /// /// [RFC 7748]: https://datatracker.ietf.org/doc/html/rfc7748 #[no_mangle] pub static WS_X448: Ecc = X448; /// Generic instance that represents a choice of f = 224 for an elliptic /// curve primitive. #[no_mangle] pub static WS_ECC_224: Ecc = ECC_224; /// Generic instance that represents a choice of f = 256 for an elliptic /// curve primitive. #[no_mangle] pub static WS_ECC_256: Ecc = ECC_256; /// Generic instance that represents a choice of f = 384 for an elliptic /// curve primitive. #[no_mangle] pub static WS_ECC_384: Ecc = ECC_384; /// Generic instance that represents a choice of f = 512 for an elliptic /// curve primitive. #[no_mangle] pub static WS_ECC_512: Ecc = ECC_512; /// Placeholder for use in where this primitive or the security level it /// implies is not allowed. #[no_mangle] pub static WS_ECC_NOT_ALLOWED: Ecc = ECC_NOT_ALLOWED; 070701000000A5000081A40000000000000000000000016537CEF400000534000000000000000000000000000000000000003300000000wardstone-0.2.0~0/crates/ffi/src/primitives/ffc.rs//! Specifies a set of commonly used finite field cryptography //! instances. use wardstone_core::primitive::ffc::*; /// Generic instance that represents a choice of L = 1024 and N = 160 /// for a finite field cryptography primitive. #[no_mangle] pub static WS_DSA_1024_160: Ffc = DSA_1024_160; /// Generic instance that represents a choice of L = 2048 and N = 224 /// for a finite field cryptography primitive. #[no_mangle] pub static WS_DSA_2048_224: Ffc = DSA_2048_224; /// Generic instance that represents a choice of L = 2048 and N = 256 /// for a finite field cryptography primitive. #[no_mangle] pub static WS_DSA_2048_256: Ffc = DSA_2048_256; /// Generic instance that represents a choice of L = 3072 and N = 256 /// for a finite field cryptography primitive. #[no_mangle] pub static WS_DSA_3072_256: Ffc = DSA_3072_256; /// Generic instance that represents a choice of L = 7680 and N = 384 /// for a finite field cryptography primitive. #[no_mangle] pub static WS_DSA_7680_384: Ffc = DSA_7680_384; /// Generic instance that represents a choice of L = 15360 and N = 512 /// for a finite field cryptography primitive. #[no_mangle] pub static WS_DSA_15360_512: Ffc = DSA_15360_512; /// Placeholder for use in where this primitive is not supported. #[no_mangle] pub static WS_FFC_NOT_SUPPORTED: Ffc = FFC_NOT_SUPPORTED; 070701000000A6000081A40000000000000000000000016537CEF40000136D000000000000000000000000000000000000003400000000wardstone-0.2.0~0/crates/ffi/src/primitives/hash.rs//! Specifies a hash or hash-based cryptography primitive and a set of //! commonly used instances. use wardstone_core::primitive::hash::*; /// The BLAKE-224 hash function. #[no_mangle] pub static WS_BLAKE_224: Hash = BLAKE_224; /// The BLAKE-256 hash function. #[no_mangle] pub static WS_BLAKE_256: Hash = BLAKE_256; /// The BLAKE-384 hash function. #[no_mangle] pub static WS_BLAKE_384: Hash = BLAKE_384; /// The BLAKE-512 hash function. #[no_mangle] pub static WS_BLAKE_512: Hash = BLAKE_512; /// The BLAKE2b hash function as defined in [RFC 7693]. /// /// [RFC 7693]: https://www.rfc-editor.org/rfc/rfc7693.html #[no_mangle] pub static WS_BLAKE2B_256: Hash = BLAKE2B_256; /// The BLAKE2b hash function as defined in [RFC 7693]. /// /// [RFC 7693]: https://www.rfc-editor.org/rfc/rfc7693.html #[no_mangle] pub static WS_BLAKE2B_384: Hash = BLAKE2B_384; /// The BLAKE2b hash function as defined in [RFC 7693]. /// /// [RFC 7693]: https://www.rfc-editor.org/rfc/rfc7693.html #[no_mangle] pub static WS_BLAKE2B_512: Hash = BLAKE2B_512; /// The BLAKE2s hash function as defined in [RFC 7693]. /// /// [RFC 7693]: https://www.rfc-editor.org/rfc/rfc7693.html #[no_mangle] pub static WS_BLAKE2S_256: Hash = BLAKE2S_256; /// The BLAKE3 hash function. #[no_mangle] pub static WS_BLAKE3: Hash = BLAKE3; /// The MD4 hash function as defined in [RFC 1320]. /// /// **Warning:** This algorithm has been shown to be broken. It should /// only be used where compatibility with legacy systems, not security, /// is the goal. /// /// [RFC 1320]: https://www.rfc-editor.org/rfc/rfc1320.html #[no_mangle] pub static WS_MD4: Hash = MD4; /// The MD5 hash function as defined in [RFC 1321]. /// /// **Warning:** This algorithm has been shown to lack collision /// resistance and should generally not be used for secure applications. /// /// [RFC 1321]: https://www.rfc-editor.org/rfc/rfc1321.html #[no_mangle] pub static WS_MD5: Hash = MD5; /// The RIPEMD-160 hash function. /// /// **Warning:** This algorithm has been shown to be broken. It should /// only be used where compatibility with legacy systems, not security, /// is the goal. #[no_mangle] pub static WS_RIPEMD160: Hash = RIPEMD160; /// The SHA1 hash function as defined in [RFC 3174]. /// /// **Warning:** This algorithm has been shown to lack collision /// resistance and should generally not be used for secure applications. /// /// While this algorithm produced a digest length of 160 bits, it's /// security is believed to be lower. Here it is recorded to be 105 per /// page 8 of NIST SP 800-107. /// /// [RFC 3174]: https://www.rfc-editor.org/rfc/rfc3174.html #[no_mangle] pub static WS_SHA1: Hash = SHA1; /// The SHA224 hash function as defined in [FIPS 180-4]. /// /// [FIPS 180-4]: https://doi.org/10.6028/NIST.FIPS.180-4 #[no_mangle] pub static WS_SHA224: Hash = SHA224; /// The SHA256 hash function as defined in [FIPS 180-4]. /// /// [FIPS 180-4]: https://doi.org/10.6028/NIST.FIPS.180-4 #[no_mangle] pub static WS_SHA256: Hash = SHA256; /// The SHA384 hash function as defined in [FIPS 180-4]. /// /// [FIPS 180-4]: https://doi.org/10.6028/NIST.FIPS.180-4 #[no_mangle] pub static WS_SHA384: Hash = SHA384; /// The SHA3-224 hash function as defined in [FIPS 202]. /// /// [FIPS 202]: https://doi.org/10.6028/NIST.FIPS.202 #[no_mangle] pub static WS_SHA3_224: Hash = SHA3_224; /// The SHA3-256 hash function as defined in [FIPS 202]. /// /// [FIPS 202]: https://doi.org/10.6028/NIST.FIPS.202 #[no_mangle] pub static WS_SHA3_256: Hash = SHA3_256; /// The SHA3-384 hash function as defined in [FIPS 202]. /// /// [FIPS 202]: https://doi.org/10.6028/NIST.FIPS.202 #[no_mangle] pub static WS_SHA3_384: Hash = SHA3_384; /// The SHA3-512 hash function as defined in [FIPS 202]. /// /// [FIPS 202]: https://doi.org/10.6028/NIST.FIPS.202 #[no_mangle] pub static WS_SHA3_512: Hash = SHA3_512; /// The SHA512 hash function as defined in [FIPS 180-4]. /// /// [FIPS 180-4]: https://doi.org/10.6028/NIST.FIPS.180-4 #[no_mangle] pub static WS_SHA512: Hash = SHA512; /// The SHA512/224 hash function as defined in [FIPS 180-4]. /// /// [FIPS 180-4]: https://doi.org/10.6028/NIST.FIPS.180-4 #[no_mangle] pub static WS_SHA512_224: Hash = SHA512_224; /// The SHA512/256 hash function as defined in [FIPS 180-4]. /// /// [FIPS 180-4]: https://doi.org/10.6028/NIST.FIPS.180-4 #[no_mangle] pub static WS_SHA512_256: Hash = SHA512_256; /// The SHAKE128 extendable-output function as defined in [FIPS 202]. /// This assumes an output length of 128-bits. /// /// [FIPS 202]: https://doi.org/10.6028/NIST.FIPS.202 #[no_mangle] pub static WS_SHAKE128: Hash = SHAKE128; /// The SHAKE256 extendable-output function as defined in [FIPS 202]. /// This assumes an output length of 256-bits. /// /// [FIPS 202]: https://doi.org/10.6028/NIST.FIPS.202 #[no_mangle] pub static WS_SHAKE256: Hash = SHAKE256; /// The WHIRLPOOL hash function as defined in ISO/IEC 10118-3. #[no_mangle] pub static WS_WHIRLPOOL: Hash = WHIRLPOOL; 070701000000A7000081A40000000000000000000000016537CEF400000B82000000000000000000000000000000000000003300000000wardstone-0.2.0~0/crates/ffi/src/primitives/ifc.rs//! Specifies a integer factorisation cryptography primitive and a set //! of commonly used instances. use wardstone_core::primitive::ifc::*; /// An identifier for custom RSA with PKCS #1 v1.5 padding keys. /// /// This for use in creating custom keys in that can be used in /// standards that make a distinction between RSA padding schemes. #[no_mangle] pub static WS_ID_RSA_PKCS1: u16 = ID_RSA_PKCS1; /// An identifier for custom RSA with PSS encoding keys. /// /// This for use in creating custom keys in that can be used in /// standards that make a distinction between RSA padding schemes. #[no_mangle] pub static WS_ID_RSA_PSS: u16 = ID_RSA_PSS; /// 1024-bit RSA with PKCS #1 v1.5 padding as defined in RFC 8446. #[no_mangle] pub static WS_RSA_PKCS1_1024: Ifc = RSA_PKCS1_1024; /// 1536-bit RSA with PKCS #1 v1.5 padding as defined in RFC 8446. #[no_mangle] pub static WS_RSA_PKCS1_1536: Ifc = RSA_PKCS1_1536; /// 2048-bit RSA with PKCS #1 v1.5 padding as defined in RFC 8446. #[no_mangle] pub static WS_RSA_PKCS1_2048: Ifc = RSA_PKCS1_2048; /// 3072-bit RSA with PKCS #1 v1.5 padding as defined in RFC 8446. #[no_mangle] pub static WS_RSA_PKCS1_3072: Ifc = RSA_PKCS1_3072; /// 4096-bit RSA with PKCS #1 v1.5 padding as defined in RFC 8446. #[no_mangle] pub static WS_RSA_PKCS1_4096: Ifc = RSA_PKCS1_4096; /// 7680-bit RSA with PKCS #1 v1.5 padding as defined in RFC 8446. #[no_mangle] pub static WS_RSA_PKCS1_7680: Ifc = RSA_PKCS1_7680; /// 8192-bit RSA with PKCS #1 v1.5 padding as defined in RFC 8446. #[no_mangle] pub static WS_RSA_PKCS1_8192: Ifc = RSA_PKCS1_8192; /// 15360-bit RSA with PKCS #1 v1.5 padding as defined in RFC 8446. #[no_mangle] pub static WS_RSA_PKCS1_15360: Ifc = RSA_PKCS1_15360; /// 1024-bit RSA with PSS encoding as defined in RFC 8446. #[no_mangle] pub static WS_RSA_PSS_1024: Ifc = RSA_PSS_1024; /// 1280-bit RSA with PSS encoding as defined in RFC 8446. #[no_mangle] pub static WS_RSA_PSS_1280: Ifc = RSA_PSS_1280; /// 1536-bit RSA with PSS encoding as defined in RFC 8446. #[no_mangle] pub static WS_RSA_PSS_1536: Ifc = RSA_PSS_1536; /// 2048-bit RSA with PSS encoding as defined in RFC 8446.. #[no_mangle] pub static WS_RSA_PSS_2048: Ifc = RSA_PSS_2048; /// 3072-bit RSA with PSS encoding as defined in RFC 8446. #[no_mangle] pub static WS_RSA_PSS_3072: Ifc = RSA_PSS_3072; /// 4096-bit RSA with PSS encoding as defined in RFC 8446. #[no_mangle] pub static WS_RSA_PSS_4096: Ifc = RSA_PSS_4096; /// 7680-bit RSA with PSS encoding as defined in RFC 8446. #[no_mangle] pub static WS_RSA_PSS_7680: Ifc = RSA_PSS_7680; /// 7680-bit RSA with PSS encoding as defined in RFC 8446. #[no_mangle] pub static WS_RSA_PSS_8192: Ifc = RSA_PSS_8192; /// 15360-bit RSA with PSS encoding as defined in RFC 8446. #[no_mangle] pub static WS_RSA_PSS_15360: Ifc = RSA_PSS_15360; /// Placeholder for use in where this primitive is not allowed. #[no_mangle] pub static WS_IFC_NOT_ALLOWED: Ifc = IFC_NOT_ALLOWED; 070701000000A8000081A40000000000000000000000016537CEF4000008DC000000000000000000000000000000000000003900000000wardstone-0.2.0~0/crates/ffi/src/primitives/symmetric.rs//! Specifies a symmetric key cryptography primitive and a set of //! commonly used instances. use wardstone_core::primitive::symmetric::*; /// The Advanced Encryption Standard algorithm as defined in [FIPS 197]. /// /// [FIPS 197]: https://doi.org/10.6028/NIST.FIPS.197 #[no_mangle] pub static WS_AES128: Symmetric = AES128; /// The Advanced Encryption Standard algorithm as defined in [FIPS 197]. /// /// [FIPS 197]: https://doi.org/10.6028/NIST.FIPS.197 #[no_mangle] pub static WS_AES192: Symmetric = AES192; /// The Advanced Encryption Standard algorithm as defined in [FIPS 197]. /// /// [FIPS 197]: https://doi.org/10.6028/NIST.FIPS.197 #[no_mangle] pub static WS_AES256: Symmetric = AES256; /// The Camellia encryption algorithm as defined in [RFC 3713]. /// /// [RFC 3713]: https://datatracker.ietf.org/doc/html/rfc3713 #[no_mangle] pub static WS_CAMELLIA128: Symmetric = CAMELLIA128; /// The Camellia encryption algorithm as defined in [RFC 3713]. /// /// [RFC 3713]: https://datatracker.ietf.org/doc/html/rfc3713 #[no_mangle] pub static WS_CAMELLIA192: Symmetric = CAMELLIA192; /// The Camellia encryption algorithm as defined in [RFC 3713]. /// /// [RFC 3713]: https://datatracker.ietf.org/doc/html/rfc3713 #[no_mangle] pub static WS_CAMELLIA256: Symmetric = CAMELLIA256; /// The Data Encryption Standard algorithm. #[no_mangle] pub static WS_DES: Symmetric = DES; /// The DES-X encryption algorithm. #[no_mangle] pub static WS_DESX: Symmetric = DESX; /// The International Data Encryption algorithm. #[no_mangle] pub static WS_IDEA: Symmetric = IDEA; /// The Serpent encryption algorithm. #[no_mangle] pub static WS_SERPENT128: Symmetric = SERPENT128; /// The Serpent encryption algorithm. #[no_mangle] pub static WS_SERPENT192: Symmetric = SERPENT192; /// The Serpent encryption algorithm. #[no_mangle] pub static WS_SERPENT256: Symmetric = SERPENT256; /// The two-key Triple Data Encryption Algorithm as defined in /// [SP800-67]. /// /// [SP800-67]: https://doi.org/10.6028/NIST.SP.800-67r2 #[no_mangle] pub static WS_TDEA2: Symmetric = TDEA2; /// The three-key Triple Data Encryption Algorithm as defined in /// [SP800-67]. /// /// [SP800-67]: https://doi.org/10.6028/NIST.SP.800-67r2 #[no_mangle] pub static WS_TDEA3: Symmetric = TDEA3; 070701000000A9000041ED0000000000000000000000026537CEF400000000000000000000000000000000000000000000002B00000000wardstone-0.2.0~0/crates/ffi/src/standards070701000000AA000081A40000000000000000000000016537CEF4000002B7000000000000000000000000000000000000002E00000000wardstone-0.2.0~0/crates/ffi/src/standards.rs//! Submodules that validate cryptographic primitives according to //! selected standards and research publications. //! //! # Safety //! //! This module contains functions that use raw pointers as arguments //! for reading and writing data. However, this is only for the C API //! that is exposed to interact with safe Rust equivalents. The C API is //! essentially a wrapper around the Rust function to maintain //! consistency with existing conventions. //! //! Checks against null dereferences are made in which the function will //! return `-1` if the argument is required.pub mod bsi; pub mod bsi; pub mod cnsa; pub mod ecrypt; pub mod lenstra; pub mod nist; pub mod strong; pub mod weak; 070701000000AB000081A40000000000000000000000016537CEF400002122000000000000000000000000000000000000003200000000wardstone-0.2.0~0/crates/ffi/src/standards/bsi.rs//! Validate cryptographic primitives against the [BSI TR-02102-1 //! Cryptographic Mechanisms: Recommendations and Key Lengths] technical //! guide. //! //! [BSI TR-02102-1 Cryptographic Mechanisms: Recommendations and Key Lengths]: https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/TechGuidelines/TG02102/BSI-TR-02102-1.html use std::ffi::c_int; use wardstone_core::context::Context; use wardstone_core::primitive::ecc::Ecc; use wardstone_core::primitive::ffc::Ffc; use wardstone_core::primitive::hash::Hash; use wardstone_core::primitive::ifc::Ifc; use wardstone_core::primitive::symmetric::Symmetric; use wardstone_core::standard::bsi::Bsi; use wardstone_core::standard::Standard; use crate::utilities; /// Validate an elliptic curve cryptography primitive used for digital /// signatures and key establishment where f is the key size. /// /// If the key is not compliant then `ws_ecc*` will contain the /// recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher security /// level, `ws_ecc*` will also hold the recommended primitive with the /// desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. /// /// **Note:** While the guide allows for elliptic curve system /// parameters "that are provided by a trustworthy authority" /// (see p. 73), this function conservatively deems any curve that is /// not explicitly stated as non-compliant. This means only the /// Brainpool curves are considered compliant. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_bsi_validate_ecc( ctx: Context, key: Ecc, alternative: *mut Ecc, ) -> c_int { utilities::c_call(Bsi::validate_ecc, ctx, key, alternative) } /// Validates a finite field cryptography primitive. /// /// Examples include the DSA and key establishment algorithms such as /// Diffie-Hellman. /// /// If the key is not compliant then `struct ws_ffc*` will point to the /// recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher security /// level, `struct ws_ffc` will also point to the recommended primitive /// with the desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_bsi_validate_ffc( ctx: Context, key: Ffc, alternative: *mut Ffc, ) -> c_int { utilities::c_call(Bsi::validate_ffc, ctx, key, alternative) } /// Validates a hash function according to page 41 of the guide. The /// reference is made with regards to applications that require /// collision resistance such as digital signatures. /// /// For applications that primarily require pre-image resistance such as /// message authentication codes (MACs), key derivation functions /// (KDFs), and random bit generation use `ws_bsi_validate_hash_based`. /// /// If the hash function is not compliant then /// `struct ws_hash* alternative` will point to the recommended /// primitive that one should use instead. /// /// If the hash function is compliant but the context specifies a higher /// security level, `struct ws_hash*` will also point to the recommended /// primitive with the desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. /// /// **Caution:** Unlike the NIST standard, the guide does not make a /// distinction between security requirements based on usage. For /// example, collision resistance generally requires twice more the /// security that one would want if they only cared about pre-image /// resistance. As a result, this module does not have a corresponding /// `validate_hash_based` function and the recommendation returned may /// be overly conservative. /// /// **Note:** An alternative might be suggested for a compliant hash /// function with a similar security level in which a switch to the /// recommended primitive would likely be unwarranted. For example, when /// evaluating compliance for the `SHA3-256`, a recommendation to use /// `SHA256` will be made but switching to this as a result is likely /// unnecessary. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_bsi_validate_hash( ctx: Context, hash: Hash, alternative: *mut Hash, ) -> c_int { utilities::c_call(Bsi::validate_hash, ctx, hash, alternative) } /// Validates a hash function. The reference is made with regards to /// applications that primarily require pre-image resistance such as /// message authentication codes (MACs), key derivation functions /// (KDFs), and random bit generation. /// /// For applications that require collision resistance such digital /// signatures use `ws_bsi_validate_hash`. /// /// If the hash function is not compliant then /// `struct ws_hash* alternative` will point to the recommended /// primitive that one should use instead. /// /// If the hash function is compliant but the context specifies a higher /// security level, `struct ws_hash*` will also point to the recommended /// primitive with the desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. /// /// **Note:** For an HMAC the minimum security required is ≥ 128 (see /// p. 45) but the minimum digest length for a hash function that can be /// used with this primitive is 256 (see p. 41). This means any /// recommendation from this function will be likely too conservative. /// /// An alternative might also be suggested for a compliant hash /// functions with a similar security level in which a switch to the /// recommended primitive would likely be unwarranted. For example, when /// evaluating compliance for the `SHA3-256`, a recommendation to use /// `SHA256` will be made but switching to this as a result is likely /// unnecessary. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_bsi_validate_hash_based( ctx: Context, hash: Hash, alternative: *mut Hash, ) -> c_int { utilities::c_call(Bsi::validate_hash_based, ctx, hash, alternative) } /// Validates an integer factorisation cryptography primitive the most /// common of which is the RSA signature algorithm. /// /// If the key is not compliant then `ws_ifc*` will point to the /// recommended key size that one should use instead. /// /// If the key is compliant but the context specifies a higher security /// level, `ws_ifc*` will also point to the recommended key size with /// the desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. // /// **Note:** Unlike other functions in this module, this will return a /// generic structure that specifies minimum private and public key /// sizes. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_bsi_validate_ifc( ctx: Context, key: Ifc, alternative: *mut Ifc, ) -> c_int { utilities::c_call(Bsi::validate_ifc, ctx, key, alternative) } /// Validates a symmetric key primitive according to pages 24 of the /// guide. /// /// If the key is not compliant then `struct ws_symmetric* alternative` /// will point to the recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher security /// level, `struct ws_symmetric*` will also point to the recommended /// primitive with the desired security level. /// /// The function returns `1` if the key is compliant, `0` if it is not, /// and `-1` if an error occurs as a result of a missing or invalid /// argument. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_bsi_validate_symmetric( ctx: Context, key: Symmetric, alternative: *mut Symmetric, ) -> c_int { utilities::c_call(Bsi::validate_symmetric, ctx, key, alternative) } 070701000000AC000081A40000000000000000000000016537CEF4000015A8000000000000000000000000000000000000003300000000wardstone-0.2.0~0/crates/ffi/src/standards/cnsa.rs//! Validate cryptographic primitives against the Commercial National //! Security Algorithm Suites, [CNSA 1.0] and [CNSA 2.0]. //! //! [CNSA 1.0]: https://media.defense.gov/2021/Sep/27/2002862527/-1/-1/0/CNSS%20WORKSHEET.PDF //! [CNSA 2.0]: https://media.defense.gov/2022/Sep/07/2003071834/-1/-1/0/CSA_CNSA_2.0_ALGORITHMS_.PDF use std::ffi::c_int; use wardstone_core::context::Context; use wardstone_core::primitive::ecc::Ecc; use wardstone_core::primitive::ffc::Ffc; use wardstone_core::primitive::hash::Hash; use wardstone_core::primitive::ifc::Ifc; use wardstone_core::primitive::symmetric::Symmetric; use wardstone_core::standard::cnsa::Cnsa; use wardstone_core::standard::Standard; use crate::utilities; /// Validate an elliptic curve cryptography primitive used for digital /// signatures and key establishment. /// /// If the key is not compliant then `ws_ecc*` will contain the /// recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher security /// level, `ws_ecc*` will also hold the recommended primitive with the /// desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_cnsa_validate_ecc( ctx: Context, key: Ecc, alternative: *mut Ecc, ) -> c_int { utilities::c_call(Cnsa::validate_ecc, ctx, key, alternative) } /// Validates a finite field cryptography primitive function. /// /// Examples include the DSA and key establishment algorithms such as /// Diffie-Hellman and MQV which can also be implemented as such. /// /// This primitive is not supported by either version of the CNSA /// guidance. /// /// If the key is not compliant then `struct ws_ffc*` will point to the /// recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher security /// level, `struct ws_ffc` will also point to the recommended primitive /// with the desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_cnsa_validate_ffc( ctx: Context, key: Ffc, alternative: *mut Ffc, ) -> c_int { utilities::c_call(Cnsa::validate_ffc, ctx, key, alternative) } /// Validates a hash function. /// /// Unlike other functions in this module, there is no distinction in /// security based on the application. As such this module does not have /// a corresponding `validate_hash_based` function. All hash function /// and hash based application are assessed by this single function. /// /// If the hash function is not compliant then /// `struct ws_hash* alternative` will point to the recommended /// primitive that one should use instead. /// /// If the hash function is compliant but the context specifies a higher /// security level, `struct ws_hash*` will also point to the recommended /// primitive with the desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_cnsa_validate_hash( ctx: Context, hash: Hash, alternative: *mut Hash, ) -> c_int { utilities::c_call(Cnsa::validate_hash, ctx, hash, alternative) } /// Validates an integer factorisation cryptography primitive the most /// common of which is the RSA signature algorithm. /// /// If the key is not compliant then `ws_ifc*` will point to the /// recommended key size that one should use instead. /// /// If the key is compliant but the context specifies a higher security /// level, `ws_ifc*` will also point to the recommended key size with /// the desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. // /// **Note:** Unlike other functions in this module, this will return a /// generic structure that specifies minimum private and public key /// sizes. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_cnsa_validate_ifc( ctx: Context, key: Ifc, alternative: *mut Ifc, ) -> c_int { utilities::c_call(Cnsa::validate_ifc, ctx, key, alternative) } /// Validates a symmetric key primitive. /// /// If the key is not compliant then `struct ws_symmetric* alternative` /// will point to the recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher security /// level, `struct ws_symmetric*` will also point to the recommended /// primitive with the desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_cnsa_validate_symmetric( ctx: Context, key: Symmetric, alternative: *mut Symmetric, ) -> c_int { utilities::c_call(Cnsa::validate_symmetric, ctx, key, alternative) } 070701000000AD000081A40000000000000000000000016537CEF400001698000000000000000000000000000000000000003500000000wardstone-0.2.0~0/crates/ffi/src/standards/ecrypt.rs//! Validate cryptographic primitives against the [ECRYPT-CSA D5.4 //! Algorithms, Key Size and Protocols Report]. //! //! [ECRYPT-CSA D5.4 Algorithms, Key Size and Protocols Report]: https://www.ecrypt.eu.org/csa/documents/D5.4-FinalAlgKeySizeProt.pdf use std::ffi::c_int; use wardstone_core::context::Context; use wardstone_core::primitive::ecc::Ecc; use wardstone_core::primitive::ffc::Ffc; use wardstone_core::primitive::hash::Hash; use wardstone_core::primitive::ifc::Ifc; use wardstone_core::primitive::symmetric::Symmetric; use wardstone_core::standard::ecrypt::Ecrypt; use wardstone_core::standard::Standard; use crate::utilities; /// Validate an elliptic curve cryptography primitive used for digital /// signatures and key establishment where f is the key size according /// to page 47 of the report. /// /// If the key is not compliant then `ws_ecc*` will contain the /// recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher security /// level, `ws_ecc*` will also hold the recommended primitive with the /// desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. /// /// **Note:** This will return a generic structure that specifies key /// sizes. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_ecrypt_validate_ecc( ctx: Context, key: Ecc, alternative: *mut Ecc, ) -> c_int { utilities::c_call(Ecrypt::validate_ecc, ctx, key, alternative) } /// Validates a finite field cryptography primitive according to page 47 /// of the report. /// /// Examples include the DSA and key establishment algorithms such as /// Diffie-Hellman. /// /// If the key is not compliant then `struct ws_ffc*` will point to the /// recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher security /// level, `struct ws_ffc` will also point to the recommended primitive /// with the desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. /// /// **Note:** The choice of security specified in the `Context` is /// restricted to the values 160, 224, 256, 384, and 512. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_ecrypt_validate_ffc( ctx: Context, key: Ffc, alternative: *mut Ffc, ) -> c_int { utilities::c_call(Ecrypt::validate_ffc, ctx, key, alternative) } /// Validates a hash function according to pages 40-43 of the report. /// /// Unlike other functions in this module, there is no distinction in /// security based on the application. As such this module does not have /// a corresponding `validate_hash_based` function. All hash function /// and hash based application are assessed by this single function. /// /// If the hash function is not compliant then /// `struct ws_hash* alternative` will point to the recommended /// primitive that one should use instead. /// /// If the hash function is compliant but the context specifies a higher /// security level, `struct ws_hash*` will also point to the recommended /// primitive with the desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_ecrypt_validate_hash( ctx: Context, hash: Hash, alternative: *mut Hash, ) -> c_int { utilities::c_call(Ecrypt::validate_hash, ctx, hash, alternative) } /// Validates an integer factorisation cryptography primitive the most /// common of which is the RSA signature algorithm according to pages /// 47-48. /// /// If the key is not compliant then `ws_ifc*` will point to the /// recommended key size that one should use instead. /// /// If the key is compliant but the context specifies a higher security /// level, `ws_ifc*` will also point to the recommended key size with /// the desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. // /// **Note:** Unlike other functions in this module, this will return a /// generic structure that specifies minimum private and public key /// sizes. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_ecrypt_validate_ifc( ctx: Context, key: Ifc, alternative: *mut Ifc, ) -> c_int { utilities::c_call(Ecrypt::validate_ifc, ctx, key, alternative) } /// Validates a symmetric key primitive according to pages 37 to 40 of /// the report. /// /// If the key is not compliant then `struct ws_symmetric* alternative` /// will point to the recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher security /// level, `struct ws_symmetric*` will also point to the recommended /// primitive with the desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_ecrypt_validate_symmetric( ctx: Context, key: Symmetric, alternative: *mut Symmetric, ) -> c_int { utilities::c_call(Ecrypt::validate_symmetric, ctx, key, alternative) } 070701000000AE000081A40000000000000000000000016537CEF400001616000000000000000000000000000000000000003600000000wardstone-0.2.0~0/crates/ffi/src/standards/lenstra.rs//! Validate cryptographic primitives against the levels of security //! mentioned in the paper Key Lengths, Arjen K. Lenstra, The Handbook //! of Information Security, 06/2004. use std::ffi::c_int; use wardstone_core::context::Context; use wardstone_core::primitive::ecc::Ecc; use wardstone_core::primitive::ffc::Ffc; use wardstone_core::primitive::hash::Hash; use wardstone_core::primitive::ifc::Ifc; use wardstone_core::primitive::symmetric::Symmetric; use wardstone_core::standard::lenstra::Lenstra; use wardstone_core::standard::Standard; use crate::utilities; /// Validate an elliptic curve cryptography primitive used for digital /// signatures and key establishment where f is the key size. /// /// If the key is not compliant then `ws_ecc*` will contain the /// recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher security /// level, `ws_ecc*` will also hold the recommended primitive with the /// desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_lenstra_validate_ecc( ctx: Context, key: Ecc, alternative: *mut Ecc, ) -> c_int { utilities::c_call(Lenstra::validate_ecc, ctx, key, alternative) } /// Validates a finite field cryptography primitive function examples /// which include DSA and key establishment algorithms such as /// Diffie-Hellman and MQV. /// /// If the key is not compliant then `struct ws_ffc*` will point to the /// recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher security /// level, `struct ws_ffc` will also point to the recommended primitive /// with the desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. /// /// **Note:** Unlike other functions in this module, this will return a /// generic structure that specifies minimum private and public key /// sizes. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_lenstra_validate_ffc( ctx: Context, key: Ffc, alternative: *mut Ffc, ) -> c_int { utilities::c_call(Lenstra::validate_ffc, ctx, key, alternative) } /// Validates a hash function according to page 14 of the paper. /// /// If the hash function is not compliant then /// `struct ws_hash* alternative` will point to the recommended /// primitive that one should use instead. /// /// If the hash function is compliant but the context specifies a higher /// security level, `struct ws_hash*` will also point to the recommended /// primitive with the desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. /// /// **Note:** that this means an alternative might be suggested for a /// compliant hash functions with a similar security level in which a /// switch to the recommended primitive would likely be unwarranted. For /// example, when evaluating compliance for the `SHA3-256`, a /// recommendation to use `SHA256` will be made but this likely /// unnecessary. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_lenstra_validate_hash( ctx: Context, hash: Hash, alternative: *mut Hash, ) -> c_int { utilities::c_call(Lenstra::validate_hash, ctx, hash, alternative) } /// Validates an integer factorisation cryptography primitive the most /// common of which is the RSA signature algorithm based on pages 17-25. /// /// If the key is not compliant then `ws_ifc*` will point to the /// recommended key size that one should use instead. /// /// If the key is compliant but the context specifies a higher security /// level, `ws_ifc*` will also point to the recommended key size with /// the desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. // /// **Note:** Unlike other functions in this module, this will return a /// generic structure that specifies minimum private and public key /// sizes. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_lenstra_validate_ifc( ctx: Context, key: Ifc, alternative: *mut Ifc, ) -> c_int { utilities::c_call(Lenstra::validate_ifc, ctx, key, alternative) } /// Validates a symmetric key primitive according to pages 9-12 of the /// paper. /// /// If the key is not compliant then `struct ws_symmetric* alternative` /// will point to the recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher security /// level, `struct ws_symmetric*` will also point to the recommended /// primitive with the desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_lenstra_validate_symmetric( ctx: Context, key: Symmetric, alternative: *mut Symmetric, ) -> c_int { utilities::c_call(Lenstra::validate_symmetric, ctx, key, alternative) } 070701000000AF000081A40000000000000000000000016537CEF400001E21000000000000000000000000000000000000003300000000wardstone-0.2.0~0/crates/ffi/src/standards/nist.rs//! Validate cryptographic primitives against the [NIST Special //! Publication 800-57 Part 1 Revision 5 standard]. //! //! [NIST Special Publication 800-57 Part 1 Revision 5 standard]: https://doi.org/10.6028/NIST.SP.800-57pt1r5 use std::ffi::c_int; use wardstone_core::context::Context; use wardstone_core::primitive::ecc::Ecc; use wardstone_core::primitive::ffc::Ffc; use wardstone_core::primitive::hash::Hash; use wardstone_core::primitive::ifc::Ifc; use wardstone_core::primitive::symmetric::Symmetric; use wardstone_core::standard::nist::Nist; use wardstone_core::standard::Standard; use crate::utilities; /// Validate an elliptic curve cryptography primitive used for digital /// signatures and key establishment where f is the key size according /// to page 54-55 of the standard. /// /// If the key is not compliant then `ws_ecc*` will contain the /// recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher security /// level, `ws_ecc*` will also hold the recommended primitive with the /// desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_nist_validate_ecc( ctx: Context, key: Ecc, alternative: *mut Ecc, ) -> c_int { utilities::c_call(Nist::validate_ecc, ctx, key, alternative) } /// Validates a finite field cryptography primitive function examples /// which include DSA and key establishment algorithms such as /// Diffie-Hellman and MQV according to page 54-55 of the standard. /// /// If the key is not compliant then `struct ws_ffc*` will point to the /// recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher security /// level, `struct ws_ffc` will also point to the recommended primitive /// with the desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. /// /// **Note:** Unlike other functions in this module, this will return a /// generic structure that specifies minimum private and public key /// sizes. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_nist_validate_ffc( ctx: Context, key: Ffc, alternative: *mut Ffc, ) -> c_int { utilities::c_call(Nist::validate_ffc, ctx, key, alternative) } /// Validates an integer factorisation cryptography primitive the most /// common of which is the RSA signature algorithm where k indicates the /// key size according to page 54-55 of the standard. /// /// If the key is not compliant then `ws_ifc*` will point to the /// recommended key size that one should use instead. /// /// If the key is compliant but the context specifies a higher security /// level, `ws_ifc*` will also point to the recommended key size with /// the desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. // /// **Note:** Unlike other functions in this module, this will return a /// generic structure that specifies minimum private and public key /// sizes. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_nist_validate_ifc( ctx: Context, key: Ifc, alternative: *mut Ifc, ) -> c_int { utilities::c_call(Nist::validate_ifc, ctx, key, alternative) } /// Validates a hash function according to page 56 of the standard. The /// reference is made with regards to applications that require /// collision resistance such as digital signatures. /// /// For applications that primarily require pre-image resistance such as /// message authentication codes (MACs), key derivation functions /// (KDFs), and random bit generation use `ws_nist_validate_hash_based`. /// /// If the hash function is not compliant then /// `struct ws_hash* alternative` will point to the recommended /// primitive that one should use instead. /// /// If the hash function is compliant but the context specifies a higher /// security level, `struct ws_hash*` will also point to the recommended /// primitive with the desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. /// /// **Note:** that this means an alternative might be suggested for a /// compliant hash functions with a similar security level in which a /// switch to the recommended primitive would likely be unwarranted. For /// example, when evaluating compliance for the `SHA3-256`, a /// recommendation to use `SHA256` will be made but this likely /// unnecessary. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_nist_validate_hash( ctx: Context, hash: Hash, alternative: *mut Hash, ) -> c_int { utilities::c_call(Nist::validate_hash, ctx, hash, alternative) } /// Validates a hash function according to page 56 of the standard. The /// reference is made with regards to applications that primarily /// require pre-image resistance such as message authentication codes /// (MACs), key derivation functions (KDFs), and random bit generation. /// /// For applications that require collision resistance such digital /// signatures use `ws_nist_validate_hash`. /// /// If the hash function is not compliant then /// `struct ws_hash* alternative` will point to the recommended /// primitive that one should use instead. /// /// If the hash function is compliant but the context specifies a higher /// security level, `struct ws_hash*` will also point to the recommended /// primitive with the desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. /// /// **Note:** that this means an alternative might be suggested for a /// compliant hash functions with a similar security level in which a /// switch to the recommended primitive would likely be unwarranted. For /// example, when evaluating compliance for the `SHA3-256`, a /// recommendation to use `SHA256` will be made but this likely /// unnecessary. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_nist_validate_hash_based( ctx: Context, hash: Hash, alternative: *mut Hash, ) -> c_int { utilities::c_call(Nist::validate_hash_based, ctx, hash, alternative) } /// Validates a symmetric key primitive according to pages 54-55 of the /// standard. /// /// If the key is not compliant then `struct ws_symmetric* alternative` /// will point to the recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher security /// level, `struct ws_symmetric*` will also point to the recommended /// primitive with the desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_nist_validate_symmetric( ctx: Context, key: Symmetric, alternative: *mut Symmetric, ) -> c_int { utilities::c_call(Nist::validate_symmetric, ctx, key, alternative) } 070701000000B0000081A40000000000000000000000016537CEF4000015EB000000000000000000000000000000000000003500000000wardstone-0.2.0~0/crates/ffi/src/standards/strong.rs//! A mock standard with a minimum security requirement of at least //! 256-bits. //! //! This is the level of security estimated to be enough to resist an //! attack using Grover's algorithm enabled by quantum computers which //! as of writing does not appear to be a practical concern. However, //! bumping the security parameter may not be enough for some signature //! schemes such as those that use elliptic curves. use std::ffi::c_int; use wardstone_core::context::Context; use wardstone_core::primitive::ecc::Ecc; use wardstone_core::primitive::ffc::Ffc; use wardstone_core::primitive::hash::Hash; use wardstone_core::primitive::ifc::Ifc; use wardstone_core::primitive::symmetric::Symmetric; use wardstone_core::standard::testing::strong::Strong; use wardstone_core::standard::Standard; use crate::utilities; /// Validate an elliptic curve cryptography primitive. /// /// If the key is not compliant then `ws_ecc*` will contain the /// recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher security /// level, `ws_ecc*` will also hold the recommended primitive with the /// desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_strong_validate_ecc( ctx: Context, key: Ecc, alternative: *mut Ecc, ) -> c_int { utilities::c_call(Strong::validate_ecc, ctx, key, alternative) } /// Validates a finite field cryptography primitive. /// /// If the key is not compliant then `struct ws_ffc*` will point to the /// recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher security /// level, `struct ws_ffc` will also point to the recommended primitive /// with the desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. /// /// **Note:** Unlike other functions in this module, this will return a /// generic structure that specifies minimum private and public key /// sizes. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_strong_validate_ffc( ctx: Context, key: Ffc, alternative: *mut Ffc, ) -> c_int { utilities::c_call(Strong::validate_ffc, ctx, key, alternative) } /// Validates an integer factorisation cryptography primitive the /// most common of which is the RSA signature algorithm. /// /// If the key is not compliant then `ws_ifc*` will point to the /// recommended key size that one should use instead. /// /// If the key is compliant but the context specifies a higher security /// level, `ws_ifc*` will also point to the recommended key size with /// the desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. // /// **Note:** Unlike other functions in this module, this will return a /// generic structure that specifies minimum private and public key /// sizes. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_strong_validate_ifc( ctx: Context, key: Ifc, alternative: *mut Ifc, ) -> c_int { utilities::c_call(Strong::validate_ifc, ctx, key, alternative) } /// Validates a hash function. /// /// If the hash function is not compliant then /// `struct ws_hash* alternative` will point to the recommended /// primitive that one should use instead. /// /// If the hash function is compliant but the context specifies a higher /// security level, `struct ws_hash*` will also point to the recommended /// primitive with the desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. /// /// **Note:** that this means an alternative might be suggested for a /// compliant hash functions with a similar security level in which a /// switch to the recommended primitive would likely be unwarranted. For /// example, when evaluating compliance for the `SHA3-256`, a /// recommendation to use `SHA256` will be made but this likely /// unnecessary. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_strong_validate_hash( ctx: Context, hash: Hash, alternative: *mut Hash, ) -> c_int { utilities::c_call(Strong::validate_hash, ctx, hash, alternative) } /// Validates a symmetric key primitive. /// /// If the key is not compliant then `struct ws_symmetric* alternative` /// will point to the recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher security /// level, `struct ws_symmetric*` will also point to the recommended /// primitive with the desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_strong_validate_symmetric( ctx: Context, key: Symmetric, alternative: *mut Symmetric, ) -> c_int { utilities::c_call(Strong::validate_symmetric, ctx, key, alternative) } 070701000000B1000081A40000000000000000000000016537CEF40000156F000000000000000000000000000000000000003300000000wardstone-0.2.0~0/crates/ffi/src/standards/weak.rs//! A mock standard with a minimum security requirement of at least //! 64-bits. //! //! **Caution:** This might return recommendations for primitives that //! are considered unsafe when used in some applications such as MD5 and //! SHA1. For secure applications use any of the other standards defined //! in this crate. use std::ffi::c_int; use wardstone_core::context::Context; use wardstone_core::primitive::ecc::Ecc; use wardstone_core::primitive::ffc::Ffc; use wardstone_core::primitive::hash::Hash; use wardstone_core::primitive::ifc::Ifc; use wardstone_core::primitive::symmetric::Symmetric; use wardstone_core::standard::testing::weak::Weak; use wardstone_core::standard::Standard; use crate::utilities; /// Validate an elliptic curve cryptography primitive. /// /// If the key is not compliant then `ws_ecc*` will contain the /// recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher security /// level, `ws_ecc*` will also hold the recommended primitive with the /// desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_weak_validate_ecc( ctx: Context, key: Ecc, alternative: *mut Ecc, ) -> c_int { utilities::c_call(Weak::validate_ecc, ctx, key, alternative) } /// Validates a finite field cryptography primitive. /// /// If the key is not compliant then `struct ws_ffc*` will point to the /// recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher security /// level, `struct ws_ffc` will also point to the recommended primitive /// with the desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. /// /// **Note:** Unlike other functions in this module, this will return a /// generic structure that specifies minimum private and public key /// sizes. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_weak_validate_ffc( ctx: Context, key: Ffc, alternative: *mut Ffc, ) -> c_int { utilities::c_call(Weak::validate_ffc, ctx, key, alternative) } /// Validates an integer factorisation cryptography primitive the /// most common of which is the RSA signature algorithm. /// /// If the key is not compliant then `ws_ifc*` will point to the /// recommended key size that one should use instead. /// /// If the key is compliant but the context specifies a higher security /// level, `ws_ifc*` will also point to the recommended key size with /// the desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. // /// **Note:** Unlike other functions in this module, this will return a /// generic structure that specifies minimum private and public key /// sizes. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_weak_validate_ifc( ctx: Context, key: Ifc, alternative: *mut Ifc, ) -> c_int { utilities::c_call(Weak::validate_ifc, ctx, key, alternative) } /// Validates a hash function. /// /// If the hash function is not compliant then /// `struct ws_hash* alternative` will point to the recommended /// primitive that one should use instead. /// /// If the hash function is compliant but the context specifies a higher /// security level, `struct ws_hash*` will also point to the recommended /// primitive with the desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. /// /// **Note:** that this means an alternative might be suggested for a /// compliant hash functions with a similar security level in which a /// switch to the recommended primitive would likely be unwarranted. For /// example, when evaluating compliance for the `SHA3-256`, a /// recommendation to use `SHA256` will be made but this likely /// unnecessary. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_weak_validate_hash( ctx: Context, hash: Hash, alternative: *mut Hash, ) -> c_int { utilities::c_call(Weak::validate_hash, ctx, hash, alternative) } /// Validates a symmetric key primitive. /// /// If the key is not compliant then `struct ws_symmetric* alternative` /// will point to the recommended primitive that one should use instead. /// /// If the key is compliant but the context specifies a higher security /// level, `struct ws_symmetric*` will also point to the recommended /// primitive with the desired security level. /// /// The function returns `1` if the hash function is compliant, `0` if /// it is not, and `-1` if an error occurs as a result of a missing or /// invalid argument. /// /// # Safety /// /// See crate documentation for comment on safety. #[no_mangle] pub unsafe extern "C" fn ws_weak_validate_symmetric( ctx: Context, key: Symmetric, alternative: *mut Symmetric, ) -> c_int { utilities::c_call(Weak::validate_symmetric, ctx, key, alternative) } 070701000000B2000081A40000000000000000000000016537CEF400000258000000000000000000000000000000000000002E00000000wardstone-0.2.0~0/crates/ffi/src/utilities.rsuse std::ffi::c_int; use wardstone_core::context::Context; /// A utility function that abstracts a call to a Rust function `f` and /// returns a result following C error handling conventions. pub(crate) unsafe fn c_call<T>( f: fn(Context, T) -> Result<T, T>, ctx: Context, primitive: T, alternative: *mut T, ) -> c_int { let (recommendation, is_compliant) = match f(ctx, primitive) { Ok(recommendation) => (recommendation, true), Err(recommendation) => (recommendation, false), }; if !alternative.is_null() { *alternative = recommendation; } is_compliant as c_int } 070701000000B3000041ED0000000000000000000000026537CEF400000000000000000000000000000000000000000000001B00000000wardstone-0.2.0~0/examples070701000000B4000041ED0000000000000000000000026537CEF400000000000000000000000000000000000000000000001F00000000wardstone-0.2.0~0/examples/ffi070701000000B5000081A40000000000000000000000016537CEF400000026000000000000000000000000000000000000002D00000000wardstone-0.2.0~0/examples/ffi/.clang-formatColumnLimit: 0 PointerAlignment: Left 070701000000B6000081A40000000000000000000000016537CEF4000001AE000000000000000000000000000000000000002A00000000wardstone-0.2.0~0/examples/ffi/.gitignore# Prerequisites *.d # Object files *.o *.ko *.obj *.elf # Linker output *.ilk *.map *.exp # Precompiled Headers *.gch *.pch # Libraries *.lib *.a *.la *.lo # Shared objects (inc. Windows DLLs) *.dll *.so *.so.* *.dylib # Executables *.exe *.out *.app *.i*86 *.x86_64 *.hex # Debug files *.dSYM/ *.su *.idb *.pdb # Kernel Module Compile Results *.mod* *.cmd .tmp_versions/ modules.order Module.symvers Mkfile.old dkms.conf 070701000000B7000081A40000000000000000000000016537CEF4000002A3000000000000000000000000000000000000002900000000wardstone-0.2.0~0/examples/ffi/README.md# `ffi` The following in an example of how to call the `wardstone` Rust library from C. ## Instructions First compile the Rust library and generate the bindings using the following. ```bash cargo build --release ``` The static library and associated header file will be placed in the `target` directory in the root directory of this repository. Finally, compile the C example and run it using the following commands in the current directory. This assumes you are on a Unix system. ```bash cc -I ../../target/ ./main.c ../../target/release/libwardstone.a ./a.out ``` If everything went well, the assertions should pass silently and the program output should be empty. 070701000000B8000081A40000000000000000000000016537CEF400000205000000000000000000000000000000000000002600000000wardstone-0.2.0~0/examples/ffi/main.c#include "wardstone.h" #include <assert.h> #include <stdbool.h> #include <stdint.h> #include <string.h> int main(void) { struct ws_hash got; memset(&got, 0, sizeof(struct ws_hash)); struct ws_hash want = WS_SHA224; struct ws_context ctx = ws_context_default(); assert(ws_nist_validate_hash(ctx, WS_SHA1, &got) == false && "SHA1 should fail"); assert(got.id == want.id && "unexpected hash function recommendation"); assert(ws_nist_validate_hash(ctx, WS_SHA256, NULL) == true && "SHA256 should pass"); } 070701000000B9000081A40000000000000000000000016537CEF400000062000000000000000000000000000000000000001F00000000wardstone-0.2.0~0/rustfmt.tomledition = "2021" match_block_trailing_comma = true tab_spaces = 2 use_field_init_shorthand = true 070701000000BA000041ED0000000000000000000000026537CEF400000000000000000000000000000000000000000000001A00000000wardstone-0.2.0~0/scripts070701000000BB000081ED0000000000000000000000016537CEF4000012F3000000000000000000000000000000000000003300000000wardstone-0.2.0~0/scripts/generate_certificates.py#!/usr/bin/env python3 """Generates test X.509 certificates encoded in PEM using OpenSSL.""" import argparse import asyncio import itertools import logging import os import re import shutil import subprocess import sys from dataclasses import dataclass from pathlib import Path @dataclass class Opts: """ OpenSSL command line arguments to generate private keys and corresponding certificates. """ alg: str name: str pkeyopt: str def _dsa_opts(): bits = ((1024, 160), (2048, 224), (3072, 256)) return ( Opts("dsa", f"dsa_{p}", f"dsa_paramgen_bits:{p} dsa_paramgen_q_bits:{q}") for (p, q) in bits ) def _ec_opts(): output = subprocess.check_output( ["openssl", "ecparam", "-list_curves"], universal_newlines=True ) names = re.findall(r"(.+):", output) names = [name.strip() for name in names] return (Opts("ec", f"ecc_{name}", f"ec_paramgen_curve:{name}") for name in names) def _edwards_opts(): names = ("ed25519", "ed448") return (Opts(name, f"ecc_{name}", "") for name in names) def _rsa_opts(): # Sizes larger than 8192 take a while to generate. n = 4 min_bits = 1024 return ( Opts("rsa", f"ifc_rsa_{min_bits << i}", f"rsa_keygen_bits:{min_bits << i}") for i in range(n) ) def _rsa_pss_opts(): # Sizes larger than 8192 take a while to generate. n = 4 min_bits = 1024 return ( Opts( "rsa-pss", f"ifc_rsa_pss_{min_bits << i}", f"rsa_keygen_bits:{min_bits << i}", ) for i in range(n) ) async def generate_certificate(certificates, keys, opt): """ Generate a single X.509 certificate using OpenSSL asynchronously. Args: opt: An Opts object containing certificate generation options. The function generates a single X.509 certificate with the specified options and saves it in the "certificates" directory. The private key is saved in the "keys" directory. An existing key is skipped, and only new certificates are generated. The function logs the progress and any errors during the generation process. Returns: None """ filename = f"{opt.name}.pem" if (certificates / filename).exists(): logging.debug(f"skipping: {filename}") return try: logging.info(f"generating certificate: {filename}") command = [ "openssl", "req", "-x509", "-newkey", opt.alg, "-keyout", keys / filename, "-out", certificates / filename, "-subj", "/CN=Test Common Name/O=Test Organization Name", "-nodes", ] if opt.pkeyopt: command.extend(["-pkeyopt", opt.pkeyopt]) proc = await asyncio.create_subprocess_exec( *command, stderr=asyncio.subprocess.DEVNULL ) await proc.communicate() if proc.returncode: logging.warning(f"failed to generate certificate: {filename}") except subprocess.SubprocessError: logging.warning(f"failed to generate certificate: {filename}") async def main(): parser = argparse.ArgumentParser( prog="generate_certificates", description="Generate test X.509 certificates encoded in PEM using OpenSSL.", ) parser.add_argument( "-p", "--path", default="../crates/cmd/src/testing/", help="Path to put the generated artifacts", ) parser.add_argument( "-l", "--log-level", choices=["debug", "info", "warning", "error", "critical"], default="warning", help="Set the logging level (default: warning)", ) arguments = parser.parse_args() numeric_level = getattr(logging, arguments.log_level.upper(), None) if not isinstance(numeric_level, int): raise ValueError(f"invalid log level: {arguments.log_level}") logging.basicConfig(format="%(levelname)s: %(message)s", level=numeric_level) testing_dir = Path(arguments.path) if not testing_dir.is_dir(): print( f"{parser.prog}: path supplied should be a directory: {testing_dir}", file=sys.stderr, ) quit(1) dirs = (testing_dir / Path("certificates"), testing_dir / Path("keys")) certificates, keys = dirs for dir in dirs: os.makedirs(dir, exist_ok=True) opts = itertools.chain( _dsa_opts(), _ec_opts(), _edwards_opts(), _rsa_opts(), _rsa_pss_opts(), ) tasks = (generate_certificate(certificates, keys, opt) for opt in opts) await asyncio.gather(*tasks) logging.debug("deleting test private keys") shutil.rmtree(keys) if __name__ == "__main__": asyncio.run(main()) 07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000B00000000TRAILER!!!780 blocks
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor