1 //! ASN.1 `OCTET STRING` support.
2 
3 use crate::{
4     asn1::AnyRef, ord::OrdIsValueOrd, BytesRef, Decode, DecodeValue, EncodeValue, ErrorKind,
5     FixedTag, Header, Length, Reader, Result, Tag, Writer,
6 };
7 
8 /// ASN.1 `OCTET STRING` type: borrowed form.
9 ///
10 /// Octet strings represent contiguous sequences of octets, a.k.a. bytes.
11 ///
12 /// This is a zero-copy reference type which borrows from the input data.
13 #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
14 pub struct OctetStringRef<'a> {
15     /// Inner value
16     inner: BytesRef<'a>,
17 }
18 
19 impl<'a> OctetStringRef<'a> {
20     /// Create a new ASN.1 `OCTET STRING` from a byte slice.
new(slice: &'a [u8]) -> Result<Self>21     pub fn new(slice: &'a [u8]) -> Result<Self> {
22         BytesRef::new(slice)
23             .map(|inner| Self { inner })
24             .map_err(|_| ErrorKind::Length { tag: Self::TAG }.into())
25     }
26 
27     /// Borrow the inner byte slice.
as_bytes(&self) -> &'a [u8]28     pub fn as_bytes(&self) -> &'a [u8] {
29         self.inner.as_slice()
30     }
31 
32     /// Get the length of the inner byte slice.
len(&self) -> Length33     pub fn len(&self) -> Length {
34         self.inner.len()
35     }
36 
37     /// Is the inner byte slice empty?
is_empty(&self) -> bool38     pub fn is_empty(&self) -> bool {
39         self.inner.is_empty()
40     }
41 
42     /// Parse `T` from this `OCTET STRING`'s contents.
decode_into<T: Decode<'a>>(&self) -> Result<T>43     pub fn decode_into<T: Decode<'a>>(&self) -> Result<T> {
44         Decode::from_der(self.as_bytes())
45     }
46 }
47 
48 impl_any_conversions!(OctetStringRef<'a>, 'a);
49 
50 impl AsRef<[u8]> for OctetStringRef<'_> {
as_ref(&self) -> &[u8]51     fn as_ref(&self) -> &[u8] {
52         self.as_bytes()
53     }
54 }
55 
56 impl<'a> DecodeValue<'a> for OctetStringRef<'a> {
decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self>57     fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
58         let inner = BytesRef::decode_value(reader, header)?;
59         Ok(Self { inner })
60     }
61 }
62 
63 impl EncodeValue for OctetStringRef<'_> {
value_len(&self) -> Result<Length>64     fn value_len(&self) -> Result<Length> {
65         self.inner.value_len()
66     }
67 
encode_value(&self, writer: &mut impl Writer) -> Result<()>68     fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
69         self.inner.encode_value(writer)
70     }
71 }
72 
73 impl FixedTag for OctetStringRef<'_> {
74     const TAG: Tag = Tag::OctetString;
75 }
76 
77 impl OrdIsValueOrd for OctetStringRef<'_> {}
78 
79 impl<'a> From<&OctetStringRef<'a>> for OctetStringRef<'a> {
from(value: &OctetStringRef<'a>) -> OctetStringRef<'a>80     fn from(value: &OctetStringRef<'a>) -> OctetStringRef<'a> {
81         *value
82     }
83 }
84 
85 impl<'a> From<OctetStringRef<'a>> for AnyRef<'a> {
from(octet_string: OctetStringRef<'a>) -> AnyRef<'a>86     fn from(octet_string: OctetStringRef<'a>) -> AnyRef<'a> {
87         AnyRef::from_tag_and_value(Tag::OctetString, octet_string.inner)
88     }
89 }
90 
91 impl<'a> From<OctetStringRef<'a>> for &'a [u8] {
from(octet_string: OctetStringRef<'a>) -> &'a [u8]92     fn from(octet_string: OctetStringRef<'a>) -> &'a [u8] {
93         octet_string.as_bytes()
94     }
95 }
96 
97 #[cfg(feature = "alloc")]
98 pub use self::allocating::OctetString;
99 
100 #[cfg(feature = "alloc")]
101 mod allocating {
102     use super::*;
103     use crate::referenced::*;
104     use alloc::vec::Vec;
105 
106     /// ASN.1 `OCTET STRING` type: owned form..
107     ///
108     /// Octet strings represent contiguous sequences of octets, a.k.a. bytes.
109     ///
110     /// This type provides the same functionality as [`OctetStringRef`] but owns
111     /// the backing data.
112     #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
113     pub struct OctetString {
114         /// Bitstring represented as a slice of bytes.
115         pub(super) inner: Vec<u8>,
116     }
117 
118     impl OctetString {
119         /// Create a new ASN.1 `OCTET STRING`.
new(bytes: impl Into<Vec<u8>>) -> Result<Self>120         pub fn new(bytes: impl Into<Vec<u8>>) -> Result<Self> {
121             let inner = bytes.into();
122 
123             // Ensure the bytes parse successfully as an `OctetStringRef`
124             OctetStringRef::new(&inner)?;
125 
126             Ok(Self { inner })
127         }
128 
129         /// Borrow the inner byte slice.
as_bytes(&self) -> &[u8]130         pub fn as_bytes(&self) -> &[u8] {
131             self.inner.as_slice()
132         }
133 
134         /// Take ownership of the octet string.
into_bytes(self) -> Vec<u8>135         pub fn into_bytes(self) -> Vec<u8> {
136             self.inner
137         }
138 
139         /// Get the length of the inner byte slice.
len(&self) -> Length140         pub fn len(&self) -> Length {
141             self.value_len().expect("invalid OCTET STRING length")
142         }
143 
144         /// Is the inner byte slice empty?
is_empty(&self) -> bool145         pub fn is_empty(&self) -> bool {
146             self.inner.is_empty()
147         }
148     }
149 
150     impl_any_conversions!(OctetString);
151 
152     impl AsRef<[u8]> for OctetString {
as_ref(&self) -> &[u8]153         fn as_ref(&self) -> &[u8] {
154             self.as_bytes()
155         }
156     }
157 
158     impl<'a> DecodeValue<'a> for OctetString {
decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self>159         fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
160             Self::new(reader.read_vec(header.length)?)
161         }
162     }
163 
164     impl EncodeValue for OctetString {
value_len(&self) -> Result<Length>165         fn value_len(&self) -> Result<Length> {
166             self.inner.len().try_into()
167         }
168 
encode_value(&self, writer: &mut impl Writer) -> Result<()>169         fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
170             writer.write(&self.inner)
171         }
172     }
173 
174     impl FixedTag for OctetString {
175         const TAG: Tag = Tag::OctetString;
176     }
177 
178     impl<'a> From<&'a OctetString> for OctetStringRef<'a> {
from(octet_string: &'a OctetString) -> OctetStringRef<'a>179         fn from(octet_string: &'a OctetString) -> OctetStringRef<'a> {
180             // Ensured to parse successfully in constructor
181             OctetStringRef::new(&octet_string.inner).expect("invalid OCTET STRING")
182         }
183     }
184 
185     impl OrdIsValueOrd for OctetString {}
186 
187     impl<'a> RefToOwned<'a> for OctetStringRef<'a> {
188         type Owned = OctetString;
ref_to_owned(&self) -> Self::Owned189         fn ref_to_owned(&self) -> Self::Owned {
190             OctetString {
191                 inner: Vec::from(self.inner.as_slice()),
192             }
193         }
194     }
195 
196     impl OwnedToRef for OctetString {
197         type Borrowed<'a> = OctetStringRef<'a>;
owned_to_ref(&self) -> Self::Borrowed<'_>198         fn owned_to_ref(&self) -> Self::Borrowed<'_> {
199             self.into()
200         }
201     }
202 
203     // Implement by hand because the derive would create invalid values.
204     // Use the constructor to create a valid value.
205     #[cfg(feature = "arbitrary")]
206     impl<'a> arbitrary::Arbitrary<'a> for OctetString {
arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self>207         fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
208             Self::new(Vec::arbitrary(u)?).map_err(|_| arbitrary::Error::IncorrectFormat)
209         }
210 
size_hint(depth: usize) -> (usize, Option<usize>)211         fn size_hint(depth: usize) -> (usize, Option<usize>) {
212             arbitrary::size_hint::and(u8::size_hint(depth), Vec::<u8>::size_hint(depth))
213         }
214     }
215 }
216 
217 #[cfg(feature = "bytes")]
218 mod bytes {
219     use super::OctetString;
220     use crate::{DecodeValue, EncodeValue, FixedTag, Header, Length, Reader, Result, Tag, Writer};
221     use bytes::Bytes;
222 
223     impl<'a> DecodeValue<'a> for Bytes {
decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self>224         fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
225             OctetString::decode_value(reader, header).map(|octet_string| octet_string.inner.into())
226         }
227     }
228 
229     impl EncodeValue for Bytes {
value_len(&self) -> Result<Length>230         fn value_len(&self) -> Result<Length> {
231             self.len().try_into()
232         }
233 
encode_value(&self, writer: &mut impl Writer) -> Result<()>234         fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
235             writer.write(self.as_ref())
236         }
237     }
238 
239     impl FixedTag for Bytes {
240         const TAG: Tag = Tag::OctetString;
241     }
242 }
243 
244 #[cfg(test)]
245 mod tests {
246     use crate::asn1::{OctetStringRef, PrintableStringRef};
247 
248     #[test]
octet_string_decode_into()249     fn octet_string_decode_into() {
250         // PrintableString "hi"
251         let der = b"\x13\x02\x68\x69";
252         let oct = OctetStringRef::new(der).unwrap();
253 
254         let res = oct.decode_into::<PrintableStringRef<'_>>().unwrap();
255         assert_eq!(AsRef::<str>::as_ref(&res), "hi");
256     }
257 }
258