diff options
author | Sam Saccone <samccone@google.com> | 2023-12-19 02:31:34 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-12-19 02:31:34 +0000 |
commit | 6f70111424f41c228553cef46ec4dc3892ca0a11 (patch) | |
tree | abcaf72f2f0f52ce70640b5a62b89492b7c7876e | |
parent | f284a252d6fcdf60d83d027bab796ecc60821146 (diff) | |
parent | c85edc5f47f81e9b14ac87b70d44d1d1994760d2 (diff) | |
download | pkcs1-6f70111424f41c228553cef46ec4dc3892ca0a11.tar.gz |
Revert "Upgrade pkcs1 to 0.7.5" am: e49e8188d6 am: c85edc5f47
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/pkcs1/+/2881630
Change-Id: I9177711d6dd88d8f2fdc6910c808fbe80bb4dae9
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | .cargo_vcs_info.json | 2 | ||||
-rw-r--r-- | Android.bp | 10 | ||||
-rw-r--r-- | CHANGELOG.md | 52 | ||||
-rw-r--r-- | Cargo.toml | 24 | ||||
-rw-r--r-- | Cargo.toml.orig | 20 | ||||
-rw-r--r-- | LICENSE-MIT | 2 | ||||
-rw-r--r-- | METADATA | 21 | ||||
-rw-r--r-- | README.md | 4 | ||||
-rw-r--r-- | src/lib.rs | 20 | ||||
-rw-r--r-- | src/params.rs | 314 | ||||
-rw-r--r-- | src/private_key.rs | 93 | ||||
-rw-r--r-- | src/private_key/other_prime_info.rs | 29 | ||||
-rw-r--r-- | src/public_key.rs | 29 | ||||
-rw-r--r-- | src/traits.rs | 53 | ||||
-rw-r--r-- | src/version.rs | 2 | ||||
-rw-r--r-- | tests/params.rs | 137 |
16 files changed, 299 insertions, 513 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index 5350233..8acf345 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,6 +1,6 @@ { "git": { - "sha1": "750ae946d284810f582a9c9ad428549561b1ee03" + "sha1": "40fbcf36aa1d1e20685424576da37b7df0279d3b" }, "path_in_vcs": "pkcs1" }
\ No newline at end of file @@ -35,16 +35,19 @@ rust_library_host { name: "libpkcs1", crate_name: "pkcs1", cargo_env_compat: true, - cargo_pkg_version: "0.7.5", + cargo_pkg_version: "0.4.1", srcs: ["src/lib.rs"], edition: "2021", features: [ "alloc", + "pkcs8", "zeroize", ], rustlibs: [ "libder", + "libpkcs8", "libspki", + "libzeroize", ], } @@ -52,16 +55,19 @@ rust_library_rlib { name: "libpkcs1_nostd", crate_name: "pkcs1", cargo_env_compat: true, - cargo_pkg_version: "0.7.5", + cargo_pkg_version: "0.4.1", srcs: ["src/lib.rs"], edition: "2021", features: [ "alloc", + "pkcs8", "zeroize", ], rustlibs: [ "libder_nostd", + "libpkcs8_nostd", "libspki_nostd", + "libzeroize_nostd", ], apex_available: [ "//apex_available:platform", diff --git a/CHANGELOG.md b/CHANGELOG.md index e6b79c1..7e95122 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,58 +4,6 @@ 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]) @@ -11,9 +11,9 @@ [package] edition = "2021" -rust-version = "1.60" +rust-version = "1.57" name = "pkcs1" -version = "0.7.5" +version = "0.4.1" authors = ["RustCrypto Developers"] description = """ Pure Rust implementation of Public-Key Cryptography Standards (PKCS) #1: @@ -45,23 +45,28 @@ rustdoc-args = [ ] [dependencies.der] -version = "0.7" +version = "0.6" features = ["oid"] [dependencies.pkcs8] -version = "0.10" +version = "0.9" optional = true default-features = false [dependencies.spki] -version = "0.7" +version = "0.6" + +[dependencies.zeroize] +version = "1" +optional = true +default-features = false [dev-dependencies.const-oid] version = "0.9" features = ["db"] [dev-dependencies.hex-literal] -version = "0.4" +version = "0.3" [dev-dependencies.tempfile] version = "3" @@ -69,16 +74,15 @@ version = "3" [features] alloc = [ "der/alloc", - "zeroize", - "pkcs8?/alloc", + "pkcs8/alloc", + "zeroize/alloc", ] pem = [ "alloc", "der/pem", - "pkcs8?/pem", + "pkcs8/pem", ] std = [ "der/std", "alloc", ] -zeroize = ["der/zeroize"] diff --git a/Cargo.toml.orig b/Cargo.toml.orig index cdc15b4..fb1fa3f 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -1,6 +1,6 @@ [package] name = "pkcs1" -version = "0.7.5" +version = "0.4.1" description = """ Pure Rust implementation of Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography Specifications Version 2.2 (RFC 8017) @@ -12,24 +12,24 @@ categories = ["cryptography", "data-structures", "encoding", "no-std", "parser-i keywords = ["crypto", "key", "pem", "pkcs", "rsa"] readme = "README.md" edition = "2021" -rust-version = "1.60" +rust-version = "1.57" [dependencies] -der = { version = "0.7", features = ["oid"] } -spki = { version = "0.7" } +der = { version = "0.6", features = ["oid"], path = "../der" } +spki = { version = "0.6", path = "../spki" } # optional dependencies -pkcs8 = { version = "0.10", optional = true, default-features = false } +pkcs8 = { version = "0.9", optional = true, default-features = false, path = "../pkcs8" } +zeroize = { version = "1", optional = true, default-features = false } [dev-dependencies] -const-oid = { version = "0.9", features = ["db"] } # TODO: path = "../const-oid" -hex-literal = "0.4" +hex-literal = "0.3" tempfile = "3" +const-oid = { version = "0.9", path = "../const-oid", features = ["db"] } [features] -zeroize = ["der/zeroize"] -alloc = ["der/alloc", "zeroize", "pkcs8?/alloc"] -pem = ["alloc", "der/pem", "pkcs8?/pem"] +alloc = ["der/alloc", "pkcs8/alloc", "zeroize/alloc"] +pem = ["alloc", "der/pem", "pkcs8/pem"] std = ["der/std", "alloc"] [package.metadata.docs.rs] diff --git a/LICENSE-MIT b/LICENSE-MIT index 3294d74..68ddaa3 100644 --- a/LICENSE-MIT +++ b/LICENSE-MIT @@ -1,4 +1,4 @@ -Copyright (c) 2021-2023 The RustCrypto Project Developers +Copyright (c) 2021-2022 The RustCrypto Project Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated @@ -1,20 +1,23 @@ # This project was upgraded with external_updater. # Usage: tools/external_updater/updater.sh update rust/crates/pkcs1 -# For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md +# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md name: "pkcs1" description: "Pure Rust implementation of Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography Specifications Version 2.2 (RFC 8017)." third_party { + url { + type: HOMEPAGE + value: "https://crates.io/crates/pkcs1" + } + url { + type: ARCHIVE + value: "https://static.crates.io/crates/pkcs1/pkcs1-0.4.1.crate" + } + version: "0.4.1" license_type: NOTICE last_upgrade_date { - year: 2023 + year: 2022 month: 12 - day: 15 - } - homepage: "https://crates.io/crates/pkcs1" - identifier { - type: "Archive" - value: "https://static.crates.io/crates/pkcs1/pkcs1-0.7.5.crate" - version: "0.7.5" + day: 13 } } @@ -31,7 +31,7 @@ PEM encoded RSA public keys begin with: ## Minimum Supported Rust Version -This crate requires **Rust 1.65** at a minimum. +This crate requires **Rust 1.57** at a minimum. We may change the MSRV in the future, but it will be accompanied by a minor version bump. @@ -58,7 +58,7 @@ dual licensed as above, without any additional terms or conditions. [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 +[rustc-image]: https://img.shields.io/badge/rustc-1.57+-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 @@ -1,19 +1,12 @@ #![no_std] -#![cfg_attr(docsrs, feature(doc_auto_cfg))] +#![cfg_attr(docsrs, feature(doc_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 -)] +#![forbid(unsafe_code, clippy::unwrap_used)] +#![warn(missing_docs, rust_2018_idioms, unused_qualifications)] /// Local Android change: Use std to allow building as a dylib. #[cfg(android_dylib)] @@ -33,7 +26,7 @@ mod version; pub use der::{ self, - asn1::{ObjectIdentifier, UintRef}, + asn1::{ObjectIdentifier, UIntRef}, }; pub use crate::{ @@ -52,15 +45,18 @@ pub use crate::{ }; #[cfg(feature = "pem")] +#[cfg_attr(docsrs, doc(cfg(feature = "pem")))] pub use der::pem::{self, LineEnding}; /// `rsaEncryption` Object Identifier (OID) #[cfg(feature = "pkcs8")] +#[cfg_attr(docsrs, doc(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 { +#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] +pub const ALGORITHM_ID: pkcs8::AlgorithmIdentifier<'static> = pkcs8::AlgorithmIdentifier { oid: ALGORITHM_OID, parameters: Some(der::asn1::AnyRef::NULL), }; diff --git a/src/params.rs b/src/params.rs index 74a1ee4..e803473 100644 --- a/src/params.rs +++ b/src/params.rs @@ -1,23 +1,27 @@ //! PKCS#1 RSA parameters. use crate::{Error, Result}; +use der::asn1::{AnyRef, ObjectIdentifier}; use der::{ - asn1::{AnyRef, ContextSpecificRef, ObjectIdentifier}, - oid::AssociatedOid, - Decode, DecodeValue, Encode, EncodeValue, FixedTag, Length, Reader, Sequence, Tag, TagMode, - TagNumber, Writer, + asn1::ContextSpecificRef, Decode, DecodeValue, Encode, EncodeValue, FixedTag, Reader, Sequence, + Tag, TagMode, TagNumber, Writer, }; -use spki::{AlgorithmIdentifier, AlgorithmIdentifierRef}; +use spki::AlgorithmIdentifier; 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 { +// TODO(tarcieri): make `AlgorithmIdentifier` generic around params; use `OID_SHA_1` +const SEQ_OID_SHA_1_DER: &[u8] = &[0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a]; + +const SHA_1_AI: AlgorithmIdentifier<'_> = AlgorithmIdentifier { oid: OID_SHA_1, - parameters: Some(AnyRef::NULL), + parameters: None, }; +const SALT_LEN_DEFAULT: u8 = 20; + /// `TrailerField` as defined in [RFC 8017 Appendix 2.3]. /// ```text /// TrailerField ::= INTEGER { trailerFieldBC(1) } @@ -46,11 +50,11 @@ impl<'a> DecodeValue<'a> for TrailerField { } impl EncodeValue for TrailerField { - fn value_len(&self) -> der::Result<Length> { - Ok(Length::ONE) + fn value_len(&self) -> der::Result<der::Length> { + Ok(der::Length::ONE) } - fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> { + fn encode_value(&self, writer: &mut dyn Writer) -> der::Result<()> { (*self as u8).encode_value(writer) } } @@ -77,10 +81,10 @@ impl FixedTag for TrailerField { #[derive(Clone, Debug, Eq, PartialEq)] pub struct RsaPssParams<'a> { /// Hash Algorithm - pub hash: AlgorithmIdentifierRef<'a>, + pub hash: AlgorithmIdentifier<'a>, /// Mask Generation Function (MGF) - pub mask_gen: AlgorithmIdentifier<AlgorithmIdentifierRef<'a>>, + pub mask_gen: AlgorithmIdentifier<'a>, /// Salt length pub salt_len: u8, @@ -89,89 +93,12 @@ pub struct RsaPssParams<'a> { 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, + salt_len: SALT_LEN_DEFAULT, trailer_field: Default::default(), } } @@ -189,7 +116,7 @@ impl<'a> DecodeValue<'a> for RsaPssParams<'a> { .unwrap_or_else(default_mgf1_sha1), salt_len: reader .context_specific(TagNumber::N2, TagMode::Explicit)? - .unwrap_or(RsaPssParams::SALT_LEN_DEFAULT), + .unwrap_or(SALT_LEN_DEFAULT), trailer_field: reader .context_specific(TagNumber::N3, TagMode::Explicit)? .unwrap_or_default(), @@ -198,25 +125,52 @@ impl<'a> DecodeValue<'a> for RsaPssParams<'a> { } } -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> { + fn fields<F, T>(&self, f: F) -> der::Result<T> + where + F: FnOnce(&[&dyn Encode]) -> der::Result<T>, + { + f(&[ + &if self.hash == SHA_1_AI { + None + } else { + Some(ContextSpecificRef { + tag_number: TagNumber::N0, + tag_mode: TagMode::Explicit, + value: &self.hash, + }) + }, + &if self.mask_gen == default_mgf1_sha1() { + None + } else { + Some(ContextSpecificRef { + tag_number: TagNumber::N1, + tag_mode: TagMode::Explicit, + value: &self.mask_gen, + }) + }, + &if self.salt_len == SALT_LEN_DEFAULT { + None + } else { + Some(ContextSpecificRef { + tag_number: TagNumber::N2, + tag_mode: TagMode::Explicit, + value: &self.salt_len, + }) + }, + &if self.trailer_field == TrailerField::default() { + None + } else { + Some(ContextSpecificRef { + tag_number: TagNumber::N3, + tag_mode: TagMode::Explicit, + value: &self.trailer_field, + }) + }, + ]) } } -impl<'a> Sequence<'a> for RsaPssParams<'a> {} - impl<'a> TryFrom<&'a [u8]> for RsaPssParams<'a> { type Error = Error; @@ -226,10 +180,13 @@ impl<'a> TryFrom<&'a [u8]> for RsaPssParams<'a> { } /// Default Mask Generation Function (MGF): SHA-1. -fn default_mgf1_sha1<'a>() -> AlgorithmIdentifier<AlgorithmIdentifierRef<'a>> { - AlgorithmIdentifier::<AlgorithmIdentifierRef<'a>> { +fn default_mgf1_sha1<'a>() -> AlgorithmIdentifier<'a> { + AlgorithmIdentifier { oid: OID_MGF_1, - parameters: Some(SHA_1_AI), + parameters: Some( + AnyRef::new(Tag::Sequence, SEQ_OID_SHA_1_DER) + .expect("error creating default MGF1 params"), + ), } } @@ -251,84 +208,13 @@ fn default_mgf1_sha1<'a>() -> AlgorithmIdentifier<AlgorithmIdentifierRef<'a>> { #[derive(Clone, Debug, Eq, PartialEq)] pub struct RsaOaepParams<'a> { /// Hash Algorithm - pub hash: AlgorithmIdentifierRef<'a>, + pub hash: AlgorithmIdentifier<'a>, /// Mask Generation Function (MGF) - pub mask_gen: AlgorithmIdentifier<AlgorithmIdentifierRef<'a>>, + pub mask_gen: AlgorithmIdentifier<'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, - }) - } - } + pub p_source: AlgorithmIdentifier<'a>, } impl<'a> Default for RsaOaepParams<'a> { @@ -359,23 +245,43 @@ impl<'a> DecodeValue<'a> for RsaOaepParams<'a> { } } -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> { + fn fields<F, T>(&self, f: F) -> der::Result<T> + where + F: FnOnce(&[&dyn Encode]) -> der::Result<T>, + { + f(&[ + &if self.hash == SHA_1_AI { + None + } else { + Some(ContextSpecificRef { + tag_number: TagNumber::N0, + tag_mode: TagMode::Explicit, + value: &self.hash, + }) + }, + &if self.mask_gen == default_mgf1_sha1() { + None + } else { + Some(ContextSpecificRef { + tag_number: TagNumber::N1, + tag_mode: TagMode::Explicit, + value: &self.mask_gen, + }) + }, + &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> Sequence<'a> for RsaOaepParams<'a> {} - impl<'a> TryFrom<&'a [u8]> for RsaOaepParams<'a> { type Error = Error; @@ -384,16 +290,12 @@ impl<'a> TryFrom<&'a [u8]> for RsaOaepParams<'a> { } } -fn pspecicied_algorithm_identifier(label: &impl AsRef<[u8]>) -> AlgorithmIdentifierRef<'_> { - AlgorithmIdentifierRef { +/// Default Source Algorithm, empty string +fn default_pempty_string<'a>() -> AlgorithmIdentifier<'a> { + AlgorithmIdentifier { oid: OID_PSPECIFIED, parameters: Some( - AnyRef::new(Tag::OctetString, label.as_ref()).expect("error creating OAEP params"), + AnyRef::new(Tag::OctetString, &[]).expect("error creating default OAEP params"), ), } } - -/// Default Source Algorithm, empty string -fn default_pempty_string<'a>() -> AlgorithmIdentifierRef<'a> { - pspecicied_algorithm_identifier(&[]) -} diff --git a/src/private_key.rs b/src/private_key.rs index b913c47..043ed02 100644 --- a/src/private_key.rs +++ b/src/private_key.rs @@ -5,10 +5,7 @@ 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, -}; +use der::{asn1::UIntRef, Decode, DecodeValue, Encode, Header, Reader, Sequence, Tag}; #[cfg(feature = "alloc")] use {self::other_prime_info::OtherPrimeInfo, alloc::vec::Vec, der::SecretDocument}; @@ -42,28 +39,28 @@ use der::pem::PemLabel; #[derive(Clone)] pub struct RsaPrivateKey<'a> { /// `n`: RSA modulus. - pub modulus: UintRef<'a>, + pub modulus: UIntRef<'a>, /// `e`: RSA public exponent. - pub public_exponent: UintRef<'a>, + pub public_exponent: UIntRef<'a>, /// `d`: RSA private exponent. - pub private_exponent: UintRef<'a>, + pub private_exponent: UIntRef<'a>, /// `p`: first prime factor of `n`. - pub prime1: UintRef<'a>, + pub prime1: UIntRef<'a>, /// `q`: Second prime factor of `n`. - pub prime2: UintRef<'a>, + pub prime2: UIntRef<'a>, /// First exponent: `d mod (p-1)`. - pub exponent1: UintRef<'a>, + pub exponent1: UIntRef<'a>, /// Second exponent: `d mod (q-1)`. - pub exponent2: UintRef<'a>, + pub exponent2: UIntRef<'a>, /// CRT coefficient: `(inverse of q) mod p`. - pub coefficient: UintRef<'a>, + 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`). @@ -119,37 +116,27 @@ impl<'a> DecodeValue<'a> for RsaPrivateKey<'a> { } } -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> { + fn fields<F, T>(&self, f: F) -> der::Result<T> + where + F: FnOnce(&[&dyn Encode]) -> der::Result<T>, + { + f(&[ + &self.version(), + &self.modulus, + &self.public_exponent, + &self.private_exponent, + &self.prime1, + &self.prime2, + &self.exponent1, + &self.exponent2, + &self.coefficient, + #[cfg(feature = "alloc")] + &self.other_prime_infos, + ]) } } -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() @@ -181,6 +168,7 @@ impl fmt::Debug for RsaPrivateKey<'_> { } #[cfg(feature = "alloc")] +#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] impl TryFrom<RsaPrivateKey<'_>> for SecretDocument { type Error = Error; @@ -190,6 +178,7 @@ impl TryFrom<RsaPrivateKey<'_>> for SecretDocument { } #[cfg(feature = "alloc")] +#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] impl TryFrom<&RsaPrivateKey<'_>> for SecretDocument { type Error = Error; @@ -199,13 +188,12 @@ impl TryFrom<&RsaPrivateKey<'_>> for SecretDocument { } #[cfg(feature = "pem")] +#[cfg_attr(docsrs, doc(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] @@ -214,30 +202,15 @@ pub struct OtherPrimeInfos<'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> { +impl<'a> Decode<'a> for OtherPrimeInfos<'a> { + fn decode<R: Reader<'a>>(reader: &mut R) -> der::Result<Self> { // Placeholder decoder that always returns an error. - // Uses `Tag::Integer` to signal an unsupported version. + // Use `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; } diff --git a/src/private_key/other_prime_info.rs b/src/private_key/other_prime_info.rs index 35194a5..8980aa1 100644 --- a/src/private_key/other_prime_info.rs +++ b/src/private_key/other_prime_info.rs @@ -1,8 +1,6 @@ //! PKCS#1 OtherPrimeInfo support. -use der::{ - asn1::UintRef, DecodeValue, Encode, EncodeValue, Header, Length, Reader, Sequence, Writer, -}; +use der::{asn1::UIntRef, DecodeValue, Encode, Header, Reader, Sequence}; /// PKCS#1 OtherPrimeInfo as defined in [RFC 8017 Appendix 1.2]. /// @@ -18,15 +16,16 @@ use der::{ /// /// [RFC 8017 Appendix 1.2]: https://datatracker.ietf.org/doc/html/rfc8017#appendix-A.1.2 #[derive(Clone)] +#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] pub struct OtherPrimeInfo<'a> { /// Prime factor `r_i` of `n`, where `i` >= 3. - pub prime: UintRef<'a>, + pub prime: UIntRef<'a>, /// Exponent: `d_i = d mod (r_i - 1)`. - pub exponent: UintRef<'a>, + pub exponent: UIntRef<'a>, /// CRT coefficient: `t_i = (r_1 * r_2 * ... * r_(i-1))^(-1) mod r_i`. - pub coefficient: UintRef<'a>, + pub coefficient: UIntRef<'a>, } impl<'a> DecodeValue<'a> for OtherPrimeInfo<'a> { @@ -41,17 +40,11 @@ impl<'a> DecodeValue<'a> for OtherPrimeInfo<'a> { } } -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> { + fn fields<F, T>(&self, f: F) -> der::Result<T> + where + F: FnOnce(&[&dyn Encode]) -> der::Result<T>, + { + f(&[&self.prime, &self.exponent, &self.coefficient]) } } - -impl<'a> Sequence<'a> for OtherPrimeInfo<'a> {} diff --git a/src/public_key.rs b/src/public_key.rs index 3281744..b6b8c87 100644 --- a/src/public_key.rs +++ b/src/public_key.rs @@ -1,10 +1,7 @@ //! PKCS#1 RSA Public Keys. use crate::{Error, Result}; -use der::{ - asn1::UintRef, Decode, DecodeValue, Encode, EncodeValue, Header, Length, Reader, Sequence, - Writer, -}; +use der::{asn1::UIntRef, Decode, DecodeValue, Encode, Header, Reader, Sequence}; #[cfg(feature = "alloc")] use der::Document; @@ -27,10 +24,10 @@ use der::pem::PemLabel; #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub struct RsaPublicKey<'a> { /// `n`: RSA modulus - pub modulus: UintRef<'a>, + pub modulus: UIntRef<'a>, /// `e`: RSA public exponent - pub public_exponent: UintRef<'a>, + pub public_exponent: UIntRef<'a>, } impl<'a> DecodeValue<'a> for RsaPublicKey<'a> { @@ -44,20 +41,15 @@ impl<'a> DecodeValue<'a> for RsaPublicKey<'a> { } } -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> { + fn fields<F, T>(&self, f: F) -> der::Result<T> + where + F: FnOnce(&[&dyn Encode]) -> der::Result<T>, + { + f(&[&self.modulus, &self.public_exponent]) } } -impl<'a> Sequence<'a> for RsaPublicKey<'a> {} - impl<'a> TryFrom<&'a [u8]> for RsaPublicKey<'a> { type Error = Error; @@ -67,6 +59,7 @@ impl<'a> TryFrom<&'a [u8]> for RsaPublicKey<'a> { } #[cfg(feature = "alloc")] +#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] impl TryFrom<RsaPublicKey<'_>> for Document { type Error = Error; @@ -76,6 +69,7 @@ impl TryFrom<RsaPublicKey<'_>> for Document { } #[cfg(feature = "alloc")] +#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] impl TryFrom<&RsaPublicKey<'_>> for Document { type Error = Error; @@ -85,6 +79,7 @@ impl TryFrom<&RsaPublicKey<'_>> for Document { } #[cfg(feature = "pem")] +#[cfg_attr(docsrs, doc(cfg(feature = "pem")))] impl PemLabel for RsaPublicKey<'_> { const PEM_LABEL: &'static str = "RSA PUBLIC KEY"; } diff --git a/src/traits.rs b/src/traits.rs index cd3d04e..c70820c 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -3,7 +3,10 @@ use crate::Result; #[cfg(feature = "alloc")] -use der::{Document, SecretDocument}; +use { + crate::{RsaPrivateKey, RsaPublicKey}, + der::SecretDocument, +}; #[cfg(feature = "pem")] use { @@ -13,19 +16,13 @@ use { }; #[cfg(feature = "pkcs8")] -use { - crate::{ALGORITHM_ID, ALGORITHM_OID}, - der::asn1::BitStringRef, -}; +use crate::{ALGORITHM_ID, ALGORITHM_OID}; #[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}; +use der::{Decode, Document}; /// Parse an [`RsaPrivateKey`] from a PKCS#1-encoded document. pub trait DecodeRsaPrivateKey: Sized { @@ -41,6 +38,7 @@ pub trait DecodeRsaPrivateKey: Sized { /// -----BEGIN RSA PRIVATE KEY----- /// ``` #[cfg(feature = "pem")] + #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] fn from_pkcs1_pem(s: &str) -> Result<Self> { let (label, doc) = SecretDocument::from_pem(s)?; RsaPrivateKey::validate_pem_label(label)?; @@ -50,12 +48,15 @@ pub trait DecodeRsaPrivateKey: Sized { /// Load PKCS#1 private key from an ASN.1 DER-encoded file on the local /// filesystem (binary format). #[cfg(feature = "std")] + #[cfg_attr(docsrs, doc(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"))] + #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] + #[cfg_attr(docsrs, doc(cfg(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)?; @@ -77,6 +78,7 @@ pub trait DecodeRsaPublicKey: Sized { /// -----BEGIN RSA PUBLIC KEY----- /// ``` #[cfg(feature = "pem")] + #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] fn from_pkcs1_pem(s: &str) -> Result<Self> { let (label, doc) = Document::from_pem(s)?; RsaPublicKey::validate_pem_label(label)?; @@ -86,6 +88,7 @@ pub trait DecodeRsaPublicKey: Sized { /// Load [`RsaPublicKey`] from an ASN.1 DER-encoded file on the local /// filesystem (binary format). #[cfg(feature = "std")] + #[cfg_attr(docsrs, doc(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()) @@ -93,6 +96,8 @@ pub trait DecodeRsaPublicKey: Sized { /// Load [`RsaPublicKey`] from a PEM-encoded file on the local filesystem. #[cfg(all(feature = "pem", feature = "std"))] + #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] + #[cfg_attr(docsrs, doc(cfg(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)?; @@ -102,12 +107,14 @@ pub trait DecodeRsaPublicKey: Sized { /// Serialize a [`RsaPrivateKey`] to a PKCS#1 encoded document. #[cfg(feature = "alloc")] +#[cfg_attr(docsrs, doc(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")] + #[cfg_attr(docsrs, doc(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)?) @@ -115,12 +122,14 @@ pub trait EncodeRsaPrivateKey { /// Write ASN.1 DER-encoded PKCS#1 private key to the given path. #[cfg(feature = "std")] + #[cfg_attr(docsrs, doc(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"))] + #[cfg_attr(docsrs, doc(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)?) @@ -129,12 +138,14 @@ pub trait EncodeRsaPrivateKey { /// Serialize a [`RsaPublicKey`] to a PKCS#1-encoded document. #[cfg(feature = "alloc")] +#[cfg_attr(docsrs, doc(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")] + #[cfg_attr(docsrs, doc(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)?) @@ -142,12 +153,14 @@ pub trait EncodeRsaPublicKey { /// Write ASN.1 DER-encoded public key to the given path. #[cfg(feature = "std")] + #[cfg_attr(docsrs, doc(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"))] + #[cfg_attr(docsrs, doc(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)?) @@ -155,10 +168,8 @@ pub trait EncodeRsaPublicKey { } #[cfg(feature = "pkcs8")] -impl<T> DecodeRsaPrivateKey for T -where - T: for<'a> TryFrom<pkcs8::PrivateKeyInfo<'a>, Error = pkcs8::Error>, -{ +#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] +impl<T: pkcs8::DecodePrivateKey> DecodeRsaPrivateKey for T { fn from_pkcs1_der(private_key: &[u8]) -> Result<Self> { Ok(Self::try_from(pkcs8::PrivateKeyInfo { algorithm: ALGORITHM_ID, @@ -169,19 +180,18 @@ where } #[cfg(feature = "pkcs8")] -impl<T> DecodeRsaPublicKey for T -where - T: for<'a> TryFrom<pkcs8::SubjectPublicKeyInfoRef<'a>, Error = pkcs8::spki::Error>, -{ +#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] +impl<T: pkcs8::DecodePublicKey> DecodeRsaPublicKey for T { fn from_pkcs1_der(public_key: &[u8]) -> Result<Self> { - Ok(Self::try_from(pkcs8::SubjectPublicKeyInfoRef { + Ok(Self::try_from(pkcs8::SubjectPublicKeyInfo { algorithm: ALGORITHM_ID, - subject_public_key: BitStringRef::from_bytes(public_key)?, + subject_public_key: public_key, })?) } } #[cfg(all(feature = "alloc", feature = "pkcs8"))] +#[cfg_attr(docsrs, doc(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()?; @@ -192,11 +202,12 @@ impl<T: pkcs8::EncodePrivateKey> EncodeRsaPrivateKey for T { } #[cfg(all(feature = "alloc", feature = "pkcs8"))] +#[cfg_attr(docsrs, doc(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())?; + let spki = pkcs8::SubjectPublicKeyInfo::from_der(doc.as_bytes())?; spki.algorithm.assert_algorithm_oid(ALGORITHM_OID)?; - RsaPublicKey::from_der(spki.subject_public_key.raw_bytes())?.try_into() + RsaPublicKey::from_der(spki.subject_public_key)?.try_into() } } diff --git a/src/version.rs b/src/version.rs index 2fdb198..6b253e8 100644 --- a/src/version.rs +++ b/src/version.rs @@ -62,7 +62,7 @@ impl Encode for Version { der::Length::ONE.for_tlv() } - fn encode(&self, writer: &mut impl Writer) -> der::Result<()> { + fn encode(&self, writer: &mut dyn Writer) -> der::Result<()> { u8::from(*self).encode(writer) } } diff --git a/tests/params.rs b/tests/params.rs index d47fbb5..6954934 100644 --- a/tests/params.rs +++ b/tests/params.rs @@ -2,9 +2,8 @@ use const_oid::db; use der::{ - asn1::{AnyRef, ObjectIdentifier, OctetStringRef}, - oid::AssociatedOid, - Encode, + asn1::{ObjectIdentifier, OctetStringRef}, + Decode, Encode, }; use hex_literal::hex; use pkcs1::{RsaOaepParams, RsaPssParams, TrailerField}; @@ -12,22 +11,12 @@ 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"); +const RSA_PSS_PARAMETERS_SHA2_256: &[u8] = &hex!("3030a00d300b0609608648016503040201a11a301806092a864886f70d010108300b0609608648016503040201a203020120"); /// 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"); -} +/// Example OAEP parameters using SHA256 instead of SHA1 and 'abc' as label +const RSA_OAEP_PARAMETERS_SHA2_256: &[u8] = &hex!("303fa00d300b0609608648016503040201a11a301806092a864886f70d010108300b0609608648016503040201a212301006092a864886f70d0101090403abcdef"); #[test] fn decode_pss_param() { @@ -37,17 +26,20 @@ fn decode_pss_param() { .hash .assert_algorithm_oid(db::rfc5912::ID_SHA_256) .is_ok()); - assert_eq!(param.hash.parameters, Some(AnyRef::NULL)); + assert_eq!(param.hash.parameters, None); 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 + .mask_gen + .parameters_any() + .unwrap() + .sequence(|reader| Ok(ObjectIdentifier::decode(reader)?)) + .unwrap(), + db::rfc5912::ID_SHA_256 + ); assert_eq!(param.salt_len, 32); assert_eq!(param.trailer_field, TrailerField::BC); } @@ -70,20 +62,19 @@ fn decode_pss_param_default() { .hash .assert_algorithm_oid(db::rfc5912::ID_SHA_1) .is_ok()); - assert_eq!(param.hash.parameters, Some(AnyRef::NULL)); + assert_eq!(param.hash.parameters, None); 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) + param + .mask_gen + .parameters_any() + .unwrap() + .sequence(|reader| Ok(ObjectIdentifier::decode(reader)?)) + .unwrap(), + db::rfc5912::ID_SHA_1 ); assert_eq!(param.salt_len, 20); assert_eq!(param.trailer_field, TrailerField::BC); @@ -100,23 +91,6 @@ fn encode_pss_param_default() { } #[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(); @@ -124,28 +98,28 @@ fn decode_oaep_param() { .hash .assert_algorithm_oid(db::rfc5912::ID_SHA_256) .is_ok()); - assert_eq!(param.hash.parameters, Some(AnyRef::NULL)); + assert_eq!(param.hash.parameters, None); 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 + .mask_gen + .parameters_any() + .unwrap() + .sequence(|reader| Ok(ObjectIdentifier::decode(reader)?)) + .unwrap(), + db::rfc5912::ID_SHA_256 + ); 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.p_source.parameters_any().unwrap().octet_string(), + OctetStringRef::new(&[0xab, 0xcd, 0xef]) + ); } #[test] @@ -166,20 +140,19 @@ fn decode_oaep_param_default() { .hash .assert_algorithm_oid(db::rfc5912::ID_SHA_1) .is_ok()); - assert_eq!(param.hash.parameters, Some(AnyRef::NULL)); + assert_eq!(param.hash.parameters, None); 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) + param + .mask_gen + .parameters_any() + .unwrap() + .sequence(|reader| Ok(ObjectIdentifier::decode(reader)?)) + .unwrap(), + db::rfc5912::ID_SHA_1 ); assert!(param .p_source @@ -189,7 +162,7 @@ fn decode_oaep_param_default() { .p_source .parameters_any() .unwrap() - .decode_as::<OctetStringRef<'_>>() + .octet_string() .unwrap() .is_empty(),); assert_eq!(param, Default::default()) @@ -203,21 +176,3 @@ fn encode_oaep_param_default() { 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 - ); -} |