aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2022-12-16 18:01:16 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2022-12-16 18:01:16 +0000
commitaf1b6b2ed018a7660757abb9d8d0a87c4e4abe30 (patch)
treeb21aa411dae47d94216d3811c053361a07950aff
parent29a232bf9d140bfbc9ad36eab6d94b5214c763cf (diff)
parent50c0040a04842ca232bfa0cb54ee15db7cd8fd50 (diff)
downloadpkcs1-af1b6b2ed018a7660757abb9d8d0a87c4e4abe30.tar.gz
Merge "Upgrade pkcs1 to 0.4.1" am: 50c0040a04
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/pkcs1/+/2348523 Change-Id: I3d70ef8b85248dd41f62639f1c9d54cc28864d16 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--.cargo_vcs_info.json2
-rw-r--r--Android.bp5
-rw-r--r--CHANGELOG.md8
-rw-r--r--Cargo.toml10
-rw-r--r--Cargo.toml.orig4
-rw-r--r--LICENSE-MIT25
-rw-r--r--METADATA13
-rw-r--r--src/lib.rs9
-rw-r--r--src/params.rs301
-rw-r--r--src/traits.rs4
-rw-r--r--tests/params.rs178
11 files changed, 541 insertions, 18 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index c6845d7..8acf345 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
{
"git": {
- "sha1": "edbfb4db0ddfd1f95c7ed29ca480e4a93ec1737e"
+ "sha1": "40fbcf36aa1d1e20685424576da37b7df0279d3b"
},
"path_in_vcs": "pkcs1"
} \ No newline at end of file
diff --git a/Android.bp b/Android.bp
index d6898bd..5201719 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,8 +1,6 @@
// This file is generated by cargo2android.py --config cargo2android.json.
// Do not modify this file as changes will be overridden on upgrade.
-
-
package {
default_applicable_licenses: ["external_rust_crates_pkcs1_license"],
}
@@ -37,7 +35,7 @@ rust_library_host {
name: "libpkcs1",
crate_name: "pkcs1",
cargo_env_compat: true,
- cargo_pkg_version: "0.4.0",
+ cargo_pkg_version: "0.4.1",
srcs: ["src/lib.rs"],
edition: "2021",
features: [
@@ -48,6 +46,7 @@ rust_library_host {
rustlibs: [
"libder",
"libpkcs8",
+ "libspki",
"libzeroize",
],
apex_available: [
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e607ae7..7e95122 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,14 @@ 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.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])
diff --git a/Cargo.toml b/Cargo.toml
index e193698..b73c625 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,7 +13,7 @@
edition = "2021"
rust-version = "1.57"
name = "pkcs1"
-version = "0.4.0"
+version = "0.4.1"
authors = ["RustCrypto Developers"]
description = """
Pure Rust implementation of Public-Key Cryptography Standards (PKCS) #1:
@@ -36,7 +36,6 @@ categories = [
]
license = "Apache-2.0 OR MIT"
repository = "https://github.com/RustCrypto/formats/tree/master/pkcs1"
-resolver = "2"
[package.metadata.docs.rs]
all-features = true
@@ -54,11 +53,18 @@ version = "0.9"
optional = true
default-features = false
+[dependencies.spki]
+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.3"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 00f6414..fb1fa3f 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
[package]
name = "pkcs1"
-version = "0.4.0" # Also update html_root_url in lib.rs when bumping this
+version = "0.4.1"
description = """
Pure Rust implementation of Public-Key Cryptography Standards (PKCS) #1:
RSA Cryptography Specifications Version 2.2 (RFC 8017)
@@ -16,6 +16,7 @@ rust-version = "1.57"
[dependencies]
der = { version = "0.6", features = ["oid"], path = "../der" }
+spki = { version = "0.6", path = "../spki" }
# optional dependencies
pkcs8 = { version = "0.9", optional = true, default-features = false, path = "../pkcs8" }
@@ -24,6 +25,7 @@ zeroize = { version = "1", optional = true, default-features = false }
[dev-dependencies]
hex-literal = "0.3"
tempfile = "3"
+const-oid = { version = "0.9", path = "../const-oid", features = ["db"] }
[features]
alloc = ["der/alloc", "pkcs8/alloc", "zeroize/alloc"]
diff --git a/LICENSE-MIT b/LICENSE-MIT
new file mode 100644
index 0000000..68ddaa3
--- /dev/null
+++ b/LICENSE-MIT
@@ -0,0 +1,25 @@
+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
+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.
diff --git a/METADATA b/METADATA
index a0641dd..51c2998 100644
--- a/METADATA
+++ b/METADATA
@@ -1,3 +1,7 @@
+# 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/+/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 {
@@ -7,14 +11,13 @@ third_party {
}
url {
type: ARCHIVE
- value: "https://static.crates.io/crates/pkcs1/pkcs1-0.4.0.crate"
+ value: "https://static.crates.io/crates/pkcs1/pkcs1-0.4.1.crate"
}
- version: "0.4.0"
- # Dual-licensed, using the least restrictive per go/thirdpartylicenses#same.
+ version: "0.4.1"
license_type: NOTICE
last_upgrade_date {
year: 2022
- month: 9
- day: 6
+ month: 12
+ day: 13
}
}
diff --git a/src/lib.rs b/src/lib.rs
index edbb128..9176c8d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2,9 +2,8 @@
#![cfg_attr(docsrs, feature(doc_cfg))]
#![doc = include_str!("../README.md")]
#![doc(
- html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg",
- html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg",
- html_root_url = "https://docs.rs/pkcs1/0.4.0-pre"
+ 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, clippy::unwrap_used)]
#![warn(missing_docs, rust_2018_idioms, unused_qualifications)]
@@ -19,6 +18,7 @@ extern crate alloc;
extern crate std;
mod error;
+mod params;
mod private_key;
mod public_key;
mod traits;
@@ -29,8 +29,9 @@ pub use der::{
asn1::{ObjectIdentifier, UIntRef},
};
-pub use self::{
+pub use crate::{
error::{Error, Result},
+ params::{RsaOaepParams, RsaPssParams, TrailerField},
private_key::RsaPrivateKey,
public_key::RsaPublicKey,
traits::{DecodeRsaPrivateKey, DecodeRsaPublicKey},
diff --git a/src/params.rs b/src/params.rs
new file mode 100644
index 0000000..e803473
--- /dev/null
+++ b/src/params.rs
@@ -0,0 +1,301 @@
+//! PKCS#1 RSA parameters.
+
+use crate::{Error, Result};
+use der::asn1::{AnyRef, ObjectIdentifier};
+use der::{
+ asn1::ContextSpecificRef, Decode, DecodeValue, Encode, EncodeValue, FixedTag, Reader, Sequence,
+ Tag, TagMode, TagNumber, Writer,
+};
+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");
+
+// 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: None,
+};
+
+const SALT_LEN_DEFAULT: u8 = 20;
+
+/// `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<der::Length> {
+ Ok(der::Length::ONE)
+ }
+
+ fn encode_value(&self, writer: &mut dyn 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: AlgorithmIdentifier<'a>,
+
+ /// Mask Generation Function (MGF)
+ pub mask_gen: AlgorithmIdentifier<'a>,
+
+ /// Salt length
+ pub salt_len: u8,
+
+ /// Trailer field (i.e. [`TrailerField::BC`])
+ pub trailer_field: TrailerField,
+}
+
+impl<'a> Default for RsaPssParams<'a> {
+ fn default() -> Self {
+ Self {
+ hash: SHA_1_AI,
+ mask_gen: default_mgf1_sha1(),
+ salt_len: 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(SALT_LEN_DEFAULT),
+ trailer_field: reader
+ .context_specific(TagNumber::N3, TagMode::Explicit)?
+ .unwrap_or_default(),
+ })
+ })
+ }
+}
+
+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> 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<'a> {
+ AlgorithmIdentifier {
+ oid: OID_MGF_1,
+ parameters: Some(
+ AnyRef::new(Tag::Sequence, SEQ_OID_SHA_1_DER)
+ .expect("error creating default MGF1 params"),
+ ),
+ }
+}
+
+/// 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: AlgorithmIdentifier<'a>,
+
+ /// Mask Generation Function (MGF)
+ pub mask_gen: AlgorithmIdentifier<'a>,
+
+ /// The source (and possibly the value) of the label L
+ pub p_source: AlgorithmIdentifier<'a>,
+}
+
+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<'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> TryFrom<&'a [u8]> for RsaOaepParams<'a> {
+ type Error = Error;
+
+ fn try_from(bytes: &'a [u8]) -> Result<Self> {
+ Ok(Self::from_der(bytes)?)
+ }
+}
+
+/// Default Source Algorithm, empty string
+fn default_pempty_string<'a>() -> AlgorithmIdentifier<'a> {
+ AlgorithmIdentifier {
+ oid: OID_PSPECIFIED,
+ parameters: Some(
+ AnyRef::new(Tag::OctetString, &[]).expect("error creating default OAEP params"),
+ ),
+ }
+}
diff --git a/src/traits.rs b/src/traits.rs
index edf06c1..c70820c 100644
--- a/src/traits.rs
+++ b/src/traits.rs
@@ -191,7 +191,7 @@ impl<T: pkcs8::DecodePublicKey> DecodeRsaPublicKey for T {
}
#[cfg(all(feature = "alloc", feature = "pkcs8"))]
-#[cfg_attr(docsrs, doc(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()?;
@@ -202,7 +202,7 @@ impl<T: pkcs8::EncodePrivateKey> EncodeRsaPrivateKey for T {
}
#[cfg(all(feature = "alloc", feature = "pkcs8"))]
-#[cfg_attr(docsrs, doc(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()?;
diff --git a/tests/params.rs b/tests/params.rs
new file mode 100644
index 0000000..6954934
--- /dev/null
+++ b/tests/params.rs
@@ -0,0 +1,178 @@
+//! PKCS#1 algorithm params tests
+
+use const_oid::db;
+use der::{
+ asn1::{ObjectIdentifier, OctetStringRef},
+ Decode, 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!("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 and 'abc' as label
+const RSA_OAEP_PARAMETERS_SHA2_256: &[u8] = &hex!("303fa00d300b0609608648016503040201a11a301806092a864886f70d010108300b0609608648016503040201a212301006092a864886f70d0101090403abcdef");
+
+#[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, None);
+ assert!(param
+ .mask_gen
+ .assert_algorithm_oid(db::rfc5912::ID_MGF_1)
+ .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);
+}
+
+#[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, None);
+ assert!(param
+ .mask_gen
+ .assert_algorithm_oid(db::rfc5912::ID_MGF_1)
+ .is_ok());
+ assert_eq!(
+ 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);
+ 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 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, None);
+ assert!(param
+ .mask_gen
+ .assert_algorithm_oid(db::rfc5912::ID_MGF_1)
+ .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_eq!(
+ param.p_source.parameters_any().unwrap().octet_string(),
+ OctetStringRef::new(&[0xab, 0xcd, 0xef])
+ );
+}
+
+#[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, None);
+ assert!(param
+ .mask_gen
+ .assert_algorithm_oid(db::rfc5912::ID_MGF_1)
+ .is_ok());
+ assert_eq!(
+ param
+ .mask_gen
+ .parameters_any()
+ .unwrap()
+ .sequence(|reader| Ok(ObjectIdentifier::decode(reader)?))
+ .unwrap(),
+ db::rfc5912::ID_SHA_1
+ );
+ assert!(param
+ .p_source
+ .assert_algorithm_oid(db::rfc5912::ID_P_SPECIFIED)
+ .is_ok());
+ assert!(param
+ .p_source
+ .parameters_any()
+ .unwrap()
+ .octet_string()
+ .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
+ );
+}