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