diff --git a/cms/src/attr.rs b/cms/src/attr.rs index 2092c7c72..694428cee 100644 --- a/cms/src/attr.rs +++ b/cms/src/attr.rs @@ -3,10 +3,11 @@ use alloc::{boxed::Box, vec}; use der::{ DecodeValue, EncodeValue, FixedTag, Length, Tag, asn1::{OctetString, OctetStringRef}, + oid::db::rfc6268, referenced::OwnedToRef, }; -use x509_cert::time::Time; +use x509_cert::{attr::Attribute, time::Time}; use crate::signed_data::SignerInfo; @@ -101,6 +102,30 @@ impl From for vec::Vec { } } +impl TryFrom<&Attribute> for MessageDigest { + type Error = der::Error; + + fn try_from(attr: &Attribute) -> Result { + if attr.oid != rfc6268::ID_MESSAGE_DIGEST { + return Err(der::ErrorKind::OidUnknown { oid: attr.oid }.into()); + } + + // A message-digest attribute MUST have a single attribute value, even + // though the syntax is defined as a SET OF AttributeValue. There MUST + // NOT be zero or multiple instances of AttributeValue present. + + if attr.values.len() != 1 { + return Err(der::ErrorKind::Value { tag: Tag::Set }.into()); + } + let message_digest = attr + .values + .get(0) + .expect("Invariant violation, only one value is present in the attribute"); + + message_digest.decode_as::().map(Self) + } +} + /// The `SigningTime` attribute is defined in [RFC 5652 Section 11.3]. /// /// ```text