diff --git a/Cargo.toml b/Cargo.toml index e8a05d9e..0896b033 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ num-integer = { version = "0.1.39", default-features = false } num-iter = { version = "0.1.37", default-features = false } rand_core = { version = "0.6.4", default-features = false } byteorder = { version = "1.3.1", default-features = false } +const-oid = { version = "0.9", default-features = false } subtle = { version = "2.1.1", default-features = false } digest = { version = "0.10.5", default-features = false, features = ["alloc", "oid"] } pkcs1 = { version = "0.7.1", default-features = false, features = ["alloc", "pkcs8"] } @@ -59,3 +60,8 @@ rustdoc-args = ["--cfg", "docsrs"] [profile.dev] opt-level = 2 + +[patch.crates-io] +pkcs1 = { git = "https://github.com/RustCrypto/formats" } +pkcs8 = { git = "https://github.com/RustCrypto/formats" } +spki = { git = "https://github.com/RustCrypto/formats" } diff --git a/src/pkcs1v15.rs b/src/pkcs1v15.rs index 5d9bac41..9b331893 100644 --- a/src/pkcs1v15.rs +++ b/src/pkcs1v15.rs @@ -11,7 +11,10 @@ use alloc::vec::Vec; use core::fmt::{Debug, Display, Formatter, LowerHex, UpperHex}; use core::marker::PhantomData; use digest::Digest; -use pkcs8::{AssociatedOid, Document, EncodePrivateKey, EncodePublicKey, SecretDocument}; +use pkcs8::{ + spki::{der::AnyRef, AlgorithmIdentifierRef, AssociatedAlgorithmIdentifier}, + AssociatedOid, Document, EncodePrivateKey, EncodePublicKey, SecretDocument, +}; use rand_core::CryptoRngCore; use signature::{ hazmat::{PrehashSigner, PrehashVerifier}, @@ -436,6 +439,15 @@ where } } +impl AssociatedAlgorithmIdentifier for SigningKey +where + D: Digest, +{ + type Params = AnyRef<'static>; + + const ALGORITHM_IDENTIFIER: AlgorithmIdentifierRef<'static> = pkcs1::ALGORITHM_ID; +} + impl From for SigningKey where D: Digest, @@ -606,6 +618,15 @@ where } } +impl AssociatedAlgorithmIdentifier for VerifyingKey +where + D: Digest, +{ + type Params = AnyRef<'static>; + + const ALGORITHM_IDENTIFIER: AlgorithmIdentifierRef<'static> = pkcs1::ALGORITHM_ID; +} + impl From for VerifyingKey where D: Digest, diff --git a/src/pss.rs b/src/pss.rs index 5111a4a3..8375aca6 100644 --- a/src/pss.rs +++ b/src/pss.rs @@ -12,10 +12,19 @@ use alloc::boxed::Box; use alloc::vec::Vec; use core::fmt::{self, Debug, Display, Formatter, LowerHex, UpperHex}; - use core::marker::PhantomData; + +use const_oid::{AssociatedOid, ObjectIdentifier}; use digest::{Digest, DynDigest, FixedOutputReset}; -use pkcs8::{Document, EncodePrivateKey, EncodePublicKey, SecretDocument}; +use pkcs1::RsaPssParams; +use pkcs8::{ + der::{Decode, Encode}, + spki::{ + der::AnyRef, AlgorithmIdentifier, AlgorithmIdentifierOwned, AlgorithmIdentifierRef, + AssociatedAlgorithmIdentifier, DynSignatureAlgorithmIdentifier, + }, + Document, EncodePrivateKey, EncodePublicKey, SecretDocument, +}; use rand_core::CryptoRngCore; use signature::{ hazmat::{PrehashVerifier, RandomizedPrehashSigner}, @@ -689,6 +698,61 @@ where } } +fn get_pss_signature_algo_id(salt_len: Option) -> AlgorithmIdentifierOwned +where + D: Digest + AssociatedOid, +{ + const ID_MGF_1: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.8"); + const ID_RSASSA_PSS: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.10"); + + let salt_len = salt_len.map_or(RsaPssParams::SALT_LEN_DEFAULT, |l| l as u8); + + /* + * We do not expect that any of this functions fails, unless the library is broken, so it + * is safe to use unwrap() + */ + let pss_params = RsaPssParams { + hash: AlgorithmIdentifierRef { + oid: D::OID, + parameters: None, + }, + mask_gen: AlgorithmIdentifier { + oid: ID_MGF_1, + parameters: Some(AlgorithmIdentifierRef { + oid: D::OID, + parameters: None, + }), + }, + salt_len, + trailer_field: Default::default(), + } + .to_der() + .unwrap(); + + AlgorithmIdentifierOwned { + oid: ID_RSASSA_PSS, + parameters: Some(pkcs8::der::Any::from_der(&pss_params).unwrap()), + } +} + +impl AssociatedAlgorithmIdentifier for SigningKey +where + D: Digest, +{ + type Params = AnyRef<'static>; + + const ALGORITHM_IDENTIFIER: AlgorithmIdentifierRef<'static> = pkcs1::ALGORITHM_ID; +} + +impl DynSignatureAlgorithmIdentifier for SigningKey +where + D: Digest + AssociatedOid, +{ + fn signature_algorithm_identifier(&self) -> AlgorithmIdentifierOwned { + get_pss_signature_algo_id::(self.salt_len) + } +} + impl From for SigningKey where D: Digest, @@ -825,6 +889,24 @@ where } } +impl AssociatedAlgorithmIdentifier for BlindedSigningKey +where + D: Digest, +{ + type Params = AnyRef<'static>; + + const ALGORITHM_IDENTIFIER: AlgorithmIdentifierRef<'static> = pkcs1::ALGORITHM_ID; +} + +impl DynSignatureAlgorithmIdentifier for BlindedSigningKey +where + D: Digest + AssociatedOid, +{ + fn signature_algorithm_identifier(&self) -> AlgorithmIdentifierOwned { + get_pss_signature_algo_id::(self.salt_len) + } +} + impl From for BlindedSigningKey where D: Digest, @@ -958,6 +1040,15 @@ where } } +impl AssociatedAlgorithmIdentifier for VerifyingKey +where + D: Digest, +{ + type Params = AnyRef<'static>; + + const ALGORITHM_IDENTIFIER: AlgorithmIdentifierRef<'static> = pkcs1::ALGORITHM_ID; +} + impl From for VerifyingKey where D: Digest,