Skip to content

Commit a4f4cb9

Browse files
authored
cms: make MessageDigest a newtype around OctetString (#1967)
1 parent 1131521 commit a4f4cb9

File tree

2 files changed

+90
-3
lines changed

2 files changed

+90
-3
lines changed

cms/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ builder = [
5757
"dep:ansi-x963-kdf",
5858
"dep:cbc",
5959
"dep:cipher",
60-
"dep:digest",
60+
"digest",
6161
"elliptic-curve/ecdh",
6262
"elliptic-curve/pkcs8",
6363
"dep:rsa",

cms/src/attr.rs

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
//! Attribute-related types
2-
use der::asn1::OctetString;
2+
use alloc::{boxed::Box, vec};
3+
use der::{
4+
DecodeValue, EncodeValue, FixedTag, Length, Tag,
5+
asn1::{OctetString, OctetStringRef},
6+
referenced::OwnedToRef,
7+
};
38

49
use x509_cert::time::Time;
510

@@ -12,7 +17,89 @@ use crate::signed_data::SignerInfo;
1217
/// ```
1318
///
1419
/// [RFC 5652 Section 11.2]: https://www.rfc-editor.org/rfc/rfc5652#section-11.2
15-
pub type MessageDigest = OctetString;
20+
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
21+
pub struct MessageDigest(pub OctetString);
22+
23+
impl MessageDigest {
24+
/// Borrow the inner byte slice.
25+
#[inline]
26+
pub fn as_bytes(&self) -> &[u8] {
27+
self.0.as_bytes()
28+
}
29+
30+
/// Take ownership of the octet string.
31+
#[inline]
32+
pub fn into_bytes(self) -> Box<[u8]> {
33+
self.0.into_bytes()
34+
}
35+
36+
/// Get the length of the inner byte slice.
37+
#[inline]
38+
pub fn len(&self) -> Length {
39+
self.0.len()
40+
}
41+
42+
/// Create a [`MessageDigest`] from a [`digest::Digest`]
43+
#[cfg(feature = "digest")]
44+
pub fn from_digest<D>(digest: D) -> der::Result<Self>
45+
where
46+
D: digest::Digest,
47+
{
48+
Ok(MessageDigest(OctetString::new(digest.finalize().to_vec())?))
49+
}
50+
51+
/// Return an [`OctetStringRef`] pointing to the underlying data
52+
#[inline]
53+
pub fn as_octet_string_ref<'a>(&'a self) -> OctetStringRef<'a> {
54+
self.0.owned_to_ref()
55+
}
56+
}
57+
58+
impl AsRef<[u8]> for MessageDigest {
59+
#[inline]
60+
fn as_ref(&self) -> &[u8] {
61+
self.0.as_ref()
62+
}
63+
}
64+
65+
impl AsRef<OctetString> for MessageDigest {
66+
#[inline]
67+
fn as_ref(&self) -> &OctetString {
68+
&self.0
69+
}
70+
}
71+
72+
impl<'a> DecodeValue<'a> for MessageDigest {
73+
type Error = <OctetString as DecodeValue<'a>>::Error;
74+
75+
#[inline]
76+
fn decode_value<R: der::Reader<'a>>(reader: &mut R, header: der::Header) -> der::Result<Self> {
77+
OctetString::decode_value(reader, header).map(Self)
78+
}
79+
}
80+
81+
impl EncodeValue for MessageDigest {
82+
#[inline]
83+
fn value_len(&self) -> der::Result<Length> {
84+
self.0.value_len()
85+
}
86+
87+
#[inline]
88+
fn encode_value(&self, writer: &mut impl der::Writer) -> der::Result<()> {
89+
self.0.encode_value(writer)
90+
}
91+
}
92+
93+
impl FixedTag for MessageDigest {
94+
const TAG: Tag = OctetString::TAG;
95+
}
96+
97+
impl From<MessageDigest> for vec::Vec<u8> {
98+
#[inline]
99+
fn from(value: MessageDigest) -> vec::Vec<u8> {
100+
value.0.into_bytes().into()
101+
}
102+
}
16103

17104
/// The `SigningTime` attribute is defined in [RFC 5652 Section 11.3].
18105
///

0 commit comments

Comments
 (0)