chore: checkpoint before Python removal

This commit is contained in:
2026-03-26 22:33:59 +00:00
parent 683cec9307
commit e568ddf82a
29972 changed files with 11269302 additions and 2 deletions

1
vendor/pkcs1/.cargo-checksum.json vendored Normal file
View File

@@ -0,0 +1 @@
{"files":{".cargo_vcs_info.json":"8f4973e9559b4d22181cbaca5f27c687ba14c4dde06319665208821ff9a2c067","CHANGELOG.md":"7b6de36b99e3359f7c55a77ca4d94dec6f25e7b55e522e5559fc6fa028fc0286","Cargo.toml":"f36a724895555cc811c9ad7c098661ff1576d039f75a4755c960a132da9f8f19","Cargo.toml.orig":"8bc2254fac5c61269cd36701d7bde11bbbf849c2d3cc3e7214e7a5f490129dcd","LICENSE-APACHE":"a9040321c3712d8fd0b09cf52b17445de04a23a10165049ae187cd39e5c86be5","LICENSE-MIT":"c995204cc6bad2ed67dd41f7d89bb9f1a9d48e0edd745732b30640d7912089a4","README.md":"96072ae2126dbbe8882335864ed80e7530914b265680a7ce7d47bbe832f07378","src/error.rs":"193ee9bcd92c91c7290e07e7c419a192e6306b77b8f9559e88d1e01cf2ffde9f","src/lib.rs":"19c061ff24e546c74db8f1368017508715bfa585aaa37e4fd59a1d2f90979a91","src/params.rs":"3c0582fa3827eae4c5a5d355be098329be366b26caaf5f8d641007c073fd9b0e","src/private_key.rs":"ceec5c850e9ba207b5796ccc62901136400550a018ae39582fd06d26f196dad9","src/private_key/other_prime_info.rs":"be3d73f51d439350956b0a6106f6e8751bc9460e1c98f6ac95240c8b7ad6c523","src/public_key.rs":"a747ab701b392c7c147906eefbf21387fc5b2d9dff958de98bd454bdb991f2c9","src/traits.rs":"7c1d6227aa9298df49e9e22b7e8640adcdaa913bf8a17e25ab9701afd4f0d051","src/version.rs":"f7e00c942fffbfc755427ecebbb93c33648d9517c4758badb3da85ff002aea8a","tests/examples/rsa2048-priv-3prime.der":"1ec54d0f9a3b360e7f4ac3f8f89ad00c0f4e44f2072aa924e2b3b9b739409141","tests/examples/rsa2048-priv-3prime.pem":"1f147cc046c3b7b6e227eb352f7e99b23a0c60c241f11d2ebeaf1cfc1ed1148c","tests/examples/rsa2048-priv.der":"f94b60300e4877e863b2bea8d5c366a90432794454c05e0ec098ddbf96263614","tests/examples/rsa2048-priv.pem":"026c0bc90e1d06dc828a90dc4fcfb29d5b4cd0eeb93123047035804092569086","tests/examples/rsa2048-pub.der":"53ad7f462c0329c639a9cd44e0f57f99713c92abe84d39a70b2cb6e0c4186aab","tests/examples/rsa2048-pub.pem":"f52a1bcae2af19cd7964f8048e32ee1f1103315952d9d98c9a5fedcf91f6812d","tests/examples/rsa4096-priv.der":"739ddd3697b6aa82ae5753663a62c0f21136d8528781261731c932f53a061ffe","tests/examples/rsa4096-priv.pem":"db7cd9d48e60b513cd322dc6fd8b679514d1f725637294fd44a61cd971067f0c","tests/examples/rsa4096-pub.der":"2a1198a8542f615eeb803d6b0a7c6fcc426f8e783ebf0ebb2baf1344996f0782","tests/examples/rsa4096-pub.pem":"4469bbb4747c1036f672078a11d74cda3aafe0c6dd2c454a242c7ae94d7da0d0","tests/params.rs":"543851f1224654fef289e7ae12fbb63337a8c0a6add31bba5648ab06279afb1f","tests/private_key.rs":"ea4a3e2a8bf4ad2e7349d6e095bf034931fc60498f3f2573936275390fdbdd20","tests/public_key.rs":"d8abb3fac083a23dd9b4642ffd48222c57d8ce692ceaa3024a2b24bdcc2f15d5","tests/traits.rs":"53a8e3bf7a6a53ef3ded4d8647eff65c482f5de79ad97c569ab831a99b34879b"},"package":"c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f"}

6
vendor/pkcs1/.cargo_vcs_info.json vendored Normal file
View File

@@ -0,0 +1,6 @@
{
"git": {
"sha1": "750ae946d284810f582a9c9ad428549561b1ee03"
},
"path_in_vcs": "pkcs1"
}

160
vendor/pkcs1/CHANGELOG.md vendored Normal file
View File

