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), + } + } +}