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`

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

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