From beb0131c010b1b65dbdb3dcd2570df9bf21e5799 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 22 Mar 2022 08:20:18 -0600 Subject: [PATCH] spki: impl `ValueOrd` for `SubjectPublicKeyInfo` Closes #309 --- spki/src/spki.rs | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/spki/src/spki.rs b/spki/src/spki.rs index a9e605040..2e3ececf9 100644 --- a/spki/src/spki.rs +++ b/spki/src/spki.rs @@ -1,7 +1,8 @@ //! X.509 `SubjectPublicKeyInfo` use crate::{AlgorithmIdentifier, Error, Result}; -use der::{asn1::BitString, Decodable, Decoder, Encodable, Sequence}; +use core::cmp::Ordering; +use der::{asn1::BitString, Decodable, Decoder, DerOrd, Encodable, Sequence, ValueOrd}; #[cfg(feature = "fingerprint")] use sha2::{digest, Digest, Sha256}; @@ -49,6 +50,11 @@ impl<'a> SubjectPublicKeyInfo<'a> { pub fn fingerprint_base64(&self) -> Result { Ok(Base64::encode_string(self.fingerprint()?.as_slice())) } + + /// Get a [`BitString`] representing the `subject_public_key` + fn subject_public_key_bitstring(&self) -> der::Result> { + BitString::from_bytes(self.subject_public_key) + } } impl<'a> Decodable<'a> for SubjectPublicKeyInfo<'a> { @@ -73,10 +79,7 @@ impl<'a> Sequence<'a> for SubjectPublicKeyInfo<'a> { where F: FnOnce(&[&dyn Encodable]) -> der::Result, { - f(&[ - &self.algorithm, - &BitString::from_bytes(self.subject_public_key)?, - ]) + f(&[&self.algorithm, &self.subject_public_key_bitstring()?]) } } @@ -87,3 +90,14 @@ impl<'a> TryFrom<&'a [u8]> for SubjectPublicKeyInfo<'a> { Ok(Self::from_der(bytes)?) } } + +impl ValueOrd for SubjectPublicKeyInfo<'_> { + fn value_cmp(&self, other: &Self) -> der::Result { + match self.algorithm.der_cmp(&other.algorithm)? { + Ordering::Equal => self + .subject_public_key_bitstring()? + .der_cmp(&other.subject_public_key_bitstring()?), + other => Ok(other), + } + } +}