@@ -0,0 +1,160 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## 0.7.5 (2023-04-24)
### Fixed
- Import failure ([#1021])
[#1021]: https://github.com/RustCrypto/formats/pull/1021
## 0.7.4 (2023-04-21)
### Changed
- Have `alloc` feature only weakly activate `pkcs8?/alloc` ([#1013])
- Have `pem` feature only weakly activate `pkcs8?/pem` ([#1013])
[#1013]: https://github.com/RustCrypto/formats/pull/1013
## 0.7.3 (2023-04-18)
### Added
- Provide functions to construct `RsaPss` and `RsaOaepParams` ([#1010])
### Changed
- Use `NULL` parameters for SHA `AlgorithmIdentifier`s ([#1010])
[#1010]: https://github.com/RustCrypto/formats/pull/1010
## 0.7.2 (2023-04-04)
### Added
- `RsaPssParams::SALT_LEN_DEFAULT` ([#953])
[#953]: https://github.com/RustCrypto/formats/pull/953
## 0.7.1 (2023-03-05)
### Fixed
- `DecodeRsaPublicKey` blanket impl ([#916])
[#916]: https://github.com/RustCrypto/formats/pull/916
## 0.7.0 (2023-02-26) [YANKED]
### Changed
- Make PSS/OAEP params use generic `AlgorithmIdentifier` ([#799])
- Bump `der` dependency to v0.7 ([#899])
- Bump `spki` dependency to v0.7 ([#900])
- Bump `pkcs8` to v0.10 ([#902])
[#799]: https://github.com/RustCrypto/formats/pull/799
[#899]: https://github.com/RustCrypto/formats/pull/899
[#900]: https://github.com/RustCrypto/formats/pull/900
[#902]: https://github.com/RustCrypto/formats/pull/902
## 0.6.0 (Skipped)
- Skipped to synchronize version number with `der` and `spki`
## 0.5.0 (Skipped)
- Skipped to synchronize version number with `der` and `spki`
## 0.4.1 (2022-10-10)
### Added
- `RsaPssParams` support ([#698])
- `RsaOaepParams` support ([#733])
[#698]: https://github.com/RustCrypto/formats/pull/698
[#733]: https://github.com/RustCrypto/formats/pull/733
## 0.4.0 (2022-05-08)
### Changed
- Replace document types with `doc::{Document, SecretDocument}` types ([#571])
- Bump `der` to v0.6 ([#653])
- Bump `pkcs8` to v0.9 ([#656])
[#571]: https://github.com/RustCrypto/formats/pull/571
[#653]: https://github.com/RustCrypto/formats/pull/653
[#656]: https://github.com/RustCrypto/formats/pull/656
## 0.3.3 (2022-01-16)
### Added
- Error conversion support to `pkcs8::spki::Error` ([#333])
[#333]: https://github.com/RustCrypto/formats/pull/331
## 0.3.2 (2022-01-16)
### Added
- Error conversion support to `pkcs8::Error` ([#331])
[#331]: https://github.com/RustCrypto/formats/pull/331
## 0.3.1 (2021-11-29)
### Changed
- Use `finish_non_exhaustive` in Debug impls ([#245])
[#245]: https://github.com/RustCrypto/formats/pull/245
## 0.3.0 (2021-11-17)
### Added
- Support for multi-prime RSA keys ([#115])
- `pkcs8` feature ([#227], [#233])
### Changed
- Rename `From/ToRsa*Key` => `DecodeRsa*Key`/`EncodeRsa*Key` ([#120])
- Use `der::Document` to impl `RsaPrivateKeyDocument` ([#131])
- Rust 2021 edition upgrade; MSRV 1.56 ([#136])
- Make `RsaPrivateKey::version` implicit ([#188])
- Bump `der` crate dependency to v0.5 ([#222])
- Activate `pkcs8/pem` when `pem` feature is enabled ([#232])
### Removed
- `*_with_le` PEM encoding methods ([#109])
- I/O related errors ([#158])
[#109]: https://github.com/RustCrypto/formats/pull/109
[#115]: https://github.com/RustCrypto/formats/pull/115
[#120]: https://github.com/RustCrypto/formats/pull/120
[#131]: https://github.com/RustCrypto/formats/pull/131
[#136]: https://github.com/RustCrypto/formats/pull/136
[#158]: https://github.com/RustCrypto/formats/pull/158
[#188]: https://github.com/RustCrypto/formats/pull/188
[#222]: https://github.com/RustCrypto/formats/pull/222
[#227]: https://github.com/RustCrypto/formats/pull/227
[#232]: https://github.com/RustCrypto/formats/pull/232
[#233]: https://github.com/RustCrypto/formats/pull/233
## 0.2.4 (2021-09-14)
### Changed
- Moved to `formats` repo ([#2])
[#2]: https://github.com/RustCrypto/formats/pull/2
## 0.2.3 (2021-07-26)
### Added
- Support for customizing PEM `LineEnding`
### Changed
- Bump `pem-rfc7468` dependency to v0.2
## 0.2.2 (2021-07-25)
### Fixed
- `Version` encoder
## 0.2.1 (2021-07-25)
### Added
- `Error::Crypto` variant
## 0.2.0 (2021-07-25)
### Added
- `From*`/`To*` traits for `RsaPrivateKey`/`RsaPublicKey`
### Changed
- Use `FromRsa*`/`ToRsa*` traits with `*Document` types
## 0.1.1 (2021-07-24)
### Added
- Re-export `der` crate and `der::UIntBytes`
### Changed
- Replace `Error::{Decode, Encode}` with `Error::Asn1`
## 0.1.0 (2021-07-24) [YANKED]
- Initial release

84
vendor/pkcs1/Cargo.toml vendored Normal file
View File

@@ -0,0 +1,84 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies.
#
# If you are reading this file be aware that the original Cargo.toml
# will likely look very different (and much more reasonable).
# See Cargo.toml.orig for the original contents.
[package]
edition = "2021"
rust-version = "1.60"
name = "pkcs1"
version = "0.7.5"
authors = ["RustCrypto Developers"]
description = """
Pure Rust implementation of Public-Key Cryptography Standards (PKCS) #1:
RSA Cryptography Specifications Version 2.2 (RFC 8017)
"""
readme = "README.md"
keywords = [
"crypto",
"key",
"pem",
"pkcs",
"rsa",
]
categories = [
"cryptography",
"data-structures",
"encoding",
"no-std",
"parser-implementations",
]
license = "Apache-2.0 OR MIT"
repository = "https://github.com/RustCrypto/formats/tree/master/pkcs1"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = [
"--cfg",
"docsrs",
]
[dependencies.der]
version = "0.7"
features = ["oid"]
[dependencies.pkcs8]
version = "0.10"
optional = true
default-features = false
[dependencies.spki]
version = "0.7"
[dev-dependencies.const-oid]
version = "0.9"
features = ["db"]
[dev-dependencies.hex-literal]
version = "0.4"
[dev-dependencies.tempfile]
version = "3"
[features]
alloc = [
"der/alloc",
"zeroize",
"pkcs8?/alloc",
]
pem = [
"alloc",
"der/pem",
"pkcs8?/pem",
]
std = [
"der/std",
"alloc",
]
zeroize = ["der/zeroize"]

201
vendor/pkcs1/LICENSE-APACHE vendored Normal file
View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

25
vendor/pkcs1/LICENSE-MIT vendored Normal file
View File

@@ -0,0 +1,25 @@
Copyright (c) 2021-2023 The RustCrypto Project Developers
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

70
vendor/pkcs1/README.md vendored Normal file
View File

@@ -0,0 +1,70 @@
# [RustCrypto]: PKCS#1 (RSA)
[![crate][crate-image]][crate-link]
[![Docs][docs-image]][docs-link]
[![Build Status][build-image]][build-link]
![Apache2/MIT licensed][license-image]
![Rust Version][rustc-image]
[![Project Chat][chat-image]][chat-link]
Pure Rust implementation of Public-Key Cryptography Standards (PKCS) #1:
RSA Cryptography Specifications Version 2.2 ([RFC 8017]).
[Documentation][docs-link]
## About
This crate supports encoding and decoding RSA private and public keys
in either PKCS#1 DER (binary) or PEM (text) formats.
PEM encoded RSA private keys begin with:
```text
-----BEGIN RSA PRIVATE KEY-----
```
PEM encoded RSA public keys begin with:
```text
-----BEGIN RSA PUBLIC KEY-----
```
## Minimum Supported Rust Version
This crate requires **Rust 1.65** at a minimum.
We may change the MSRV in the future, but it will be accompanied by a minor
version bump.
## License
Licensed under either of:
* [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
* [MIT license](http://opensource.org/licenses/MIT)
at your option.
### Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.
[//]: # (badges)
[crate-image]: https://buildstats.info/crate/pkcs1
[crate-link]: https://crates.io/crates/pkcs1
[docs-image]: https://docs.rs/pkcs1/badge.svg
[docs-link]: https://docs.rs/pkcs1/
[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg
[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg
[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg
[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/300570-formats
[build-image]: https://github.com/RustCrypto/formats/workflows/pkcs1/badge.svg?branch=master&event=push
[build-link]: https://github.com/RustCrypto/formats/actions
[//]: # (links)
[RustCrypto]: https://github.com/rustcrypto
[RFC 8017]: https://datatracker.ietf.org/doc/html/rfc8017

95
vendor/pkcs1/src/error.rs vendored Normal file
View File

@@ -0,0 +1,95 @@
//! Error types
use core::fmt;
#[cfg(feature = "pem")]
use der::pem;
/// Result type
pub type Result<T> = core::result::Result<T, Error>;
/// Error type
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum Error {
/// ASN.1 DER-related errors.
Asn1(der::Error),
/// Cryptographic errors.
///
/// These can be used by RSA implementations to signal that a key is
/// invalid for cryptographic reasons. This means the document parsed
/// correctly, but one of the values contained within was invalid, e.g.
/// a number expected to be a prime was not a prime.
Crypto,
/// PKCS#8 errors.
#[cfg(feature = "pkcs8")]
Pkcs8(pkcs8::Error),
/// Version errors
Version,
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::Asn1(err) => write!(f, "PKCS#1 ASN.1 error: {}", err),
Error::Crypto => f.write_str("PKCS#1 cryptographic error"),
#[cfg(feature = "pkcs8")]
Error::Pkcs8(err) => write!(f, "{}", err),
Error::Version => f.write_str("PKCS#1 version error"),
}
}
}
impl From<der::Error> for Error {
fn from(err: der::Error) -> Error {
Error::Asn1(err)
}
}
#[cfg(feature = "pem")]
impl From<pem::Error> for Error {
fn from(err: pem::Error) -> Error {
der::Error::from(err).into()
}
}
#[cfg(feature = "pkcs8")]
impl From<Error> for pkcs8::Error {
fn from(err: Error) -> pkcs8::Error {
match err {
Error::Asn1(e) => pkcs8::Error::Asn1(e),
Error::Crypto | Error::Version => pkcs8::Error::KeyMalformed,
Error::Pkcs8(e) => e,
}
}
}
#[cfg(feature = "pkcs8")]
impl From<pkcs8::Error> for Error {
fn from(err: pkcs8::Error) -> Error {
Error::Pkcs8(err)
}
}
#[cfg(feature = "pkcs8")]
impl From<Error> for pkcs8::spki::Error {
fn from(err: Error) -> pkcs8::spki::Error {
match err {
Error::Asn1(e) => pkcs8::spki::Error::Asn1(e),
_ => pkcs8::spki::Error::KeyMalformed,
}
}
}
#[cfg(feature = "pkcs8")]
impl From<pkcs8::spki::Error> for Error {
fn from(err: pkcs8::spki::Error) -> Error {
Error::Pkcs8(pkcs8::Error::PublicKey(err))
}
}
#[cfg(feature = "std")]
impl std::error::Error for Error {}

62
vendor/pkcs1/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,62 @@
#![no_std]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![doc = include_str!("../README.md")]
#![doc(
html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
)]
#![forbid(unsafe_code)]
#![warn(
clippy::mod_module_files,
clippy::unwrap_used,
missing_docs,
rust_2018_idioms,
unused_lifetimes,
unused_qualifications
)]
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "std")]
extern crate std;
mod error;
mod params;
mod private_key;
mod public_key;
mod traits;
mod version;
pub use der::{
self,
asn1::{ObjectIdentifier, UintRef},
};
pub use crate::{
error::{Error, Result},
params::{RsaOaepParams, RsaPssParams, TrailerField},
private_key::RsaPrivateKey,
public_key::RsaPublicKey,
traits::{DecodeRsaPrivateKey, DecodeRsaPublicKey},
version::Version,
};
#[cfg(feature = "alloc")]
pub use crate::{
private_key::{other_prime_info::OtherPrimeInfo, OtherPrimeInfos},
traits::{EncodeRsaPrivateKey, EncodeRsaPublicKey},
};
#[cfg(feature = "pem")]
pub use der::pem::{self, LineEnding};
/// `rsaEncryption` Object Identifier (OID)
#[cfg(feature = "pkcs8")]
pub const ALGORITHM_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.1");
/// `AlgorithmIdentifier` for RSA.
#[cfg(feature = "pkcs8")]
pub const ALGORITHM_ID: pkcs8::AlgorithmIdentifierRef<'static> = pkcs8::AlgorithmIdentifierRef {
oid: ALGORITHM_OID,
parameters: Some(der::asn1::AnyRef::NULL),
};

399
vendor/pkcs1/src/params.rs vendored Normal file
View File

@@ -0,0 +1,399 @@
//! PKCS#1 RSA parameters.
use crate::{Error, Result};
use der::{
asn1::{AnyRef, ContextSpecificRef, ObjectIdentifier},
oid::AssociatedOid,
Decode, DecodeValue, Encode, EncodeValue, FixedTag, Length, Reader, Sequence, Tag, TagMode,
TagNumber, Writer,
};
use spki::{AlgorithmIdentifier, AlgorithmIdentifierRef};
const OID_SHA_1: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.14.3.2.26");
const OID_MGF_1: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.8");
const OID_PSPECIFIED: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.9");
const SHA_1_AI: AlgorithmIdentifierRef<'_> = AlgorithmIdentifierRef {
oid: OID_SHA_1,
parameters: Some(AnyRef::NULL),
};
/// `TrailerField` as defined in [RFC 8017 Appendix 2.3].
/// ```text
/// TrailerField ::= INTEGER { trailerFieldBC(1) }
/// ```
/// [RFC 8017 Appendix 2.3]: https://datatracker.ietf.org/doc/html/rfc8017#appendix-A.2.3
#[derive(Clone, Debug, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum TrailerField {
/// the only supported value (0xbc, default)
BC = 1,
}
impl Default for TrailerField {
fn default() -> Self {
Self::BC
}
}
impl<'a> DecodeValue<'a> for TrailerField {
fn decode_value<R: Reader<'a>>(decoder: &mut R, header: der::Header) -> der::Result<Self> {
match u8::decode_value(decoder, header)? {
1 => Ok(TrailerField::BC),
_ => Err(Self::TAG.value_error()),
}
}
}
impl EncodeValue for TrailerField {
fn value_len(&self) -> der::Result<Length> {
Ok(Length::ONE)
}
fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> {
(*self as u8).encode_value(writer)
}
}
impl FixedTag for TrailerField {
const TAG: Tag = Tag::Integer;
}
/// PKCS#1 RSASSA-PSS parameters as defined in [RFC 8017 Appendix 2.3]
///
/// ASN.1 structure containing a serialized RSASSA-PSS parameters:
/// ```text
/// RSASSA-PSS-params ::= SEQUENCE {
/// hashAlgorithm [0] HashAlgorithm DEFAULT sha1,
/// maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
/// saltLength [2] INTEGER DEFAULT 20,
/// trailerField [3] TrailerField DEFAULT trailerFieldBC
/// }
/// HashAlgorithm ::= AlgorithmIdentifier
/// MaskGenAlgorithm ::= AlgorithmIdentifier
/// ```
///
/// [RFC 8017 Appendix 2.3]: https://datatracker.ietf.org/doc/html/rfc8017#appendix-A.2.3
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct RsaPssParams<'a> {
/// Hash Algorithm
pub hash: AlgorithmIdentifierRef<'a>,
/// Mask Generation Function (MGF)
pub mask_gen: AlgorithmIdentifier<AlgorithmIdentifierRef<'a>>,
/// Salt length
pub salt_len: u8,
/// Trailer field (i.e. [`TrailerField::BC`])
pub trailer_field: TrailerField,
}
impl<'a> RsaPssParams<'a> {
/// Default RSA PSS Salt length in RsaPssParams
pub const SALT_LEN_DEFAULT: u8 = 20;
/// Create new RsaPssParams for the provided digest and salt len
pub fn new<D>(salt_len: u8) -> Self
where
D: AssociatedOid,
{
Self {
hash: AlgorithmIdentifierRef {
oid: D::OID,
parameters: Some(AnyRef::NULL),
},
mask_gen: AlgorithmIdentifier {
oid: OID_MGF_1,
parameters: Some(AlgorithmIdentifierRef {
oid: D::OID,
parameters: Some(AnyRef::NULL),
}),
},
salt_len,
trailer_field: Default::default(),
}
}
fn context_specific_hash(&self) -> Option<ContextSpecificRef<'_, AlgorithmIdentifierRef<'a>>> {
if self.hash == SHA_1_AI {
None
} else {
Some(ContextSpecificRef {
tag_number: TagNumber::N0,
tag_mode: TagMode::Explicit,
value: &self.hash,
})
}
}
fn context_specific_mask_gen(
&self,
) -> Option<ContextSpecificRef<'_, AlgorithmIdentifier<AlgorithmIdentifierRef<'a>>>> {
if self.mask_gen == default_mgf1_sha1() {
None
} else {
Some(ContextSpecificRef {
tag_number: TagNumber::N1,
tag_mode: TagMode::Explicit,
value: &self.mask_gen,
})
}
}
fn context_specific_salt_len(&self) -> Option<ContextSpecificRef<'_, u8>> {
if self.salt_len == RsaPssParams::SALT_LEN_DEFAULT {
None
} else {
Some(ContextSpecificRef {
tag_number: TagNumber::N2,
tag_mode: TagMode::Explicit,
value: &self.salt_len,
})
}
}
fn context_specific_trailer_field(&self) -> Option<ContextSpecificRef<'_, TrailerField>> {
if self.trailer_field == TrailerField::default() {
None
} else {
Some(ContextSpecificRef {
tag_number: TagNumber::N3,
tag_mode: TagMode::Explicit,
value: &self.trailer_field,
})
}
}
}
impl<'a> Default for RsaPssParams<'a> {
fn default() -> Self {
Self {
hash: SHA_1_AI,
mask_gen: default_mgf1_sha1(),
salt_len: RsaPssParams::SALT_LEN_DEFAULT,
trailer_field: Default::default(),
}
}
}
impl<'a> DecodeValue<'a> for RsaPssParams<'a> {
fn decode_value<R: Reader<'a>>(reader: &mut R, header: der::Header) -> der::Result<Self> {
reader.read_nested(header.length, |reader| {
Ok(Self {
hash: reader
.context_specific(TagNumber::N0, TagMode::Explicit)?
.unwrap_or(SHA_1_AI),
mask_gen: reader
.context_specific(TagNumber::N1, TagMode::Explicit)?
.unwrap_or_else(default_mgf1_sha1),
salt_len: reader
.context_specific(TagNumber::N2, TagMode::Explicit)?
.unwrap_or(RsaPssParams::SALT_LEN_DEFAULT),
trailer_field: reader
.context_specific(TagNumber::N3, TagMode::Explicit)?
.unwrap_or_default(),
})
})
}
}
impl EncodeValue for RsaPssParams<'_> {
fn value_len(&self) -> der::Result<Length> {
self.context_specific_hash().encoded_len()?
+ self.context_specific_mask_gen().encoded_len()?
+ self.context_specific_salt_len().encoded_len()?
+ self.context_specific_trailer_field().encoded_len()?
}
fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> {
self.context_specific_hash().encode(writer)?;
self.context_specific_mask_gen().encode(writer)?;
self.context_specific_salt_len().encode(writer)?;
self.context_specific_trailer_field().encode(writer)?;
Ok(())
}
}
impl<'a> Sequence<'a> for RsaPssParams<'a> {}
impl<'a> TryFrom<&'a [u8]> for RsaPssParams<'a> {
type Error = Error;
fn try_from(bytes: &'a [u8]) -> Result<Self> {
Ok(Self::from_der(bytes)?)
}
}
/// Default Mask Generation Function (MGF): SHA-1.
fn default_mgf1_sha1<'a>() -> AlgorithmIdentifier<AlgorithmIdentifierRef<'a>> {
AlgorithmIdentifier::<AlgorithmIdentifierRef<'a>> {
oid: OID_MGF_1,
parameters: Some(SHA_1_AI),
}
}
/// PKCS#1 RSAES-OAEP parameters as defined in [RFC 8017 Appendix 2.1]
///
/// ASN.1 structure containing a serialized RSAES-OAEP parameters:
/// ```text
/// RSAES-OAEP-params ::= SEQUENCE {
/// hashAlgorithm [0] HashAlgorithm DEFAULT sha1,
/// maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
/// pSourceAlgorithm [2] PSourceAlgorithm DEFAULT pSpecifiedEmpty
/// }
/// HashAlgorithm ::= AlgorithmIdentifier
/// MaskGenAlgorithm ::= AlgorithmIdentifier
/// PSourceAlgorithm ::= AlgorithmIdentifier
/// ```
///
/// [RFC 8017 Appendix 2.1]: https://datatracker.ietf.org/doc/html/rfc8017#appendix-A.2.1
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct RsaOaepParams<'a> {
/// Hash Algorithm
pub hash: AlgorithmIdentifierRef<'a>,
/// Mask Generation Function (MGF)
pub mask_gen: AlgorithmIdentifier<AlgorithmIdentifierRef<'a>>,
/// The source (and possibly the value) of the label L
pub p_source: AlgorithmIdentifierRef<'a>,
}
impl<'a> RsaOaepParams<'a> {
/// Create new RsaPssParams for the provided digest and default (empty) label
pub fn new<D>() -> Self
where
D: AssociatedOid,
{
Self::new_with_label::<D>(&[])
}
/// Create new RsaPssParams for the provided digest and specified label
pub fn new_with_label<D>(label: &'a impl AsRef<[u8]>) -> Self
where
D: AssociatedOid,
{
Self {
hash: AlgorithmIdentifierRef {
oid: D::OID,
parameters: Some(AnyRef::NULL),
},
mask_gen: AlgorithmIdentifier {
oid: OID_MGF_1,
parameters: Some(AlgorithmIdentifierRef {
oid: D::OID,
parameters: Some(AnyRef::NULL),
}),
},
p_source: pspecicied_algorithm_identifier(label),
}
}
fn context_specific_hash(&self) -> Option<ContextSpecificRef<'_, AlgorithmIdentifierRef<'a>>> {
if self.hash == SHA_1_AI {
None
} else {
Some(ContextSpecificRef {
tag_number: TagNumber::N0,
tag_mode: TagMode::Explicit,
value: &self.hash,
})
}
}
fn context_specific_mask_gen(
&self,
) -> Option<ContextSpecificRef<'_, AlgorithmIdentifier<AlgorithmIdentifierRef<'a>>>> {
if self.mask_gen == default_mgf1_sha1() {
None
} else {
Some(ContextSpecificRef {
tag_number: TagNumber::N1,
tag_mode: TagMode::Explicit,
value: &self.mask_gen,
})
}
}
fn context_specific_p_source(
&self,
) -> Option<ContextSpecificRef<'_, AlgorithmIdentifierRef<'a>>> {
if self.p_source == default_pempty_string() {
None
} else {
Some(ContextSpecificRef {
tag_number: TagNumber::N2,
tag_mode: TagMode::Explicit,
value: &self.p_source,
})
}
}
}
impl<'a> Default for RsaOaepParams<'a> {
fn default() -> Self {
Self {
hash: SHA_1_AI,
mask_gen: default_mgf1_sha1(),
p_source: default_pempty_string(),
}
}
}
impl<'a> DecodeValue<'a> for RsaOaepParams<'a> {
fn decode_value<R: Reader<'a>>(reader: &mut R, header: der::Header) -> der::Result<Self> {
reader.read_nested(header.length, |reader| {
Ok(Self {
hash: reader
.context_specific(TagNumber::N0, TagMode::Explicit)?
.unwrap_or(SHA_1_AI),
mask_gen: reader
.context_specific(TagNumber::N1, TagMode::Explicit)?
.unwrap_or_else(default_mgf1_sha1),
p_source: reader
.context_specific(TagNumber::N2, TagMode::Explicit)?
.unwrap_or_else(default_pempty_string),
})
})
}
}
impl EncodeValue for RsaOaepParams<'_> {
fn value_len(&self) -> der::Result<Length> {
self.context_specific_hash().encoded_len()?
+ self.context_specific_mask_gen().encoded_len()?
+ self.context_specific_p_source().encoded_len()?
}
fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> {
self.context_specific_hash().encode(writer)?;
self.context_specific_mask_gen().encode(writer)?;
self.context_specific_p_source().encode(writer)?;
Ok(())
}
}
impl<'a> Sequence<'a> for RsaOaepParams<'a> {}
impl<'a> TryFrom<&'a [u8]> for RsaOaepParams<'a> {
type Error = Error;
fn try_from(bytes: &'a [u8]) -> Result<Self> {
Ok(Self::from_der(bytes)?)
}
}
fn pspecicied_algorithm_identifier(label: &impl AsRef<[u8]>) -> AlgorithmIdentifierRef<'_> {
AlgorithmIdentifierRef {
oid: OID_PSPECIFIED,
parameters: Some(
AnyRef::new(Tag::OctetString, label.as_ref()).expect("error creating OAEP params"),
),
}
}
/// Default Source Algorithm, empty string
fn default_pempty_string<'a>() -> AlgorithmIdentifierRef<'a> {
pspecicied_algorithm_identifier(&[])
}

247
vendor/pkcs1/src/private_key.rs vendored Normal file
View File

@@ -0,0 +1,247 @@
//! PKCS#1 RSA Private Keys.
#[cfg(feature = "alloc")]
pub(crate) mod other_prime_info;
use crate::{Error, Result, RsaPublicKey, Version};
use core::fmt;
use der::{
asn1::UintRef, Decode, DecodeValue, Encode, EncodeValue, Header, Length, Reader, Sequence, Tag,
Writer,
};
#[cfg(feature = "alloc")]
use {self::other_prime_info::OtherPrimeInfo, alloc::vec::Vec, der::SecretDocument};
#[cfg(feature = "pem")]
use der::pem::PemLabel;
/// PKCS#1 RSA Private Keys as defined in [RFC 8017 Appendix 1.2].
///
/// ASN.1 structure containing a serialized RSA private key:
///
/// ```text
/// RSAPrivateKey ::= SEQUENCE {
/// version Version,
/// modulus INTEGER, -- n
/// publicExponent INTEGER, -- e
/// privateExponent INTEGER, -- d
/// prime1 INTEGER, -- p
/// prime2 INTEGER, -- q
/// exponent1 INTEGER, -- d mod (p-1)
/// exponent2 INTEGER, -- d mod (q-1)
/// coefficient INTEGER, -- (inverse of q) mod p
/// otherPrimeInfos OtherPrimeInfos OPTIONAL
/// }
/// ```
///
/// Note: the `version` field is selected automatically based on the absence or
/// presence of the `other_prime_infos` field.
///
/// [RFC 8017 Appendix 1.2]: https://datatracker.ietf.org/doc/html/rfc8017#appendix-A.1.2
#[derive(Clone)]
pub struct RsaPrivateKey<'a> {
/// `n`: RSA modulus.
pub modulus: UintRef<'a>,
/// `e`: RSA public exponent.
pub public_exponent: UintRef<'a>,
/// `d`: RSA private exponent.
pub private_exponent: UintRef<'a>,
/// `p`: first prime factor of `n`.
pub prime1: UintRef<'a>,
/// `q`: Second prime factor of `n`.
pub prime2: UintRef<'a>,
/// First exponent: `d mod (p-1)`.
pub exponent1: UintRef<'a>,
/// Second exponent: `d mod (q-1)`.
pub exponent2: UintRef<'a>,
/// CRT coefficient: `(inverse of q) mod p`.
pub coefficient: UintRef<'a>,
/// Additional primes `r_3`, ..., `r_u`, in order, if this is a multi-prime
/// RSA key (i.e. `version` is `multi`).
pub other_prime_infos: Option<OtherPrimeInfos<'a>>,
}
impl<'a> RsaPrivateKey<'a> {
/// Get the public key that corresponds to this [`RsaPrivateKey`].
pub fn public_key(&self) -> RsaPublicKey<'a> {
RsaPublicKey {
modulus: self.modulus,
public_exponent: self.public_exponent,
}
}
/// Get the [`Version`] for this key.
///
/// Determined by the presence or absence of the
/// [`RsaPrivateKey::other_prime_infos`] field.
pub fn version(&self) -> Version {
if self.other_prime_infos.is_some() {
Version::Multi
} else {
Version::TwoPrime
}
}
}
impl<'a> DecodeValue<'a> for RsaPrivateKey<'a> {
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> der::Result<Self> {
reader.read_nested(header.length, |reader| {
let version = Version::decode(reader)?;
let result = Self {
modulus: reader.decode()?,
public_exponent: reader.decode()?,
private_exponent: reader.decode()?,
prime1: reader.decode()?,
prime2: reader.decode()?,
exponent1: reader.decode()?,
exponent2: reader.decode()?,
coefficient: reader.decode()?,
other_prime_infos: reader.decode()?,
};
// Ensure version is set correctly for two-prime vs multi-prime key.
if version.is_multi() != result.other_prime_infos.is_some() {
return Err(reader.error(der::ErrorKind::Value { tag: Tag::Integer }));
}
Ok(result)
})
}
}
impl EncodeValue for RsaPrivateKey<'_> {
fn value_len(&self) -> der::Result<Length> {
self.version().encoded_len()?
+ self.modulus.encoded_len()?
+ self.public_exponent.encoded_len()?
+ self.private_exponent.encoded_len()?
+ self.prime1.encoded_len()?
+ self.prime2.encoded_len()?
+ self.exponent1.encoded_len()?
+ self.exponent2.encoded_len()?
+ self.coefficient.encoded_len()?
+ self.other_prime_infos.encoded_len()?
}
fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> {
self.version().encode(writer)?;
self.modulus.encode(writer)?;
self.public_exponent.encode(writer)?;
self.private_exponent.encode(writer)?;
self.prime1.encode(writer)?;
self.prime2.encode(writer)?;
self.exponent1.encode(writer)?;
self.exponent2.encode(writer)?;
self.coefficient.encode(writer)?;
self.other_prime_infos.encode(writer)?;
Ok(())
}
}
impl<'a> Sequence<'a> for RsaPrivateKey<'a> {}
impl<'a> From<RsaPrivateKey<'a>> for RsaPublicKey<'a> {
fn from(private_key: RsaPrivateKey<'a>) -> RsaPublicKey<'a> {
private_key.public_key()
}
}
impl<'a> From<&RsaPrivateKey<'a>> for RsaPublicKey<'a> {
fn from(private_key: &RsaPrivateKey<'a>) -> RsaPublicKey<'a> {
private_key.public_key()
}
}
impl<'a> TryFrom<&'a [u8]> for RsaPrivateKey<'a> {
type Error = Error;
fn try_from(bytes: &'a [u8]) -> Result<Self> {
Ok(Self::from_der(bytes)?)
}
}
impl fmt::Debug for RsaPrivateKey<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("RsaPrivateKey")
.field("version", &self.version())
.field("modulus", &self.modulus)
.field("public_exponent", &self.public_exponent)
.finish_non_exhaustive()
}
}
#[cfg(feature = "alloc")]
impl TryFrom<RsaPrivateKey<'_>> for SecretDocument {
type Error = Error;
fn try_from(private_key: RsaPrivateKey<'_>) -> Result<SecretDocument> {
SecretDocument::try_from(&private_key)
}
}
#[cfg(feature = "alloc")]
impl TryFrom<&RsaPrivateKey<'_>> for SecretDocument {
type Error = Error;
fn try_from(private_key: &RsaPrivateKey<'_>) -> Result<SecretDocument> {
Ok(Self::encode_msg(private_key)?)
}
}
#[cfg(feature = "pem")]
impl PemLabel for RsaPrivateKey<'_> {
const PEM_LABEL: &'static str = "RSA PRIVATE KEY";
}
/// Placeholder struct for `OtherPrimeInfos` in the no-`alloc` case.
///
/// This type is unconstructable by design, but supports the same traits.
#[cfg(not(feature = "alloc"))]
#[derive(Clone)]
#[non_exhaustive]
pub struct OtherPrimeInfos<'a> {
_lifetime: core::marker::PhantomData<&'a ()>,
}
#[cfg(not(feature = "alloc"))]
impl<'a> DecodeValue<'a> for OtherPrimeInfos<'a> {
fn decode_value<R: Reader<'a>>(reader: &mut R, _header: Header) -> der::Result<Self> {
// Placeholder decoder that always returns an error.
// Uses `Tag::Integer` to signal an unsupported version.
Err(reader.error(der::ErrorKind::Value { tag: Tag::Integer }))
}
}
#[cfg(not(feature = "alloc"))]
impl EncodeValue for OtherPrimeInfos<'_> {
fn value_len(&self) -> der::Result<Length> {
// Placeholder decoder that always returns an error.
// Uses `Tag::Integer` to signal an unsupported version.
Err(der::ErrorKind::Value { tag: Tag::Integer }.into())
}
fn encode_value(&self, _writer: &mut impl Writer) -> der::Result<()> {
// Placeholder decoder that always returns an error.
// Uses `Tag::Integer` to signal an unsupported version.
Err(der::ErrorKind::Value { tag: Tag::Integer }.into())
}
}
#[cfg(not(feature = "alloc"))]
impl<'a> der::FixedTag for OtherPrimeInfos<'a> {
const TAG: Tag = Tag::Sequence;
}
/// Additional RSA prime info in a multi-prime RSA key.
#[cfg(feature = "alloc")]
pub type OtherPrimeInfos<'a> = Vec<OtherPrimeInfo<'a>>;

View File

@@ -0,0 +1,57 @@
//! PKCS#1 OtherPrimeInfo support.
use der::{
asn1::UintRef, DecodeValue, Encode, EncodeValue, Header, Length, Reader, Sequence, Writer,
};
/// PKCS#1 OtherPrimeInfo as defined in [RFC 8017 Appendix 1.2].
///
/// ASN.1 structure containing an additional prime in a multi-prime RSA key.
///
/// ```text
/// OtherPrimeInfo ::= SEQUENCE {
/// prime INTEGER, -- ri
/// exponent INTEGER, -- di
/// coefficient INTEGER -- ti
/// }
/// ```
///
/// [RFC 8017 Appendix 1.2]: https://datatracker.ietf.org/doc/html/rfc8017#appendix-A.1.2
#[derive(Clone)]
pub struct OtherPrimeInfo<'a> {
/// Prime factor `r_i` of `n`, where `i` >= 3.
pub prime: UintRef<'a>,
/// Exponent: `d_i = d mod (r_i - 1)`.
pub exponent: UintRef<'a>,
/// CRT coefficient: `t_i = (r_1 * r_2 * ... * r_(i-1))^(-1) mod r_i`.
pub coefficient: UintRef<'a>,
}
impl<'a> DecodeValue<'a> for OtherPrimeInfo<'a> {
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> der::Result<Self> {
reader.read_nested(header.length, |reader| {
Ok(Self {
prime: reader.decode()?,
exponent: reader.decode()?,
coefficient: reader.decode()?,
})
})
}
}
impl EncodeValue for OtherPrimeInfo<'_> {
fn value_len(&self) -> der::Result<Length> {
self.prime.encoded_len()? + self.exponent.encoded_len()? + self.coefficient.encoded_len()?
}
fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> {
self.prime.encode(writer)?;
self.exponent.encode(writer)?;
self.coefficient.encode(writer)?;
Ok(())
}
}
impl<'a> Sequence<'a> for OtherPrimeInfo<'a> {}

90
vendor/pkcs1/src/public_key.rs vendored Normal file
View File

@@ -0,0 +1,90 @@
//! PKCS#1 RSA Public Keys.
use crate::{Error, Result};
use der::{
asn1::UintRef, Decode, DecodeValue, Encode, EncodeValue, Header, Length, Reader, Sequence,
Writer,
};
#[cfg(feature = "alloc")]
use der::Document;
#[cfg(feature = "pem")]
use der::pem::PemLabel;
/// PKCS#1 RSA Public Keys as defined in [RFC 8017 Appendix 1.1].
///
/// ASN.1 structure containing a serialized RSA public key:
///
/// ```text
/// RSAPublicKey ::= SEQUENCE {
/// modulus INTEGER, -- n
/// publicExponent INTEGER -- e
/// }
/// ```
///
/// [RFC 8017 Appendix 1.1]: https://datatracker.ietf.org/doc/html/rfc8017#appendix-A.1.1
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct RsaPublicKey<'a> {
/// `n`: RSA modulus
pub modulus: UintRef<'a>,
/// `e`: RSA public exponent
pub public_exponent: UintRef<'a>,
}
impl<'a> DecodeValue<'a> for RsaPublicKey<'a> {
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> der::Result<Self> {
reader.read_nested(header.length, |reader| {
Ok(Self {
modulus: reader.decode()?,
public_exponent: reader.decode()?,
})
})
}
}
impl EncodeValue for RsaPublicKey<'_> {
fn value_len(&self) -> der::Result<Length> {
self.modulus.encoded_len()? + self.public_exponent.encoded_len()?
}
fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> {
self.modulus.encode(writer)?;
self.public_exponent.encode(writer)?;
Ok(())
}
}
impl<'a> Sequence<'a> for RsaPublicKey<'a> {}
impl<'a> TryFrom<&'a [u8]> for RsaPublicKey<'a> {
type Error = Error;
fn try_from(bytes: &'a [u8]) -> Result<Self> {
Ok(Self::from_der(bytes)?)
}
}
#[cfg(feature = "alloc")]
impl TryFrom<RsaPublicKey<'_>> for Document {
type Error = Error;
fn try_from(spki: RsaPublicKey<'_>) -> Result<Document> {
Self::try_from(&spki)
}
}
#[cfg(feature = "alloc")]
impl TryFrom<&RsaPublicKey<'_>> for Document {
type Error = Error;
fn try_from(spki: &RsaPublicKey<'_>) -> Result<Document> {
Ok(Self::encode_msg(spki)?)
}
}
#[cfg(feature = "pem")]
impl PemLabel for RsaPublicKey<'_> {
const PEM_LABEL: &'static str = "RSA PUBLIC KEY";
}

202
vendor/pkcs1/src/traits.rs vendored Normal file
View File

@@ -0,0 +1,202 @@
//! Traits for parsing objects from PKCS#1 encoded documents
use crate::Result;
#[cfg(feature = "alloc")]
use der::{Document, SecretDocument};
#[cfg(feature = "pem")]
use {
crate::LineEnding,
alloc::string::String,
der::{pem::PemLabel, zeroize::Zeroizing},
};
#[cfg(feature = "pkcs8")]
use {
crate::{ALGORITHM_ID, ALGORITHM_OID},
der::asn1::BitStringRef,
};
#[cfg(feature = "std")]
use std::path::Path;
#[cfg(all(feature = "alloc", feature = "pkcs8"))]
use der::Decode;
#[cfg(all(feature = "alloc", any(feature = "pem", feature = "pkcs8")))]
use crate::{RsaPrivateKey, RsaPublicKey};
/// Parse an [`RsaPrivateKey`] from a PKCS#1-encoded document.
pub trait DecodeRsaPrivateKey: Sized {
/// Deserialize PKCS#1 private key from ASN.1 DER-encoded data
/// (binary format).
fn from_pkcs1_der(bytes: &[u8]) -> Result<Self>;
/// Deserialize PKCS#1-encoded private key from PEM.
///
/// Keys in this format begin with the following:
///
/// ```text
/// -----BEGIN RSA PRIVATE KEY-----
/// ```
#[cfg(feature = "pem")]
fn from_pkcs1_pem(s: &str) -> Result<Self> {
let (label, doc) = SecretDocument::from_pem(s)?;
RsaPrivateKey::validate_pem_label(label)?;
Self::from_pkcs1_der(doc.as_bytes())
}
/// Load PKCS#1 private key from an ASN.1 DER-encoded file on the local
/// filesystem (binary format).
#[cfg(feature = "std")]
fn read_pkcs1_der_file(path: impl AsRef<Path>) -> Result<Self> {
Self::from_pkcs1_der(SecretDocument::read_der_file(path)?.as_bytes())
}
/// Load PKCS#1 private key from a PEM-encoded file on the local filesystem.
#[cfg(all(feature = "pem", feature = "std"))]
fn read_pkcs1_pem_file(path: impl AsRef<Path>) -> Result<Self> {
let (label, doc) = SecretDocument::read_pem_file(path)?;
RsaPrivateKey::validate_pem_label(&label)?;
Self::from_pkcs1_der(doc.as_bytes())
}
}
/// Parse a [`RsaPublicKey`] from a PKCS#1-encoded document.
pub trait DecodeRsaPublicKey: Sized {
/// Deserialize object from ASN.1 DER-encoded [`RsaPublicKey`]
/// (binary format).
fn from_pkcs1_der(bytes: &[u8]) -> Result<Self>;
/// Deserialize PEM-encoded [`RsaPublicKey`].
///
/// Keys in this format begin with the following:
///
/// ```text
/// -----BEGIN RSA PUBLIC KEY-----
/// ```
#[cfg(feature = "pem")]
fn from_pkcs1_pem(s: &str) -> Result<Self> {
let (label, doc) = Document::from_pem(s)?;
RsaPublicKey::validate_pem_label(label)?;
Self::from_pkcs1_der(doc.as_bytes())
}
/// Load [`RsaPublicKey`] from an ASN.1 DER-encoded file on the local
/// filesystem (binary format).
#[cfg(feature = "std")]
fn read_pkcs1_der_file(path: impl AsRef<Path>) -> Result<Self> {
let doc = Document::read_der_file(path)?;
Self::from_pkcs1_der(doc.as_bytes())
}
/// Load [`RsaPublicKey`] from a PEM-encoded file on the local filesystem.
#[cfg(all(feature = "pem", feature = "std"))]
fn read_pkcs1_pem_file(path: impl AsRef<Path>) -> Result<Self> {
let (label, doc) = Document::read_pem_file(path)?;
RsaPublicKey::validate_pem_label(&label)?;
Self::from_pkcs1_der(doc.as_bytes())
}
}
/// Serialize a [`RsaPrivateKey`] to a PKCS#1 encoded document.
#[cfg(feature = "alloc")]
pub trait EncodeRsaPrivateKey {
/// Serialize a [`SecretDocument`] containing a PKCS#1-encoded private key.
fn to_pkcs1_der(&self) -> Result<SecretDocument>;
/// Serialize this private key as PEM-encoded PKCS#1 with the given [`LineEnding`].
#[cfg(feature = "pem")]
fn to_pkcs1_pem(&self, line_ending: LineEnding) -> Result<Zeroizing<String>> {
let doc = self.to_pkcs1_der()?;
Ok(doc.to_pem(RsaPrivateKey::PEM_LABEL, line_ending)?)
}
/// Write ASN.1 DER-encoded PKCS#1 private key to the given path.
#[cfg(feature = "std")]
fn write_pkcs1_der_file(&self, path: impl AsRef<Path>) -> Result<()> {
Ok(self.to_pkcs1_der()?.write_der_file(path)?)
}
/// Write ASN.1 DER-encoded PKCS#1 private key to the given path.
#[cfg(all(feature = "pem", feature = "std"))]
fn write_pkcs1_pem_file(&self, path: impl AsRef<Path>, line_ending: LineEnding) -> Result<()> {
let doc = self.to_pkcs1_der()?;
Ok(doc.write_pem_file(path, RsaPrivateKey::PEM_LABEL, line_ending)?)
}
}
/// Serialize a [`RsaPublicKey`] to a PKCS#1-encoded document.
#[cfg(feature = "alloc")]
pub trait EncodeRsaPublicKey {
/// Serialize a [`Document`] containing a PKCS#1-encoded public key.
fn to_pkcs1_der(&self) -> Result<Document>;
/// Serialize this public key as PEM-encoded PKCS#1 with the given line ending.
#[cfg(feature = "pem")]
fn to_pkcs1_pem(&self, line_ending: LineEnding) -> Result<String> {
let doc = self.to_pkcs1_der()?;
Ok(doc.to_pem(RsaPublicKey::PEM_LABEL, line_ending)?)
}
/// Write ASN.1 DER-encoded public key to the given path.
#[cfg(feature = "std")]
fn write_pkcs1_der_file(&self, path: impl AsRef<Path>) -> Result<()> {
Ok(self.to_pkcs1_der()?.write_der_file(path)?)
}
/// Write ASN.1 DER-encoded public key to the given path.
#[cfg(all(feature = "pem", feature = "std"))]
fn write_pkcs1_pem_file(&self, path: impl AsRef<Path>, line_ending: LineEnding) -> Result<()> {
let doc = self.to_pkcs1_der()?;
Ok(doc.write_pem_file(path, RsaPublicKey::PEM_LABEL, line_ending)?)
}
}
#[cfg(feature = "pkcs8")]
impl<T> DecodeRsaPrivateKey for T
where
T: for<'a> TryFrom<pkcs8::PrivateKeyInfo<'a>, Error = pkcs8::Error>,
{
fn from_pkcs1_der(private_key: &[u8]) -> Result<Self> {
Ok(Self::try_from(pkcs8::PrivateKeyInfo {
algorithm: ALGORITHM_ID,
private_key,
public_key: None,
})?)
}
}
#[cfg(feature = "pkcs8")]
impl<T> DecodeRsaPublicKey for T
where
T: for<'a> TryFrom<pkcs8::SubjectPublicKeyInfoRef<'a>, Error = pkcs8::spki::Error>,
{
fn from_pkcs1_der(public_key: &[u8]) -> Result<Self> {
Ok(Self::try_from(pkcs8::SubjectPublicKeyInfoRef {
algorithm: ALGORITHM_ID,
subject_public_key: BitStringRef::from_bytes(public_key)?,
})?)
}
}
#[cfg(all(feature = "alloc", feature = "pkcs8"))]
impl<T: pkcs8::EncodePrivateKey> EncodeRsaPrivateKey for T {
fn to_pkcs1_der(&self) -> Result<SecretDocument> {
let pkcs8_doc = self.to_pkcs8_der()?;
let pkcs8_key = pkcs8::PrivateKeyInfo::from_der(pkcs8_doc.as_bytes())?;
pkcs8_key.algorithm.assert_algorithm_oid(ALGORITHM_OID)?;
RsaPrivateKey::from_der(pkcs8_key.private_key)?.try_into()
}
}
#[cfg(all(feature = "alloc", feature = "pkcs8"))]
impl<T: pkcs8::EncodePublicKey> EncodeRsaPublicKey for T {
fn to_pkcs1_der(&self) -> Result<Document> {
let doc = self.to_public_key_der()?;
let spki = pkcs8::SubjectPublicKeyInfoRef::from_der(doc.as_bytes())?;
spki.algorithm.assert_algorithm_oid(ALGORITHM_OID)?;
RsaPublicKey::from_der(spki.subject_public_key.raw_bytes())?.try_into()
}
}

72
vendor/pkcs1/src/version.rs vendored Normal file
View File

@@ -0,0 +1,72 @@
//! PKCS#1 version identifier.
use crate::Error;
use der::{Decode, Encode, FixedTag, Reader, Tag, Writer};
/// Version identifier for PKCS#1 documents as defined in
/// [RFC 8017 Appendix 1.2].
///
/// > version is the version number, for compatibility with future
/// > revisions of this document. It SHALL be 0 for this version of the
/// > document, unless multi-prime is used; in which case, it SHALL be 1.
///
/// ```text
/// Version ::= INTEGER { two-prime(0), multi(1) }
/// (CONSTRAINED BY
/// {-- version must be multi if otherPrimeInfos present --})
/// ```
///
/// [RFC 8017 Appendix 1.2]: https://datatracker.ietf.org/doc/html/rfc8017#appendix-A.1.2
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
#[repr(u8)]
pub enum Version {
/// Denotes a `two-prime` key
TwoPrime = 0,
/// Denotes a `multi` (i.e. multi-prime) key
Multi = 1,
}
impl Version {
/// Is this a multi-prime RSA key?
pub fn is_multi(self) -> bool {
self == Self::Multi
}
}
impl From<Version> for u8 {
fn from(version: Version) -> Self {
version as u8
}
}
impl TryFrom<u8> for Version {
type Error = Error;
fn try_from(byte: u8) -> Result<Version, Error> {
match byte {
0 => Ok(Version::TwoPrime),
1 => Ok(Version::Multi),
_ => Err(Error::Version),
}
}
}
impl<'a> Decode<'a> for Version {
fn decode<R: Reader<'a>>(decoder: &mut R) -> der::Result<Self> {
Version::try_from(u8::decode(decoder)?).map_err(|_| Self::TAG.value_error())
}
}
impl Encode for Version {
fn encoded_len(&self) -> der::Result<der::Length> {
der::Length::ONE.for_tlv()
}
fn encode(&self, writer: &mut impl Writer) -> der::Result<()> {
u8::from(*self).encode(writer)
}
}
impl FixedTag for Version {
const TAG: Tag = Tag::Integer;
}

Binary file not shown.

View File

View File

@@ -0,0 +1 @@
{"name":"pkcs1","vers":"0.7.5","deps":[{"name":"der","req":"^0.7","features":["oid"],"optional":false,"default_features":true,"target":null,"kind":"normal","registry":"https://github.com/rust-lang/crates.io-index","package":null,"public":null,"artifact":null,"bindep_target":null,"lib":false},{"name":"pkcs8","req":"^0.10","features":[],"optional":true,"default_features":false,"target":null,"kind":"normal","registry":"https://github.com/rust-lang/crates.io-index","package":null,"public":null,"artifact":null,"bindep_target":null,"lib":false},{"name":"spki","req":"^0.7","features":[],"optional":false,"default_features":true,"target":null,"kind":"normal","registry":"https://github.com/rust-lang/crates.io-index","package":null,"public":null,"artifact":null,"bindep_target":null,"lib":false},{"name":"const-oid","req":"^0.9","features":["db"],"optional":false,"default_features":true,"target":null,"kind":"dev","registry":"https://github.com/rust-lang/crates.io-index","package":null,"public":null,"artifact":null,"bindep_target":null,"lib":false},{"name":"hex-literal","req":"^0.4","features":[],"optional":false,"default_features":true,"target":null,"kind":"dev","registry":"https://github.com/rust-lang/crates.io-index","package":null,"public":null,"artifact":null,"bindep_target":null,"lib":false},{"name":"tempfile","req":"^3","features":[],"optional":false,"default_features":true,"target":null,"kind":"dev","registry":"https://github.com/rust-lang/crates.io-index","package":null,"public":null,"artifact":null,"bindep_target":null,"lib":false}],"features":{"alloc":["der/alloc","zeroize","pkcs8?/alloc"],"pem":["alloc","der/pem","pkcs8?/pem"],"std":["der/std","alloc"],"zeroize":["der/zeroize"]},"features2":null,"cksum":"61ba4aed2977d0648a3fb89c71b568047f811681df519831c09e0daf64d6e944","yanked":null,"links":null,"rust_version":null,"v":2}

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,28 @@
-----BEGIN RSA PRIVATE KEY-----
MIIE2AIBAQKCAQEA6L9GSA2RROk9DnlxVU9+9F+yW4OhBpQW247HxlTrSJxpWjJ0
7ktfOgjjW6bR/y7Eh85URkHqDAmUzFVNIgEwjjrGSRMmGD9HfTDxZQAYALOHcb+W
9p3m1GGm4viAVxBPzdbGobaef5WifawMuuOcwfkmTAnf7qaEd0gsKBYTMBK6KaDW
F/psa3D6w77csCDLH26jN1FjmI5/jJR0tUYsJNK1a8A/ntAC5Dx2Sx57BcMex9jp
FYLOwJQvOW2rlPMWLRqqBB2pnO6QuB/0CLt1t7IzsZ005QTiWMHXdHBuTF/CsR+X
yeTO6sNF+MV8PTcC9z/Jj37taIgSvptWBhjCRQIDAQABAoIBAFGtpmVs1XkgfPvS
ZJJytnPeDYKOG/lqCOd+IN+aN4Og2Fv97wkdTEraiadFUNbDu9aI8wxA33jf9+cJ
XGs9jaOsPp+wZ6MEufrWLTCrqsC8QCEMAldZo3QDSGQwivbkRMa+6k/qEtt4qXBa
DwyLcys/1zPFh3qHHsxY+rJdQjbQyR8gfW/HntVWhlhiOYTvmSyF6nv/x/jBg2jm
RCiRmLZM82jA/e/6fiS2XYlbcB+K9wrqsLt9LhTENU4Vvkcj7Ihd8UbXsMbShEwU
32Od2px5M//71a4jCLKpzn5sUuN2YQa4/vjVk7iEkbztaGMgReDi+4iaWO0v8otu
XiCCuwECVgfqQeOwtvpjN9jSVLIfBsI3/apkQrOydWpHmycnPOzPu19HKqXZQeEd
oarrF2RQ/AROpjnvbmt3tTDZikOs8tOVcXFO7VFrv0OnB55kDKRq5kDMrka1AlYH
fpIQOZRT8fnWrYYrTYPuhlH5I1S8TyKxpTdu02/oDc/d9zzusyaXImW1ysIeL1/y
Lwnm6grzWFQABNbR7zqCviFNIGsl+Y8PO6+M1PJdcWmsyZgJqQJWAjYimMJ8LXNh
XDRQM8BVfBh2yI/gzyJyifJd2E+vRx83ZASXVuVf8cz8qaurynySHYX4DcHnISG+
P1rYtdXxtspPevApgJFRTE6z4z5jBeFUWhCWNO0CVgCDD/1VwaE+bX/R2NGKeRHJ
UT5AwKAgk9Eo5TGH9iQXFXUnV51C1ccLTYFuuXYQbHCB8B47LMZU6WAa9IXg3tFh
paq8JTWx56j1vddUEL57aemo198JAlYDtUxSGZYE2akgsberlfC0dLpGeWzEbD5j
xINJkHG/rcDScyHr1T4JJx8oZGt1kMlxAvnkWKk7OgJKA1Zbyv+hX3PAW7+WU74j
IkoeNVJKmJVkHHb9LjCCAQswggEHAlYD7HVTL7DSyhQmMmGOpphUjYSJ/jCoaNY3
odU4lcefFqY622DbIX3cDZVpSj2V0CnRqaLfVI7RBbLGqEhVc57bw86CkGUAJB1R
ijFy+NRw+t1OHf5ZaQJWA6EVCKPlL6RBLO+O806/Of5IaQdYZH3MH1suiQ9pvIpL
qcc/eJErBH8AA4rrGgaYl9kL0P06uLZHnZ8MgRXYC7i67GO5OH8vKzvi71Cf1/0C
9H2jxXkCVTnqImyr+zF+QaVZO5Fo0aASSZO0XZzRSiK9FVfNy0PSgCSsJu0shTC1
PpuTqHj0KIB8UoLruBE5n5EwF83yFJAT2Azfc/YJ1saSR163oSPQ6T5qYPw=
-----END RSA PRIVATE KEY-----

Binary file not shown.

View File

@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAtsQsUV8QpqrygsY+2+JCQ6Fw8/omM71IM2N/R8pPbzbgOl0p
78MZGsgPOQ2HSznjD0FPzsH8oO2B5Uftws04LHb2HJAYlz25+lN5cqfHAfa3fgmC
38FfwBkn7l582UtPWZ/wcBOnyCgb3yLcvJrXyrt8QxHJgvWO23ITrUVYszImbXQ6
7YGS0YhMrbixRzmo2tpm3JcIBtnHrEUMsT0NfFdfsZhTT8YbxBvA8FdODgEwx7u/
vf3J9qbi4+Kv8cvqyJuleIRSjVXPsIMnoejIn04APPKIjpMyQdnWlby7rNyQtE4+
CV+jcFjqJbE/Xilcvqxt6DirjFCvYeKYl1uHLwIDAQABAoIBAH7Mg2LA7bB0EWQh
XiL3SrnZG6BpAHAM9jaQ5RFNjua9z7suP5YUaSpnegg/FopeUuWWjmQHudl8bg5A
ZPgtoLdYoU8XubfUH19I4o1lUXBPVuaeeqn6Yw/HZCjAbSXkVdz8VbesK092ZD/e
0/4V/3irsn5lrMSq0L322yfvYKaRDFxKCF7UMnWrGcHZl6Msbv/OffLRk19uYB7t
4WGhK1zCfKIfgdLJnD0eoI6Q4wU6sJvvpyTe8NDDo8HpdAwNn3YSahSewKp9gHgg
VIQlTZUdsHxM+R+2RUwJZYj9WSTbq+s1nKICUmjQBPnWbrPW963BE5utQPFt3mOe
EWRzdsECgYEA3MBhJC1Okq+u5yrFE8plufdwNvm9fg5uYUYafvdlQiXsFTx+XDGm
FXpuWhP/bheOh1jByzPZ1rvjF57xiZjkIuzcvtePTs/b5fT82K7CydDchkc8qb0W
2dI40h+13e++sUPKYdC9aqjZHzOgl3kOlkDbyRCF3F8mNDujE49rLWcCgYEA0/MU
dX5A6VSDb5K+JCNq8vDaBKNGU8GAr2fpYAhtk/3mXLI+/Z0JN0di9ZgeNhhJr2jN
11OU/2pOButpsgnkIo2y36cOQPf5dQpSgXZke3iNDld3osuLIuPNJn/3C087AtOq
+w4YxZClZLAxiLCqX8SBVrB2IiFCQ70SJ++n8vkCgYEAzmi3rBsNEA1jblVIh1PF
wJhD/bOQ4nBd92iUV8m9jZdl4wl4YX4u/IBI9MMkIG24YIe2VOl7s9Rk5+4/jNg/
4QQ2998Y6aljxOZJEdZ+3jQELy4m49OhrTRq2ta5t/Z3CMsJTmLe6f9NXWZpr5iK
8iVdHOjtMXxqfYaR2jVNEtsCgYAl9uWUQiAoa037v0I1wO5YQ9IZgJGJUSDWynsg
C4JtPs5zji4ASY+sCipsqWnH8MPKGrC8QClxMr51ONe+30yw78a5jvfbpU9Wqpmq
vOU0xJwnlH1GeMUcY8eMfOFocjG0yOtYeubvBIDLr0/AFzz9WHp+Z69RX7m53nUR
GDlyKQKBgDGZVAbUBiB8rerqNbONBAxfipoa4IJ+ntBrFT2DtoIZNbSzaoK+nVbH
kbWMJycaV5PVOh1lfAiZeWCxQz5RcZh/RS8USnxyMG1j4dP/wLcbdasI8uRaSC6Y
hFHL5HjhLrIo0HRWySS2b2ztBI2FP1M+MaaGFPHDzm2OyZg85yr3
-----END RSA PRIVATE KEY-----

Binary file not shown.

View File

@@ -0,0 +1,8 @@
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAtsQsUV8QpqrygsY+2+JCQ6Fw8/omM71IM2N/R8pPbzbgOl0p78MZ
GsgPOQ2HSznjD0FPzsH8oO2B5Uftws04LHb2HJAYlz25+lN5cqfHAfa3fgmC38Ff
wBkn7l582UtPWZ/wcBOnyCgb3yLcvJrXyrt8QxHJgvWO23ITrUVYszImbXQ67YGS
0YhMrbixRzmo2tpm3JcIBtnHrEUMsT0NfFdfsZhTT8YbxBvA8FdODgEwx7u/vf3J
9qbi4+Kv8cvqyJuleIRSjVXPsIMnoejIn04APPKIjpMyQdnWlby7rNyQtE4+CV+j
cFjqJbE/Xilcvqxt6DirjFCvYeKYl1uHLwIDAQAB
-----END RSA PUBLIC KEY-----

Binary file not shown.

View File

@@ -0,0 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
MIIJKQIBAAKCAgEAp6dFcoEeomF+Sehb1zDd4w8QP32I7j92XlQNPdmTu7C6FAAC
hZ0LQIl0NmN/WLgo6nTfgyFjQHf5nUqi1UyjdYUu9ZdmHTcTzh7ztP1qjiICOORn
ZoosfuOGHSISrmoevd+oi2LfEPa8957/SsKY+yVj3xuHZDga+bH7DM0IXgJrCtn2
chojUXfQOWtIdUrUp1JCJQqHO/L25+48dd1hPjZbpPMhCmzGa5Ci+j92LKaIQIe2
v4Fh6xRIGfD1cvIfbI4nPnDUWjZbiygZznNGE8wjsBMpoXkB8XB4QDhh9UxSoFHi
pYx1wtnYAJG7mAihBsH37LQDThUFi+7HJcX5GdYuqiNLYmKNNGxgu5GecIUdqzhX
Hm8O12NBKfmU6jaP7nNz397AREXrykf6IO0VQKhgyUi6vJjaWRyh3i4uJVQO+bfL
NT9gITuBSkXTWe+puBHu/wjGWZO/ioXCv+qqftXmtD4YrmBEZM5flhUBNufQn4sk
+tQ9eHARjPp7wkh1UG67wyG5d+CGGupQEoYgEh8LOUqc3QpCQRoTUMB3DZddcbAK
kENiQMlnoMOlwgoPbed/Pyyv2pTtAUPB9uNPc+DKwnnu63xjdyOisCbIKALhpK66
qIRt+Y55GUmHc+DU8xmVb03jqtAO+5oUfWazrBoB01ss+0jUALDnqA3JdVECAwEA
AQKCAgEAn+MJeyMiuQ+rZgbAF6CV6+ZAw5wQC87gLyOPoU2v846eV1aPESftRDYS
a5BGMbEn7Dlbs+4SfrgsiNJWKn+1X+2NFFC35OLS839XQmNvzG8omWNSLVtXBggs
rfoBwO6ZtNDpJ006mS4Gl0y+AWlGhjVpYqwZWf2b1EfluZaMBUPfG/E0dCrzRc2y
+h+TcbDUz2HGjRbWU9jpmdT9OhbPl4o1qkDoYM3OCWVd2LTPGdQUGx6SrV5RqOSl
wn+nRWEdkOSdDpKCIiq28SZkPhx3V4gW/OO5jzIdJUnylKRw34RTRGvzb5hd8l7Y
/en98wc/sncn30jp4fxwVrx4llCQt4UBJkBkYsglMFHvhONO48POuPlsZYw4vkVV
jS9k4p0iM1BVX8Hvoo7B9K+1ukCA8JqGzcNTjBrXyXLm16NhLmhFupr73xnwkGDR
p3neljXi0vjgxRC6JMbESzDJvfr4W+kXrsXUOvqxqjrdM8yD2pPKxpIY9qNutH8Z
nVQkyV/Z7Xsei+KuqmQzsickExbCDueSZQzrSL/WNERrGdKGtOoXIkmNoaNpcyEO
w4JHUaWAjZqu9ZxEnhmlB3z+yhJr2ajdSZZWHU4ns2Cf+CxbGyHmJ4RdRJYbM7h1
1cT6n/NX72vjNklp4TN8kbKaB7mpE83kDOLVUwyQDnN1FoXmVDECggEBANAhOnlC
W2ZbcZEYRIiT7DJ1YA9j2/hbd/To6Z7zAvboJZYEj23Kdy3mu/ESTbhLCv5hsDqG
BKsAee1T8zBHl60Bs4xE/ielpF43hIOoBLVqSpZ/SPAahm5yHmfkyaEEivaJJ/qk
PWqF2T579wdNunl1Y/yr4SMJt2ZTxtthTcIxzFVtnyWsSEGgLTHN8wFbISMH+dDH
n+tdOVbOU8yPoWUb5gdh8Z90ZySJ6vnyFUCfOZVud6ghg/H3K7L+3fG5+/xK2J6k
RYCd29W9WVJ3mQwL6TZvuy7PewV8wcPcj7d7+EVtB7vJWzwYFfSOYrgUaMPU2dls
D0jasEmTvo2R7eUCggEBAM42xoEFIqvl1kZfNusTfaO56kpfHSfGYUcp645eLly4
jj7xpHOiGUS2ZVez3CzkYuS/NEbLSZADflZysXBcuugbZbr5Z6Jm3Bjv6A9Nu/4a
WQYyBc4pQ8rfQhzOdK9wY/0ag688Oa+EUl9ZvcH/VIFfUq/R6NSGKyw2VPbPqD3A
jiqdUrn4M8ZGr3aURn38X31617RBiV/Lf/vtUmMksBVKFYI/UQfIlUjt3LYdpTCM
bMg01KDBbfpsodZ7YaZWd+sXGc0SXQ7w24gC+3bPwXV3vLJRCuKU4b+KkXOiuFwW
prUIyY8tdwt/PeSNnnIMU+JjaAtX5xCUEAFXRVcGUv0CggEAdItGzQPlXmmyLEdk
iP4b8x1azwNh965we4m42DLH5C6WbWzcS+Rl3CQp9ZIER0BuRYe6QOsuzfqUS9sI
gG52doBPZCp2DwloAwIfiAGbsWJ1pdRcqWaRBGOOtyqb5ThAAFFJO8agRXfx8FVG
PKa/1qdvd9tfVFlqgzhCUDIqcqWj/+pEhbn1NBpXdF4YxxeadJ1QvCIsYIVxSDR9
JD0BaTa4FkY4IMvzvbglBhUS5X7DpfOXuWQbGHEJ3U9uRJ+ahOn8ZskhyiWbJhLD
Y7Ro1SAOVVc3f7za7HWxotVs/JfErEujWvojxoDOOoVIrj9vcslLu74QyQD8WhcL
Swb+KQKCAQB1yk4LBp7uZ8PEwMCC+MgsjJbq0ne575RDbQuTb/K1neoKxEa2kmIy
oKk0tpVOw0pF9X3r7lTfwU8aHDuEvkM5L+UlLy9mUbDpQahhjXqTxAMUCeDNCT8j
E/IUuE1opR9IRSvxHcqpmkDfHEjLFojzuTpnGdUQCG+Cuqo/rRAh7eqHJwRJHCCe
4mN5rWqyrkTxTQkHeuP4Zyp9AeusnBlEn+O3WWl0s7uqQ8xt7nMcTyoYFi1aggLL
J+Atvp5hwESRccmYHSQw053ijCmNjVCpQ7LyfF5mXLqyiXlZ/xml6H5jLFjNwx+b
3pvBAK//31DPIQ8eY6CmFJ0r1ujRs9gVAoIBAQCMVXxINei0BmYGpdwlXbw+tfFY
bHMomIyOJCQD+Vde+w0oASwGNLckF2itciBJOCkG1jWvyx0qBb3/yAX+ZwOJt/qQ
1l+Ur7wgCNm8DTzO5CXfxyQCBQYDyfV57oUQ7MaTrG3TKDa24V49xSA2ahukr8kd
Pkik1nJMpCRD9IA+OxJjSwQ4Vy2OE7xy8agoU7jZ/KYZnXqQq2TZ5595OsKH+aGQ
EQgqUmjyCTMtVNmNbhkDCQf9nmuC7xJGd7oIrWeXpEIhPQl6NRxQoIko3XMtaymm
z2cG2vXyD3j4cXD7J5QDxSIbXlxwwrqg5ppy4NHzJn29jJvd/yivqS83yY02
-----END RSA PRIVATE KEY-----

Binary file not shown.

View File

@@ -0,0 +1,13 @@
-----BEGIN RSA PUBLIC KEY-----
MIICCgKCAgEAp6dFcoEeomF+Sehb1zDd4w8QP32I7j92XlQNPdmTu7C6FAAChZ0L
QIl0NmN/WLgo6nTfgyFjQHf5nUqi1UyjdYUu9ZdmHTcTzh7ztP1qjiICOORnZoos
fuOGHSISrmoevd+oi2LfEPa8957/SsKY+yVj3xuHZDga+bH7DM0IXgJrCtn2choj
UXfQOWtIdUrUp1JCJQqHO/L25+48dd1hPjZbpPMhCmzGa5Ci+j92LKaIQIe2v4Fh
6xRIGfD1cvIfbI4nPnDUWjZbiygZznNGE8wjsBMpoXkB8XB4QDhh9UxSoFHipYx1
wtnYAJG7mAihBsH37LQDThUFi+7HJcX5GdYuqiNLYmKNNGxgu5GecIUdqzhXHm8O
12NBKfmU6jaP7nNz397AREXrykf6IO0VQKhgyUi6vJjaWRyh3i4uJVQO+bfLNT9g
ITuBSkXTWe+puBHu/wjGWZO/ioXCv+qqftXmtD4YrmBEZM5flhUBNufQn4sk+tQ9
eHARjPp7wkh1UG67wyG5d+CGGupQEoYgEh8LOUqc3QpCQRoTUMB3DZddcbAKkENi
QMlnoMOlwgoPbed/Pyyv2pTtAUPB9uNPc+DKwnnu63xjdyOisCbIKALhpK66qIRt
+Y55GUmHc+DU8xmVb03jqtAO+5oUfWazrBoB01ss+0jUALDnqA3JdVECAwEAAQ==
-----END RSA PUBLIC KEY-----

223
vendor/pkcs1/tests/params.rs vendored Normal file
View File

@@ -0,0 +1,223 @@
//! PKCS#1 algorithm params tests
use const_oid::db;
use der::{
asn1::{AnyRef, ObjectIdentifier, OctetStringRef},
oid::AssociatedOid,
Encode,
};
use hex_literal::hex;
use pkcs1::{RsaOaepParams, RsaPssParams, TrailerField};
/// Default PSS parameters using all default values (SHA1, MGF1)
const RSA_PSS_PARAMETERS_DEFAULTS: &[u8] = &hex!("3000");
/// Example PSS parameters using SHA256 instead of SHA1
const RSA_PSS_PARAMETERS_SHA2_256: &[u8] = &hex!("3034a00f300d06096086480165030402010500a11c301a06092a864886f70d010108300d06096086480165030402010500a203020120");
/// Default OAEP parameters using all default values (SHA1, MGF1, Empty)
const RSA_OAEP_PARAMETERS_DEFAULTS: &[u8] = &hex!("3000");
/// Example OAEP parameters using SHA256 instead of SHA1
const RSA_OAEP_PARAMETERS_SHA2_256: &[u8] = &hex!("302fa00f300d06096086480165030402010500a11c301a06092a864886f70d010108300d06096086480165030402010500");
struct Sha1Mock {}
impl AssociatedOid for Sha1Mock {
const OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.14.3.2.26");
}
struct Sha256Mock {}
impl AssociatedOid for Sha256Mock {
const OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("2.16.840.1.101.3.4.2.1");
}
#[test]
fn decode_pss_param() {
let param = RsaPssParams::try_from(RSA_PSS_PARAMETERS_SHA2_256).unwrap();
assert!(param
.hash
.assert_algorithm_oid(db::rfc5912::ID_SHA_256)
.is_ok());
assert_eq!(param.hash.parameters, Some(AnyRef::NULL));
assert!(param
.mask_gen
.assert_algorithm_oid(db::rfc5912::ID_MGF_1)
.is_ok());
assert!(param
.mask_gen
.parameters
.unwrap()
.assert_algorithm_oid(db::rfc5912::ID_SHA_256)
.is_ok());
assert_eq!(param.salt_len, 32);
assert_eq!(param.trailer_field, TrailerField::BC);
}
#[test]
fn encode_pss_param() {
let mut buf = [0_u8; 256];
let param = RsaPssParams::try_from(RSA_PSS_PARAMETERS_SHA2_256).unwrap();
assert_eq!(
param.encode_to_slice(&mut buf).unwrap(),
RSA_PSS_PARAMETERS_SHA2_256
);
}
#[test]
fn decode_pss_param_default() {
let param = RsaPssParams::try_from(RSA_PSS_PARAMETERS_DEFAULTS).unwrap();
assert!(param
.hash
.assert_algorithm_oid(db::rfc5912::ID_SHA_1)
.is_ok());
assert_eq!(param.hash.parameters, Some(AnyRef::NULL));
assert!(param
.mask_gen
.assert_algorithm_oid(db::rfc5912::ID_MGF_1)
.is_ok());
assert!(param
.mask_gen
.parameters
.unwrap()
.assert_algorithm_oid(db::rfc5912::ID_SHA_1)
.is_ok());
assert_eq!(
param.mask_gen.parameters.unwrap().parameters,
Some(AnyRef::NULL)
);
assert_eq!(param.salt_len, 20);
assert_eq!(param.trailer_field, TrailerField::BC);
assert_eq!(param, Default::default())
}
#[test]
fn encode_pss_param_default() {
let mut buf = [0_u8; 256];
assert_eq!(
RsaPssParams::default().encode_to_slice(&mut buf).unwrap(),
RSA_PSS_PARAMETERS_DEFAULTS
);
}
#[test]
fn new_pss_param() {
let mut buf = [0_u8; 256];
let param = RsaPssParams::new::<Sha1Mock>(20);
assert_eq!(
param.encode_to_slice(&mut buf).unwrap(),
RSA_PSS_PARAMETERS_DEFAULTS
);
let param = RsaPssParams::new::<Sha256Mock>(32);
assert_eq!(
param.encode_to_slice(&mut buf).unwrap(),
RSA_PSS_PARAMETERS_SHA2_256
);
}
#[test]
fn decode_oaep_param() {
let param = RsaOaepParams::try_from(RSA_OAEP_PARAMETERS_SHA2_256).unwrap();
assert!(param
.hash
.assert_algorithm_oid(db::rfc5912::ID_SHA_256)
.is_ok());
assert_eq!(param.hash.parameters, Some(AnyRef::NULL));
assert!(param
.mask_gen
.assert_algorithm_oid(db::rfc5912::ID_MGF_1)
.is_ok());
assert!(param
.mask_gen
.parameters
.unwrap()
.assert_algorithm_oid(db::rfc5912::ID_SHA_256)
.is_ok());
assert!(param
.p_source
.assert_algorithm_oid(db::rfc5912::ID_P_SPECIFIED)
.is_ok());
assert!(param
.p_source
.parameters_any()
.unwrap()
.decode_as::<OctetStringRef<'_>>()
.unwrap()
.is_empty(),);
}
#[test]
fn encode_oaep_param() {
let mut buf = [0_u8; 256];
let param = RsaOaepParams::try_from(RSA_OAEP_PARAMETERS_SHA2_256).unwrap();
assert_eq!(
param.encode_to_slice(&mut buf).unwrap(),
RSA_OAEP_PARAMETERS_SHA2_256
);
}
#[test]
fn decode_oaep_param_default() {
let param = RsaOaepParams::try_from(RSA_OAEP_PARAMETERS_DEFAULTS).unwrap();
assert!(param
.hash
.assert_algorithm_oid(db::rfc5912::ID_SHA_1)
.is_ok());
assert_eq!(param.hash.parameters, Some(AnyRef::NULL));
assert!(param
.mask_gen
.assert_algorithm_oid(db::rfc5912::ID_MGF_1)
.is_ok());
assert!(param
.mask_gen
.parameters
.unwrap()
.assert_algorithm_oid(db::rfc5912::ID_SHA_1)
.is_ok());
assert_eq!(
param.mask_gen.parameters.unwrap().parameters,
Some(AnyRef::NULL)
);
assert!(param
.p_source
.assert_algorithm_oid(db::rfc5912::ID_P_SPECIFIED)
.is_ok());
assert!(param
.p_source
.parameters_any()
.unwrap()
.decode_as::<OctetStringRef<'_>>()
.unwrap()
.is_empty(),);
assert_eq!(param, Default::default())
}
#[test]
fn encode_oaep_param_default() {
let mut buf = [0_u8; 256];
assert_eq!(
RsaOaepParams::default().encode_to_slice(&mut buf).unwrap(),
RSA_OAEP_PARAMETERS_DEFAULTS
);
}
#[test]
fn new_oaep_param() {
let mut buf = [0_u8; 256];
let param = RsaOaepParams::new::<Sha1Mock>();
assert_eq!(
param.encode_to_slice(&mut buf).unwrap(),
RSA_OAEP_PARAMETERS_DEFAULTS
);
let param = RsaOaepParams::new::<Sha256Mock>();
println!("{:02x?}", param.encode_to_slice(&mut buf).unwrap());
assert_eq!(
param.encode_to_slice(&mut buf).unwrap(),
RSA_OAEP_PARAMETERS_SHA2_256
);
}

94
vendor/pkcs1/tests/private_key.rs vendored Normal file
View File

@@ -0,0 +1,94 @@
//! PKCS#1 private key tests
use hex_literal::hex;
use pkcs1::{RsaPrivateKey, Version};
/// RSA-2048 PKCS#1 private key encoded as ASN.1 DER.
///
/// Note: this key is extracted from the corresponding `rsa2048-priv.der`
/// example key in the `pkcs8` crate.
const RSA_2048_DER_EXAMPLE: &[u8] = include_bytes!("examples/rsa2048-priv.der");
/// RSA-4096 PKCS#1 private key encoded as ASN.1 DER
const RSA_4096_DER_EXAMPLE: &[u8] = include_bytes!("examples/rsa4096-priv.der");
/// RSA-2048 PKCS#1 private key with 3 primes encoded as ASN.1 DER
const RSA_2048_MULTI_PRIME_DER_EXAMPLE: &[u8] = include_bytes!("examples/rsa2048-priv-3prime.der");
#[test]
fn decode_rsa2048_der() {
let key = RsaPrivateKey::try_from(RSA_2048_DER_EXAMPLE).unwrap();
assert_eq!(key.version(), Version::TwoPrime);
// Extracted using:
// $ openssl asn1parse -in tests/examples/rsa2048-priv.pem
assert_eq!(key.modulus.as_bytes(), hex!("B6C42C515F10A6AAF282C63EDBE24243A170F3FA2633BD4833637F47CA4F6F36E03A5D29EFC3191AC80F390D874B39E30F414FCEC1FCA0ED81E547EDC2CD382C76F61C9018973DB9FA537972A7C701F6B77E0982DFC15FC01927EE5E7CD94B4F599FF07013A7C8281BDF22DCBC9AD7CABB7C4311C982F58EDB7213AD4558B332266D743AED8192D1884CADB8B14739A8DADA66DC970806D9C7AC450CB13D0D7C575FB198534FC61BC41BC0F0574E0E0130C7BBBFBDFDC9F6A6E2E3E2AFF1CBEAC89BA57884528D55CFB08327A1E8C89F4E003CF2888E933241D9D695BCBBACDC90B44E3E095FA37058EA25B13F5E295CBEAC6DE838AB8C50AF61E298975B872F"));
assert_eq!(key.public_exponent.as_bytes(), hex!("010001"));
assert_eq!(key.private_exponent.as_bytes(), hex!("7ECC8362C0EDB0741164215E22F74AB9D91BA06900700CF63690E5114D8EE6BDCFBB2E3F9614692A677A083F168A5E52E5968E6407B9D97C6E0E4064F82DA0B758A14F17B9B7D41F5F48E28D6551704F56E69E7AA9FA630FC76428C06D25E455DCFC55B7AC2B4F76643FDED3FE15FF78ABB27E65ACC4AAD0BDF6DB27EF60A6910C5C4A085ED43275AB19C1D997A32C6EFFCE7DF2D1935F6E601EEDE161A12B5CC27CA21F81D2C99C3D1EA08E90E3053AB09BEFA724DEF0D0C3A3C1E9740C0D9F76126A149EC0AA7D8078205484254D951DB07C4CF91FB6454C096588FD5924DBABEB359CA2025268D004F9D66EB3D6F7ADC1139BAD40F16DDE639E11647376C1"));
assert_eq!(key.prime1.as_bytes(), hex!("DCC061242D4E92AFAEE72AC513CA65B9F77036F9BD7E0E6E61461A7EF7654225EC153C7E5C31A6157A6E5A13FF6E178E8758C1CB33D9D6BBE3179EF18998E422ECDCBED78F4ECFDBE5F4FCD8AEC2C9D0DC86473CA9BD16D9D238D21FB5DDEFBEB143CA61D0BD6AA8D91F33A097790E9640DBC91085DC5F26343BA3138F6B2D67"));
assert_eq!(key.prime2.as_bytes(), hex!("D3F314757E40E954836F92BE24236AF2F0DA04A34653C180AF67E960086D93FDE65CB23EFD9D09374762F5981E361849AF68CDD75394FF6A4E06EB69B209E4228DB2DFA70E40F7F9750A528176647B788D0E5777A2CB8B22E3CD267FF70B4F3B02D3AAFB0E18C590A564B03188B0AA5FC48156B07622214243BD1227EFA7F2F9"));
assert_eq!(key.exponent1.as_bytes(), hex!("CE68B7AC1B0D100D636E55488753C5C09843FDB390E2705DF7689457C9BD8D9765E30978617E2EFC8048F4C324206DB86087B654E97BB3D464E7EE3F8CD83FE10436F7DF18E9A963C4E64911D67EDE34042F2E26E3D3A1AD346ADAD6B9B7F67708CB094E62DEE9FF4D5D6669AF988AF2255D1CE8ED317C6A7D8691DA354D12DB"));
assert_eq!(key.exponent2.as_bytes(), hex!("25F6E5944220286B4DFBBF4235C0EE5843D2198091895120D6CA7B200B826D3ECE738E2E00498FAC0A2A6CA969C7F0C3CA1AB0BC40297132BE7538D7BEDF4CB0EFC6B98EF7DBA54F56AA99AABCE534C49C27947D4678C51C63C78C7CE1687231B4C8EB587AE6EF0480CBAF4FC0173CFD587A7E67AF515FB9B9DE751118397229"));
assert_eq!(key.coefficient.as_bytes(), hex!("31995406D406207CADEAEA35B38D040C5F8A9A1AE0827E9ED06B153D83B6821935B4B36A82BE9D56C791B58C27271A5793D53A1D657C08997960B1433E5171987F452F144A7C72306D63E1D3FFC0B71B75AB08F2E45A482E988451CBE478E12EB228D07456C924B66F6CED048D853F533E31A68614F1C3CE6D8EC9983CE72AF7"));
assert!(key.other_prime_infos.is_none());
}
#[test]
fn decode_rsa4096_der() {
let key = RsaPrivateKey::try_from(RSA_4096_DER_EXAMPLE).unwrap();
assert_eq!(key.version(), Version::TwoPrime);
// Extracted using:
// $ openssl asn1parse -in tests/examples/rsa4096-priv.pem
assert_eq!(key.modulus.as_bytes(), hex!("A7A74572811EA2617E49E85BD730DDE30F103F7D88EE3F765E540D3DD993BBB0BA140002859D0B40897436637F58B828EA74DF8321634077F99D4AA2D54CA375852EF597661D3713CE1EF3B4FD6A8E220238E467668A2C7EE3861D2212AE6A1EBDDFA88B62DF10F6BCF79EFF4AC298FB2563DF1B8764381AF9B1FB0CCD085E026B0AD9F6721A235177D0396B48754AD4A75242250A873BF2F6E7EE3C75DD613E365BA4F3210A6CC66B90A2FA3F762CA6884087B6BF8161EB144819F0F572F21F6C8E273E70D45A365B8B2819CE734613CC23B01329A17901F17078403861F54C52A051E2A58C75C2D9D80091BB9808A106C1F7ECB4034E15058BEEC725C5F919D62EAA234B62628D346C60BB919E70851DAB38571E6F0ED7634129F994EA368FEE7373DFDEC04445EBCA47FA20ED1540A860C948BABC98DA591CA1DE2E2E25540EF9B7CB353F60213B814A45D359EFA9B811EEFF08C65993BF8A85C2BFEAAA7ED5E6B43E18AE604464CE5F96150136E7D09F8B24FAD43D7870118CFA7BC24875506EBBC321B977E0861AEA50128620121F0B394A9CDD0A42411A1350C0770D975D71B00A90436240C967A0C3A5C20A0F6DE77F3F2CAFDA94ED0143C1F6E34F73E0CAC279EEEB7C637723A2B026C82802E1A4AEBAA8846DF98E7919498773E0D4F319956F4DE3AAD00EFB9A147D66B3AC1A01D35B2CFB48D400B0E7A80DC97551"));
assert_eq!(key.public_exponent.as_bytes(), hex!("010001"));
assert_eq!(key.private_exponent.as_bytes(), hex!("9FE3097B2322B90FAB6606C017A095EBE640C39C100BCEE02F238FA14DAFF38E9E57568F1127ED4436126B904631B127EC395BB3EE127EB82C88D2562A7FB55FED8D1450B7E4E2D2F37F5742636FCC6F289963522D5B5706082CADFA01C0EE99B4D0E9274D3A992E06974CBE01694686356962AC1959FD9BD447E5B9968C0543DF1BF134742AF345CDB2FA1F9371B0D4CF61C68D16D653D8E999D4FD3A16CF978A35AA40E860CDCE09655DD8B4CF19D4141B1E92AD5E51A8E4A5C27FA745611D90E49D0E9282222AB6F126643E1C77578816FCE3B98F321D2549F294A470DF8453446BF36F985DF25ED8FDE9FDF3073FB27727DF48E9E1FC7056BC78965090B7850126406462C8253051EF84E34EE3C3CEB8F96C658C38BE45558D2F64E29D223350555FC1EFA28EC1F4AFB5BA4080F09A86CDC3538C1AD7C972E6D7A3612E6845BA9AFBDF19F09060D1A779DE9635E2D2F8E0C510BA24C6C44B30C9BDFAF85BE917AEC5D43AFAB1AA3ADD33CC83DA93CAC69218F6A36EB47F199D5424C95FD9ED7B1E8BE2AEAA6433B227241316C20EE792650CEB48BFD634446B19D286B4EA1722498DA1A36973210EC3824751A5808D9AAEF59C449E19A5077CFECA126BD9A8DD4996561D4E27B3609FF82C5B1B21E627845D44961B33B875D5C4FA9FF357EF6BE3364969E1337C91B29A07B9A913CDE40CE2D5530C900E73751685E65431"));
assert_eq!(key.prime1.as_bytes(), hex!("D0213A79425B665B719118448893EC3275600F63DBF85B77F4E8E99EF302F6E82596048F6DCA772DE6BBF1124DB84B0AFE61B03A8604AB0079ED53F3304797AD01B38C44FE27A5A45E378483A804B56A4A967F48F01A866E721E67E4C9A1048AF68927FAA43D6A85D93E7BF7074DBA797563FCABE12309B76653C6DB614DC231CC556D9F25AC4841A02D31CDF3015B212307F9D0C79FEB5D3956CE53CC8FA1651BE60761F19F74672489EAF9F215409F39956E77A82183F1F72BB2FEDDF1B9FBFC4AD89EA445809DDBD5BD595277990C0BE9366FBB2ECF7B057CC1C3DC8FB77BF8456D07BBC95B3C1815F48E62B81468C3D4D9D96C0F48DAB04993BE8D91EDE5"));
assert_eq!(key.prime2.as_bytes(), hex!("CE36C6810522ABE5D6465F36EB137DA3B9EA4A5F1D27C6614729EB8E5E2E5CB88E3EF1A473A21944B66557B3DC2CE462E4BF3446CB4990037E5672B1705CBAE81B65BAF967A266DC18EFE80F4DBBFE1A59063205CE2943CADF421CCE74AF7063FD1A83AF3C39AF84525F59BDC1FF54815F52AFD1E8D4862B2C3654F6CFA83DC08E2A9D52B9F833C646AF7694467DFC5F7D7AD7B441895FCB7FFBED526324B0154A15823F5107C89548EDDCB61DA5308C6CC834D4A0C16DFA6CA1D67B61A65677EB1719CD125D0EF0DB8802FB76CFC17577BCB2510AE294E1BF8A9173A2B85C16A6B508C98F2D770B7F3DE48D9E720C53E263680B57E7109410015745570652FD"));
assert_eq!(key.exponent1.as_bytes(), hex!("748B46CD03E55E69B22C476488FE1BF31D5ACF0361F7AE707B89B8D832C7E42E966D6CDC4BE465DC2429F5920447406E4587BA40EB2ECDFA944BDB08806E7676804F642A760F096803021F88019BB16275A5D45CA9669104638EB72A9BE538400051493BC6A04577F1F055463CA6BFD6A76F77DB5F54596A83384250322A72A5A3FFEA4485B9F5341A57745E18C7179A749D50BC222C60857148347D243D016936B816463820CBF3BDB825061512E57EC3A5F397B9641B187109DD4F6E449F9A84E9FC66C921CA259B2612C363B468D5200E5557377FBCDAEC75B1A2D56CFC97C4AC4BA35AFA23C680CE3A8548AE3F6F72C94BBBBE10C900FC5A170B4B06FE29"));
assert_eq!(key.exponent2.as_bytes(), hex!("75CA4E0B069EEE67C3C4C0C082F8C82C8C96EAD277B9EF94436D0B936FF2B59DEA0AC446B6926232A0A934B6954EC34A45F57DEBEE54DFC14F1A1C3B84BE43392FE5252F2F6651B0E941A8618D7A93C4031409E0CD093F2313F214B84D68A51F48452BF11DCAA99A40DF1C48CB1688F3B93A6719D510086F82BAAA3FAD1021EDEA872704491C209EE26379AD6AB2AE44F14D09077AE3F8672A7D01EBAC9C19449FE3B7596974B3BBAA43CC6DEE731C4F2A18162D5A8202CB27E02DBE9E61C0449171C9981D2430D39DE28C298D8D50A943B2F27C5E665CBAB2897959FF19A5E87E632C58CDC31F9BDE9BC100AFFFDF50CF210F1E63A0A6149D2BD6E8D1B3D815"));
assert_eq!(key.coefficient.as_bytes(), hex!("8C557C4835E8B4066606A5DC255DBC3EB5F1586C7328988C8E242403F9575EFB0D28012C0634B7241768AD722049382906D635AFCB1D2A05BDFFC805FE670389B7FA90D65F94AFBC2008D9BC0D3CCEE425DFC72402050603C9F579EE8510ECC693AC6DD32836B6E15E3DC520366A1BA4AFC91D3E48A4D6724CA42443F4803E3B12634B0438572D8E13BC72F1A82853B8D9FCA6199D7A90AB64D9E79F793AC287F9A19011082A5268F209332D54D98D6E19030907FD9E6B82EF124677BA08AD6797A442213D097A351C50A08928DD732D6B29A6CF6706DAF5F20F78F87170FB279403C5221B5E5C70C2BAA0E69A72E0D1F3267DBD8C9BDDFF28AFA92F37C98D36"));
assert!(key.other_prime_infos.is_none());
}
#[cfg(not(feature = "alloc"))]
#[test]
fn decode_rsa2048_multi_prime_der() {
// Multi-prime RSA keys are unsupported when the alloc feature is disabled
assert!(RsaPrivateKey::try_from(RSA_2048_MULTI_PRIME_DER_EXAMPLE).is_err());
}
#[cfg(feature = "alloc")]
#[test]
fn decode_rsa2048_multi_prime_der() {
let key = RsaPrivateKey::try_from(RSA_2048_MULTI_PRIME_DER_EXAMPLE).unwrap();
assert_eq!(key.version(), Version::Multi);
// Extracted using:
// $ openssl asn1parse -in tests/examples/rsa2048-priv-3prime.pem
assert_eq!(key.modulus.as_bytes(), hex!("E8BF46480D9144E93D0E7971554F7EF45FB25B83A1069416DB8EC7C654EB489C695A3274EE4B5F3A08E35BA6D1FF2EC487CE544641EA0C0994CC554D2201308E3AC6491326183F477D30F165001800B38771BF96F69DE6D461A6E2F88057104FCDD6C6A1B69E7F95A27DAC0CBAE39CC1F9264C09DFEEA68477482C2816133012BA29A0D617FA6C6B70FAC3BEDCB020CB1F6EA3375163988E7F8C9474B5462C24D2B56BC03F9ED002E43C764B1E7B05C31EC7D8E91582CEC0942F396DAB94F3162D1AAA041DA99CEE90B81FF408BB75B7B233B19D34E504E258C1D774706E4C5FC2B11F97C9E4CEEAC345F8C57C3D3702F73FC98F7EED688812BE9B560618C245"));
assert_eq!(key.public_exponent.as_bytes(), hex!("010001"));
assert_eq!(key.private_exponent.as_bytes(), hex!("51ADA6656CD579207CFBD2649272B673DE0D828E1BF96A08E77E20DF9A3783A0D85BFDEF091D4C4ADA89A74550D6C3BBD688F30C40DF78DFF7E7095C6B3D8DA3AC3E9FB067A304B9FAD62D30ABAAC0BC40210C025759A374034864308AF6E444C6BEEA4FEA12DB78A9705A0F0C8B732B3FD733C5877A871ECC58FAB25D4236D0C91F207D6FC79ED5568658623984EF992C85EA7BFFC7F8C18368E644289198B64CF368C0FDEFFA7E24B65D895B701F8AF70AEAB0BB7D2E14C4354E15BE4723EC885DF146D7B0C6D2844C14DF639DDA9C7933FFFBD5AE2308B2A9CE7E6C52E3766106B8FEF8D593B88491BCED68632045E0E2FB889A58ED2FF28B6E5E2082BB01"));
assert_eq!(key.prime1.as_bytes(), hex!("07EA41E3B0B6FA6337D8D254B21F06C237FDAA6442B3B2756A479B27273CECCFBB5F472AA5D941E11DA1AAEB176450FC044EA639EF6E6B77B530D98A43ACF2D39571714EED516BBF43A7079E640CA46AE640CCAE46B5"));
assert_eq!(key.prime2.as_bytes(), hex!("077E9210399453F1F9D6AD862B4D83EE8651F92354BC4F22B1A5376ED36FE80DCFDDF73CEEB326972265B5CAC21E2F5FF22F09E6EA0AF358540004D6D1EF3A82BE214D206B25F98F0F3BAF8CD4F25D7169ACC99809A9"));
assert_eq!(key.exponent1.as_bytes(), hex!("02362298C27C2D73615C345033C0557C1876C88FE0CF227289F25DD84FAF471F3764049756E55FF1CCFCA9ABABCA7C921D85F80DC1E72121BE3F5AD8B5D5F1B6CA4F7AF0298091514C4EB3E33E6305E1545A109634ED"));
assert_eq!(key.exponent2.as_bytes(), hex!("830FFD55C1A13E6D7FD1D8D18A7911C9513E40C0A02093D128E53187F62417157527579D42D5C70B4D816EB976106C7081F01E3B2CC654E9601AF485E0DED161A5AABC2535B1E7A8F5BDD75410BE7B69E9A8D7DF09"));
assert_eq!(key.coefficient.as_bytes(), hex!("03B54C52199604D9A920B1B7AB95F0B474BA46796CC46C3E63C483499071BFADC0D27321EBD53E09271F28646B7590C97102F9E458A93B3A024A03565BCAFFA15F73C05BBF9653BE23224A1E35524A9895641C76FD2E"));
let other_prime_infos = key.other_prime_infos.unwrap();
assert_eq!(other_prime_infos.len(), 1);
assert_eq!(other_prime_infos[0].prime.as_bytes(), hex!("03EC75532FB0D2CA142632618EA698548D8489FE30A868D637A1D53895C79F16A63ADB60DB217DDC0D95694A3D95D029D1A9A2DF548ED105B2C6A84855739EDBC3CE82906500241D518A3172F8D470FADD4E1DFE5969"));
assert_eq!(other_prime_infos[0].exponent.as_bytes(), hex!("03A11508A3E52FA4412CEF8EF34EBF39FE48690758647DCC1F5B2E890F69BC8A4BA9C73F78912B047F00038AEB1A069897D90BD0FD3AB8B6479D9F0C8115D80BB8BAEC63B9387F2F2B3BE2EF509FD7FD02F47DA3C579"));
assert_eq!(other_prime_infos[0].coefficient.as_bytes(), hex!("39EA226CABFB317E41A5593B9168D1A0124993B45D9CD14A22BD1557CDCB43D28024AC26ED2C8530B53E9B93A878F428807C5282EBB811399F913017CDF2149013D80CDF73F609D6C692475EB7A123D0E93E6A60FC"));
}
#[test]
fn private_key_to_public_key() {
let private_key = RsaPrivateKey::try_from(RSA_2048_DER_EXAMPLE).unwrap();
let public_key = private_key.public_key();
// Extracted using:
// $ openssl asn1parse -in tests/examples/rsa2048-pub.pem
assert_eq!(public_key.modulus.as_bytes(), hex!("B6C42C515F10A6AAF282C63EDBE24243A170F3FA2633BD4833637F47CA4F6F36E03A5D29EFC3191AC80F390D874B39E30F414FCEC1FCA0ED81E547EDC2CD382C76F61C9018973DB9FA537972A7C701F6B77E0982DFC15FC01927EE5E7CD94B4F599FF07013A7C8281BDF22DCBC9AD7CABB7C4311C982F58EDB7213AD4558B332266D743AED8192D1884CADB8B14739A8DADA66DC970806D9C7AC450CB13D0D7C575FB198534FC61BC41BC0F0574E0E0130C7BBBFBDFDC9F6A6E2E3E2AFF1CBEAC89BA57884528D55CFB08327A1E8C89F4E003CF2888E933241D9D695BCBBACDC90B44E3E095FA37058EA25B13F5E295CBEAC6DE838AB8C50AF61E298975B872F"));
assert_eq!(public_key.public_exponent.as_bytes(), hex!("010001"));
}

64
vendor/pkcs1/tests/public_key.rs vendored Normal file
View File

@@ -0,0 +1,64 @@
//! PKCS#1 public key tests
use hex_literal::hex;
use pkcs1::RsaPublicKey;
/// RSA-2048 PKCS#1 public key encoded as ASN.1 DER.
///
/// Note: this key is extracted from the corresponding `rsa2048-priv.der`
/// example key in the `pkcs8` crate.
const RSA_2048_DER_EXAMPLE: &[u8] = include_bytes!("examples/rsa2048-pub.der");
/// RSA-4096 PKCS#1 public key encoded as ASN.1 DER
const RSA_4096_DER_EXAMPLE: &[u8] = include_bytes!("examples/rsa4096-pub.der");
// /// RSA-2048 PKCS#1 public key encoded as PEM
// #[cfg(feature = "pem")]
// const RSA_2048_PEM_EXAMPLE: &str = include_str!("examples/rsa2048-pub.pem");
//
// /// RSA-4096 PKCS#1 public key encoded as PEM
// #[cfg(feature = "pem")]
// const RSA_4096_PEM_EXAMPLE: &str = include_str!("examples/rsa4096-pub.pem");
#[test]
fn decode_rsa2048_der() {
let key = RsaPublicKey::try_from(RSA_2048_DER_EXAMPLE).unwrap();
// Extracted using:
// $ openssl asn1parse -in tests/examples/rsa2048-pub.pem
assert_eq!(key.modulus.as_bytes(), hex!("B6C42C515F10A6AAF282C63EDBE24243A170F3FA2633BD4833637F47CA4F6F36E03A5D29EFC3191AC80F390D874B39E30F414FCEC1FCA0ED81E547EDC2CD382C76F61C9018973DB9FA537972A7C701F6B77E0982DFC15FC01927EE5E7CD94B4F599FF07013A7C8281BDF22DCBC9AD7CABB7C4311C982F58EDB7213AD4558B332266D743AED8192D1884CADB8B14739A8DADA66DC970806D9C7AC450CB13D0D7C575FB198534FC61BC41BC0F0574E0E0130C7BBBFBDFDC9F6A6E2E3E2AFF1CBEAC89BA57884528D55CFB08327A1E8C89F4E003CF2888E933241D9D695BCBBACDC90B44E3E095FA37058EA25B13F5E295CBEAC6DE838AB8C50AF61E298975B872F"));
assert_eq!(key.public_exponent.as_bytes(), hex!("010001"));
}
#[test]
fn decode_rsa4096_der() {
let key = RsaPublicKey::try_from(RSA_4096_DER_EXAMPLE).unwrap();
// Extracted using:
// $ openssl asn1parse -in tests/examples/rsa4096-pub.pem
assert_eq!(key.modulus.as_bytes(), hex!("A7A74572811EA2617E49E85BD730DDE30F103F7D88EE3F765E540D3DD993BBB0BA140002859D0B40897436637F58B828EA74DF8321634077F99D4AA2D54CA375852EF597661D3713CE1EF3B4FD6A8E220238E467668A2C7EE3861D2212AE6A1EBDDFA88B62DF10F6BCF79EFF4AC298FB2563DF1B8764381AF9B1FB0CCD085E026B0AD9F6721A235177D0396B48754AD4A75242250A873BF2F6E7EE3C75DD613E365BA4F3210A6CC66B90A2FA3F762CA6884087B6BF8161EB144819F0F572F21F6C8E273E70D45A365B8B2819CE734613CC23B01329A17901F17078403861F54C52A051E2A58C75C2D9D80091BB9808A106C1F7ECB4034E15058BEEC725C5F919D62EAA234B62628D346C60BB919E70851DAB38571E6F0ED7634129F994EA368FEE7373DFDEC04445EBCA47FA20ED1540A860C948BABC98DA591CA1DE2E2E25540EF9B7CB353F60213B814A45D359EFA9B811EEFF08C65993BF8A85C2BFEAAA7ED5E6B43E18AE604464CE5F96150136E7D09F8B24FAD43D7870118CFA7BC24875506EBBC321B977E0861AEA50128620121F0B394A9CDD0A42411A1350C0770D975D71B00A90436240C967A0C3A5C20A0F6DE77F3F2CAFDA94ED0143C1F6E34F73E0CAC279EEEB7C637723A2B026C82802E1A4AEBAA8846DF98E7919498773E0D4F319956F4DE3AAD00EFB9A147D66B3AC1A01D35B2CFB48D400B0E7A80DC97551"));
assert_eq!(key.public_exponent.as_bytes(), hex!("010001"));
}
// TODO(tarcieri): test trait-based PEM decoding
// #[test]
// #[cfg(feature = "pem")]
// fn decode_rsa_2048_pem() {
// let pkcs1_doc: Document = RSA_2048_PEM_EXAMPLE.parse().unwrap();
// assert_eq!(pkcs1_doc.as_ref(), RSA_2048_DER_EXAMPLE);
//
// // Ensure `Document` parses successfully
// let pk = RsaPublicKey::try_from(RSA_2048_DER_EXAMPLE).unwrap();
// assert_eq!(pkcs1_doc.decode().modulus.as_bytes(), pk.modulus.as_bytes());
// }
//
// #[test]
// #[cfg(feature = "pem")]
// fn decode_rsa_4096_pem() {
// let pkcs1_doc: Document = RSA_4096_PEM_EXAMPLE.parse().unwrap();
// assert_eq!(pkcs1_doc.as_ref(), RSA_4096_DER_EXAMPLE);
//
// // Ensure `Document` parses successfully
// let pk = RsaPublicKey::try_from(RSA_4096_DER_EXAMPLE).unwrap();
// assert_eq!(pkcs1_doc.decode().modulus.as_bytes(), pk.modulus.as_bytes());
// }

100
vendor/pkcs1/tests/traits.rs vendored Normal file
View File

@@ -0,0 +1,100 @@
//! Tests for PKCS#1 encoding/decoding traits.
#![cfg(any(feature = "pem", feature = "std"))]
use der::SecretDocument;
use pkcs1::{DecodeRsaPrivateKey, EncodeRsaPrivateKey, Result};
#[cfg(feature = "pem")]
use pkcs1::der::pem::LineEnding;
#[cfg(feature = "std")]
use tempfile::tempdir;
#[cfg(all(feature = "pem", feature = "std"))]
use std::fs;
/// PKCS#1 `RsaPrivateKey` encoded as ASN.1 DER
const RSA_2048_PRIV_DER_EXAMPLE: &[u8] = include_bytes!("examples/rsa2048-priv.der");
/// PKCS#1 `RsaPrivateKey` encoded as PEM
#[cfg(feature = "pem")]
const RSA_2048_PRIV_PEM_EXAMPLE: &str = include_str!("examples/rsa2048-priv.pem");
/// Mock RSA private key type for testing trait impls against.
pub struct MockPrivateKey(Vec<u8>);
impl AsRef<[u8]> for MockPrivateKey {
fn as_ref(&self) -> &[u8] {
self.0.as_ref()
}
}
impl DecodeRsaPrivateKey for MockPrivateKey {
fn from_pkcs1_der(bytes: &[u8]) -> Result<MockPrivateKey> {
Ok(MockPrivateKey(bytes.to_vec()))
}
}
impl EncodeRsaPrivateKey for MockPrivateKey {
fn to_pkcs1_der(&self) -> Result<SecretDocument> {
Ok(SecretDocument::try_from(self.as_ref())?)
}
}
#[cfg(feature = "pem")]
#[test]
fn from_pkcs1_pem() {
let key = MockPrivateKey::from_pkcs1_pem(RSA_2048_PRIV_PEM_EXAMPLE).unwrap();
assert_eq!(key.as_ref(), RSA_2048_PRIV_DER_EXAMPLE);
}
#[cfg(feature = "std")]
#[test]
fn read_pkcs1_der_file() {
let key = MockPrivateKey::read_pkcs1_der_file("tests/examples/rsa2048-priv.der").unwrap();
assert_eq!(key.as_ref(), RSA_2048_PRIV_DER_EXAMPLE);
}
#[cfg(all(feature = "pem", feature = "std"))]
#[test]
fn read_pkcs1_pem_file() {
let key = MockPrivateKey::read_pkcs1_pem_file("tests/examples/rsa2048-priv.pem").unwrap();
assert_eq!(key.as_ref(), RSA_2048_PRIV_DER_EXAMPLE);
}
#[cfg(feature = "pem")]
#[test]
fn to_pkcs1_pem() {
let pem = MockPrivateKey(RSA_2048_PRIV_DER_EXAMPLE.to_vec())
.to_pkcs1_pem(LineEnding::LF)
.unwrap();
assert_eq!(&*pem, RSA_2048_PRIV_PEM_EXAMPLE);
}
#[cfg(feature = "std")]
#[test]
fn write_pkcs1_der_file() {
let dir = tempdir().unwrap();
let path = dir.path().join("example.der");
MockPrivateKey(RSA_2048_PRIV_DER_EXAMPLE.to_vec())
.write_pkcs1_der_file(&path)
.unwrap();
let key = MockPrivateKey::read_pkcs1_der_file(&path).unwrap();
assert_eq!(key.as_ref(), RSA_2048_PRIV_DER_EXAMPLE);
}
#[cfg(all(feature = "pem", feature = "std"))]
#[test]
fn write_pkcs1_pem_file() {
let dir = tempdir().unwrap();
let path = dir.path().join("example.pem");
MockPrivateKey(RSA_2048_PRIV_DER_EXAMPLE.to_vec())
.write_pkcs1_pem_file(&path, LineEnding::LF)
.unwrap();
let pem = fs::read_to_string(path).unwrap();
assert_eq!(&pem, RSA_2048_PRIV_PEM_EXAMPLE);
}