From 52ce7fdd557d7cd7c2a742bc2faa26b74d5060ed Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Wed, 22 May 2024 20:24:51 -0700 Subject: [PATCH] spki: ensure params are encoded with `Any` --- spki/src/algorithm.rs | 16 ++++++++-------- spki/src/lib.rs | 3 ++- spki/src/spki.rs | 25 ++++++++++++++----------- spki/src/traits.rs | 6 +++--- spki/tests/spki.rs | 2 +- 5 files changed, 28 insertions(+), 24 deletions(-) diff --git a/spki/src/algorithm.rs b/spki/src/algorithm.rs index baa89cc4f..f932bc49d 100644 --- a/spki/src/algorithm.rs +++ b/spki/src/algorithm.rs @@ -3,7 +3,7 @@ use crate::{Error, Result}; use core::cmp::Ordering; use der::{ - asn1::{AnyRef, Choice, ObjectIdentifier}, + asn1::{AnyLike, AnyRef, Choice, ObjectIdentifier}, Decode, DecodeValue, DerOrd, Encode, EncodeValue, Header, Length, Reader, Sequence, ValueOrd, Writer, }; @@ -22,7 +22,7 @@ use der::asn1::Any; /// [RFC 5280 Section 4.1.1.2]: https://tools.ietf.org/html/rfc5280#section-4.1.1.2 #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] -pub struct AlgorithmIdentifier { +pub struct AlgorithmIdentifier { /// Algorithm OID, i.e. the `algorithm` field in the `AlgorithmIdentifier` /// ASN.1 schema. pub oid: ObjectIdentifier, @@ -31,7 +31,7 @@ pub struct AlgorithmIdentifier { pub parameters: Option, } -impl<'a, Params> DecodeValue<'a> for AlgorithmIdentifier +impl<'a, Params: AnyLike> DecodeValue<'a> for AlgorithmIdentifier where Params: Choice<'a, Error = der::Error>, { @@ -47,7 +47,7 @@ where } } -impl EncodeValue for AlgorithmIdentifier +impl EncodeValue for AlgorithmIdentifier where Params: Encode, { @@ -62,12 +62,12 @@ where } } -impl<'a, Params> Sequence<'a> for AlgorithmIdentifier where +impl<'a, Params: AnyLike> Sequence<'a> for AlgorithmIdentifier where Params: Choice<'a, Error = der::Error> + Encode { } -impl<'a, Params> TryFrom<&'a [u8]> for AlgorithmIdentifier +impl<'a, Params: AnyLike> TryFrom<&'a [u8]> for AlgorithmIdentifier where Params: Choice<'a, Error = der::Error> + Encode, { @@ -78,7 +78,7 @@ where } } -impl ValueOrd for AlgorithmIdentifier +impl ValueOrd for AlgorithmIdentifier where Params: DerOrd, { @@ -100,7 +100,7 @@ pub type AlgorithmIdentifierWithOid = AlgorithmIdentifier; #[cfg(feature = "alloc")] pub type AlgorithmIdentifierOwned = AlgorithmIdentifier; -impl AlgorithmIdentifier { +impl AlgorithmIdentifier { /// Assert the `algorithm` OID is an expected value. pub fn assert_algorithm_oid(&self, expected_oid: ObjectIdentifier) -> Result { if self.oid == expected_oid { diff --git a/spki/src/lib.rs b/spki/src/lib.rs index 6c0caa72a..76d2554bc 100644 --- a/spki/src/lib.rs +++ b/spki/src/lib.rs @@ -21,6 +21,7 @@ //! Borrow the [`ObjectIdentifier`] first then use [`der::AnyRef::from`] or `.into()`: //! //! ``` +//! use der::asn1::AnyRef; //! use spki::{AlgorithmIdentifier, ObjectIdentifier}; //! //! let alg_oid = "1.2.840.10045.2.1".parse::().unwrap(); @@ -28,7 +29,7 @@ //! //! let alg_id = AlgorithmIdentifier { //! oid: alg_oid, -//! parameters: Some(params_oid) +//! parameters: Some(AnyRef::from(¶ms_oid)) //! }; //! ``` diff --git a/spki/src/spki.rs b/spki/src/spki.rs index b2972a62e..1cdfb6e77 100644 --- a/spki/src/spki.rs +++ b/spki/src/spki.rs @@ -3,7 +3,7 @@ use crate::{AlgorithmIdentifier, Error, Result}; use core::cmp::Ordering; use der::{ - asn1::{AnyRef, BitStringRef}, + asn1::{AnyLike, AnyRef, BitStringRef}, Choice, Decode, DecodeValue, DerOrd, Encode, EncodeValue, FixedTag, Header, Length, Reader, Sequence, ValueOrd, Writer, }; @@ -41,7 +41,7 @@ pub type SubjectPublicKeyInfoOwned = SubjectPublicKeyInfo; /// [RFC 5280 ยง 4.1.2.7]: https://tools.ietf.org/html/rfc5280#section-4.1.2.7 #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[derive(Clone, Debug, Eq, PartialEq)] -pub struct SubjectPublicKeyInfo { +pub struct SubjectPublicKeyInfo { /// X.509 [`AlgorithmIdentifier`] for the public key type pub algorithm: AlgorithmIdentifier, @@ -51,7 +51,7 @@ pub struct SubjectPublicKeyInfo { impl<'a, Params, Key> SubjectPublicKeyInfo where - Params: Choice<'a, Error = der::Error> + Encode, + Params: AnyLike + Choice<'a, Error = der::Error> + Encode, // TODO: replace FixedTag with FixedTag once // https://github.com/rust-lang/rust/issues/92827 is fixed Key: Decode<'a, Error = der::Error> + Encode + FixedTag, @@ -84,7 +84,7 @@ where impl<'a: 'k, 'k, Params, Key: 'k> DecodeValue<'a> for SubjectPublicKeyInfo where - Params: Choice<'a, Error = der::Error> + Encode, + Params: AnyLike + Choice<'a, Error = der::Error> + Encode, Key: Decode<'a, Error = der::Error>, { type Error = der::Error; @@ -101,7 +101,7 @@ where impl<'a, Params, Key> EncodeValue for SubjectPublicKeyInfo where - Params: Choice<'a, Error = der::Error> + Encode, + Params: AnyLike + Choice<'a, Error = der::Error> + Encode, Key: Encode, { fn value_len(&self) -> der::Result { @@ -117,14 +117,14 @@ where impl<'a, Params, Key> Sequence<'a> for SubjectPublicKeyInfo where - Params: Choice<'a, Error = der::Error> + Encode, + Params: AnyLike + Choice<'a, Error = der::Error> + Encode, Key: Decode<'a, Error = der::Error> + Encode + FixedTag, { } impl<'a, Params, Key> TryFrom<&'a [u8]> for SubjectPublicKeyInfo where - Params: Choice<'a, Error = der::Error> + Encode, + Params: AnyLike + Choice<'a, Error = der::Error> + Encode, Key: Decode<'a, Error = der::Error> + Encode + FixedTag, { type Error = Error; @@ -136,7 +136,7 @@ where impl<'a, Params, Key> ValueOrd for SubjectPublicKeyInfo where - Params: Choice<'a, Error = der::Error> + DerOrd + Encode, + Params: AnyLike + Choice<'a, Error = der::Error> + DerOrd + Encode, Key: ValueOrd, { fn value_cmp(&self, other: &Self) -> der::Result { @@ -150,7 +150,7 @@ where #[cfg(feature = "alloc")] impl<'a: 'k, 'k, Params, Key: 'k> TryFrom> for Document where - Params: Choice<'a, Error = der::Error> + Encode, + Params: AnyLike + Choice<'a, Error = der::Error> + Encode, Key: Decode<'a, Error = der::Error> + Encode + FixedTag, BitStringRef<'a>: From<&'k Key>, { @@ -164,7 +164,7 @@ where #[cfg(feature = "alloc")] impl<'a: 'k, 'k, Params, Key: 'k> TryFrom<&SubjectPublicKeyInfo> for Document where - Params: Choice<'a, Error = der::Error> + Encode, + Params: AnyLike + Choice<'a, Error = der::Error> + Encode, Key: Decode<'a, Error = der::Error> + Encode + FixedTag, BitStringRef<'a>: From<&'k Key>, { @@ -176,7 +176,10 @@ where } #[cfg(feature = "pem")] -impl PemLabel for SubjectPublicKeyInfo { +impl PemLabel for SubjectPublicKeyInfo +where + Params: AnyLike, +{ const PEM_LABEL: &'static str = "PUBLIC KEY"; } diff --git a/spki/src/traits.rs b/spki/src/traits.rs index f80bf69d7..af2b31e43 100644 --- a/spki/src/traits.rs +++ b/spki/src/traits.rs @@ -1,7 +1,7 @@ //! Traits for encoding/decoding SPKI public keys. use crate::{AlgorithmIdentifier, Error, Result, SubjectPublicKeyInfoRef}; -use der::{EncodeValue, Tagged}; +use der::{asn1::AnyLike, EncodeValue, Tagged}; #[cfg(feature = "alloc")] use { @@ -103,7 +103,7 @@ pub trait EncodePublicKey { /// This is useful for e.g. keys for digital signature algorithms. pub trait AssociatedAlgorithmIdentifier { /// Algorithm parameters. - type Params: Tagged + EncodeValue; + type Params: Tagged + EncodeValue + AnyLike; /// `AlgorithmIdentifier` for this structure. const ALGORITHM_IDENTIFIER: AlgorithmIdentifier; @@ -141,7 +141,7 @@ where /// private keys. pub trait SignatureAlgorithmIdentifier { /// Algorithm parameters. - type Params: Tagged + EncodeValue; + type Params: Tagged + EncodeValue + AnyLike; /// `AlgorithmIdentifier` for the corresponding singature system. const SIGNATURE_ALGORITHM_IDENTIFIER: AlgorithmIdentifier; diff --git a/spki/tests/spki.rs b/spki/tests/spki.rs index f912d4875..3ea759cda 100644 --- a/spki/tests/spki.rs +++ b/spki/tests/spki.rs @@ -1,6 +1,6 @@ //! `SubjectPublicKeyInfo` tests. -use der::asn1::ObjectIdentifier; +use der::asn1::{AnyLike, ObjectIdentifier}; use hex_literal::hex; use spki::SubjectPublicKeyInfoRef;