der/asn1/
bit_string.rs
1use crate::{
4 asn1::Any, ByteSlice, DecodeValue, Decoder, DerOrd, EncodeValue, Encoder, Error, ErrorKind,
5 FixedTag, Length, Result, Tag, ValueOrd,
6};
7use core::{cmp::Ordering, iter::FusedIterator};
8
9#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
14pub struct BitString<'a> {
15 unused_bits: u8,
17
18 bit_length: usize,
20
21 inner: ByteSlice<'a>,
23}
24
25impl<'a> BitString<'a> {
26 pub const MAX_UNUSED_BITS: u8 = 7;
28
29 pub fn new(unused_bits: u8, bytes: &'a [u8]) -> Result<Self> {
34 if (unused_bits > Self::MAX_UNUSED_BITS) || (unused_bits != 0 && bytes.is_empty()) {
35 return Err(Self::TAG.value_error());
36 }
37
38 let inner = ByteSlice::new(bytes).map_err(|_| Self::TAG.length_error())?;
39
40 let bit_length = usize::try_from(inner.len())?
41 .checked_mul(8)
42 .and_then(|n| n.checked_sub(usize::from(unused_bits)))
43 .ok_or(ErrorKind::Overflow)?;
44
45 Ok(Self {
46 unused_bits,
47 bit_length,
48 inner,
49 })
50 }
51
52 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self> {
56 Self::new(0, bytes)
57 }
58
59 pub fn unused_bits(&self) -> u8 {
61 self.unused_bits
62 }
63
64 pub fn has_unused_bits(&self) -> bool {
66 self.unused_bits != 0
67 }
68
69 pub fn bit_len(&self) -> usize {
71 self.bit_length
72 }
73
74 pub fn byte_len(&self) -> Length {
77 self.inner.len()
78 }
79
80 pub fn is_empty(&self) -> bool {
82 self.inner.is_empty()
83 }
84
85 pub fn as_bytes(&self) -> Option<&'a [u8]> {
93 if self.has_unused_bits() {
94 None
95 } else {
96 Some(self.raw_bytes())
97 }
98 }
99
100 pub fn raw_bytes(&self) -> &'a [u8] {
106 self.inner.as_bytes()
107 }
108
109 pub fn bits(self) -> BitStringIter<'a> {
111 BitStringIter {
112 bit_string: self,
113 position: 0,
114 }
115 }
116}
117
118impl<'a> DecodeValue<'a> for BitString<'a> {
119 fn decode_value(decoder: &mut Decoder<'a>, encoded_len: Length) -> Result<Self> {
120 let unused_bits = decoder.byte()?;
121 let inner = ByteSlice::decode_value(decoder, (encoded_len - Length::ONE)?)?;
122 Self::new(unused_bits, inner.as_bytes())
123 }
124}
125
126impl EncodeValue for BitString<'_> {
127 fn value_len(&self) -> Result<Length> {
128 self.byte_len() + Length::ONE
129 }
130
131 fn encode_value(&self, encoder: &mut Encoder<'_>) -> Result<()> {
132 encoder.byte(self.unused_bits)?;
133 encoder.bytes(self.raw_bytes())
134 }
135}
136
137impl ValueOrd for BitString<'_> {
138 fn value_cmp(&self, other: &Self) -> Result<Ordering> {
139 match self.unused_bits.cmp(&other.unused_bits) {
140 Ordering::Equal => self.inner.der_cmp(&other.inner),
141 ordering => Ok(ordering),
142 }
143 }
144}
145
146impl<'a> From<&BitString<'a>> for BitString<'a> {
147 fn from(value: &BitString<'a>) -> BitString<'a> {
148 *value
149 }
150}
151
152impl<'a> TryFrom<Any<'a>> for BitString<'a> {
153 type Error = Error;
154
155 fn try_from(any: Any<'a>) -> Result<BitString<'a>> {
156 any.decode_into()
157 }
158}
159
160impl<'a> TryFrom<&'a [u8]> for BitString<'a> {
161 type Error = Error;
162
163 fn try_from(bytes: &'a [u8]) -> Result<BitString<'a>> {
164 BitString::from_bytes(bytes)
165 }
166}
167
168impl<'a> TryFrom<&&'a [u8]> for BitString<'a> {
170 type Error = Error;
171
172 fn try_from(bytes: &&'a [u8]) -> Result<BitString<'a>> {
173 BitString::from_bytes(*bytes)
174 }
175}
176
177impl<'a> TryFrom<BitString<'a>> for &'a [u8] {
178 type Error = Error;
179
180 fn try_from(bit_string: BitString<'a>) -> Result<&'a [u8]> {
181 bit_string
182 .as_bytes()
183 .ok_or_else(|| Tag::BitString.value_error())
184 }
185}
186
187impl<'a> FixedTag for BitString<'a> {
188 const TAG: Tag = Tag::BitString;
189}
190
191pub struct BitStringIter<'a> {
193 bit_string: BitString<'a>,
195
196 position: usize,
198}
199
200impl<'a> Iterator for BitStringIter<'a> {
201 type Item = bool;
202
203 fn next(&mut self) -> Option<bool> {
204 if self.position >= self.bit_string.bit_len() {
205 return None;
206 }
207
208 let byte = self.bit_string.raw_bytes().get(self.position / 8)?;
209 let bit = 1u8 << (7 - (self.position % 8));
210 self.position = self.position.checked_add(1)?;
211 Some(byte & bit != 0)
212 }
213}
214
215impl<'a> ExactSizeIterator for BitStringIter<'a> {
216 fn len(&self) -> usize {
217 self.bit_string.bit_len()
218 }
219}
220
221impl<'a> FusedIterator for BitStringIter<'a> {}
222
223#[cfg(test)]
224mod tests {
225 use super::{BitString, Result, Tag};
226 use crate::asn1::Any;
227 use hex_literal::hex;
228
229 fn parse_bitstring(bytes: &[u8]) -> Result<BitString<'_>> {
231 Any::new(Tag::BitString, bytes)?.try_into()
232 }
233
234 #[test]
235 fn decode_empty_bitstring() {
236 let bs = parse_bitstring(&hex!("00")).unwrap();
237 assert_eq!(bs.as_bytes().unwrap(), &[]);
238 }
239
240 #[test]
241 fn decode_non_empty_bitstring() {
242 let bs = parse_bitstring(&hex!("00010203")).unwrap();
243 assert_eq!(bs.as_bytes().unwrap(), &[0x01, 0x02, 0x03]);
244 }
245
246 #[test]
247 fn decode_bitstring_with_unused_bits() {
248 let bs = parse_bitstring(&hex!("066e5dc0")).unwrap();
249 assert_eq!(bs.unused_bits(), 6);
250 assert_eq!(bs.raw_bytes(), &hex!("6e5dc0"));
251
252 let mut bits = bs.bits();
254 assert_eq!(bits.len(), 18);
255
256 for bit in [0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1] {
257 assert_eq!(bits.next().unwrap() as u8, bit)
258 }
259
260 assert_eq!(bits.next(), None);
262 assert_eq!(bits.next(), None);
263 }
264
265 #[test]
266 fn reject_unused_bits_in_empty_string() {
267 assert_eq!(
268 parse_bitstring(&[0x03]).err().unwrap().kind(),
269 Tag::BitString.value_error().kind()
270 )
271 }
272}