asn1_rs/asn1_types/
bitstring.rs1use crate::*;
2use bitvec::order::Msb0;
3use bitvec::slice::BitSlice;
4use bitvec::vec::BitVec;
5
6const BITSTRING_MAX_RECURSION: usize = 5;
7
8#[derive(Clone, Debug, Default, Eq, PartialEq)]
17pub struct BitString {
18 bitvec: BitVec<u8, Msb0>,
19}
20
21impl BitString {
22 pub fn new(unused_bits: u8, s: &[u8]) -> Self {
27 let unused_bits = usize::from(unused_bits);
28 let mut bitvec = BitVec::from_slice(s);
29 assert!(unused_bits < 8 && unused_bits < bitvec.len());
30 bitvec.truncate(bitvec.len() - unused_bits);
31
32 BitString { bitvec }
33 }
34
35 pub fn len(&self) -> usize {
37 self.bitvec.len()
38 }
39
40 pub fn is_empty(&self) -> bool {
42 self.bitvec.is_empty()
43 }
44
45 pub fn is_set(&self, bitnum: usize) -> bool {
49 self.as_bitslice()
50 .get(bitnum)
51 .map(|bitref| bitref == true)
52 .unwrap_or(false)
53 }
54
55 pub fn as_bitslice(&self) -> &BitSlice<u8, Msb0> {
57 self.bitvec.as_bitslice()
58 }
59
60 pub fn as_mut_bitslice(&mut self) -> &mut BitSlice<u8, Msb0> {
62 self.bitvec.as_mut_bitslice()
63 }
64
65 pub fn as_raw_slice(&self) -> &[u8] {
67 self.bitvec.as_raw_slice()
68 }
69}
70
71impl AsRef<[u8]> for BitString {
72 fn as_ref(&self) -> &[u8] {
73 self.as_raw_slice()
74 }
75}
76
77impl_tryfrom_any!(BitString);
78
79impl From<&BitSlice<u8, Msb0>> for BitString {
80 fn from(slice: &BitSlice<u8, Msb0>) -> Self {
81 let bitvec = BitVec::from_bitslice(slice);
82 Self { bitvec }
83 }
84}
85
86impl<'i> BerParser<'i> for BitString {
87 type Error = BerError<Input<'i>>;
88
89 fn from_ber_content(
90 header: &'_ Header<'i>,
91 input: Input<'i>,
92 ) -> IResult<Input<'i>, Self, Self::Error> {
93 if !header.constructed() {
96 let (rem, data) = ber_get_content(header, input)?;
97
98 if data.is_empty() {
99 return Err(BerError::nom_err_input(&data, InnerError::InvalidLength));
100 }
101
102 let (ignored, bytes) = data.as_bytes2().split_at(1);
104
105 match ignored[0] {
108 ignored @ 0..=7 => {
109 let mut bitvec = BitVec::from_slice(bytes);
110 let new_len = bitvec
111 .len()
112 .checked_sub(usize::from(ignored))
113 .ok_or(BerError::nom_err_input(&data, InnerError::InvalidLength))?;
114 bitvec.truncate(new_len);
115 Ok((rem, Self { bitvec }))
116 }
117 _ => Err(BerError::nom_err_input(
118 &data,
119 InnerError::invalid_value(Tag::BitString, "Invalid unused bits"),
120 )),
121 }
122 } else {
123 parse_ber_segmented(header, input, BITSTRING_MAX_RECURSION)
125 }
126 }
127}
128
129impl<'i> DerParser<'i> for BitString {
130 type Error = BerError<Input<'i>>;
131
132 fn from_der_content(
133 header: &'_ Header<'i>,
134 input: Input<'i>,
135 ) -> IResult<Input<'i>, Self, Self::Error> {
136 header.assert_primitive_input(&input).map_err(Err::Error)?;
138
139 <BitString>::from_ber_content(header, input)
140 }
141}
142
143impl CheckDerConstraints for BitString {
144 fn check_constraints(any: &Any) -> Result<()> {
145 any.header.assert_primitive()?;
147 let s = any.data.as_bytes2();
149 match s.len() {
150 0 => Err(Error::InvalidLength),
151 1 => {
152 if s[0] == 0 {
154 Ok(())
155 } else {
156 Err(Error::InvalidLength)
157 }
158 }
159 len => {
160 let unused_bits = s[0];
161 let last_byte = s[len - 1];
162 if last_byte.trailing_zeros() < unused_bits as u32 {
163 return Err(Error::DerConstraintFailed(DerConstraint::UnusedBitsNotZero));
164 }
165
166 Ok(())
167 }
168 }
169 }
170}
171
172impl DerAutoDerive for BitString {}
173
174impl Tagged for BitString {
175 const TAG: Tag = Tag::BitString;
176}
177
178impl Appendable for BitString {
179 fn append(&mut self, other: &mut Self) {
180 self.bitvec.append(&mut other.bitvec);
181 }
182}
183
184#[cfg(feature = "std")]
185const _: () = {
186 use std::io::Write;
187
188 impl ToBer for BitString {
189 type Encoder = Primitive<{ Tag::BitString.0 }>;
190
191 fn ber_content_len(&self) -> Length {
192 let len = 1 + ((self.len() + 7) / 8);
193 Length::Definite(len)
194 }
195
196 fn ber_write_content<W: Write>(&self, target: &mut W) -> SerializeResult<usize> {
197 let data = self.as_raw_slice();
198 let ignored = (8 * data.len()) - self.len();
200 target.write_all(&[ignored as u8])?;
201 target.write_all(data)?;
203
204 Ok(1 + data.len())
205 }
206
207 fn ber_tag_info(&self) -> (Class, bool, Tag) {
208 (Self::CLASS, false, Self::TAG)
209 }
210 }
211
212 impl_toder_from_tober!(TY BitString);
213};
214
215#[cfg(test)]
216mod tests {
217 use hex_literal::hex;
218
219 use crate::{parse_ber_segmented, BerParser, Header, Input};
220
221 use super::BitString;
222
223 #[test]
224 fn test_bitstring_is_set() {
225 let obj = BitString::new(0, &[0x0f, 0x00, 0x40]);
226 assert!(!obj.is_set(0));
227 assert!(obj.is_set(7));
228 assert!(!obj.is_set(9));
229 assert!(obj.is_set(17));
230 }
231
232 #[test]
233 fn test_bitstring_to_bitvec() {
234 let obj = BitString::new(0, &[0x0f, 0x00, 0x40]);
235 let bv = obj.as_bitslice();
236 assert_eq!(bv.get(0).as_deref(), Some(&false));
237 assert_eq!(bv.get(7).as_deref(), Some(&true));
238 assert_eq!(bv.get(9).as_deref(), Some(&false));
239 assert_eq!(bv.get(17).as_deref(), Some(&true));
240 }
241
242 #[test]
243 fn test_bitstring_parse_segmented_primitive() {
244 let bytes = &hex!("0307 040A3B5F291CD0");
247 let (data, header) = Header::parse_ber(Input::from(bytes)).expect("header");
248 let (rem, b) = parse_ber_segmented::<BitString>(&header, data, 5).expect("parsing failed");
249 assert!(rem.is_empty());
250 assert_eq!(b.len(), bytes[3..].len() * 8 - usize::from(bytes[2]));
252
253 let bytes = &hex!("0301 04");
255 let (data, header) = Header::parse_ber(Input::from(bytes)).expect("header");
256 let _ = parse_ber_segmented::<BitString>(&header, data, 5).expect_err("invalid length");
257
258 let bytes = &hex!("0302 0901");
260 let (data, header) = Header::parse_ber(Input::from(bytes)).expect("header");
261 let _ = parse_ber_segmented::<BitString>(&header, data, 5).expect_err("invalid length");
262 }
263
264 #[test]
265 fn test_bitstring_parse_segmented_constructed() {
266 let bytes = &hex!(
269 "23 80\
270 0303 000A3B\
271 0305 045F291CD0\
272 00 00"
273 );
274 let (data, header) = Header::parse_ber(Input::from(bytes)).expect("header");
275 let (rem, b) = parse_ber_segmented::<BitString>(&header, data, 5).expect("parsing failed");
276 assert!(rem.is_empty());
277 assert_eq!(b.len(), 44);
278
279 let (data, header) = Header::parse_ber(Input::from(bytes)).expect("header");
281 let _ = parse_ber_segmented::<BitString>(&header, data, 1).expect_err("recursion limit");
282 }
283
284 #[cfg(feature = "std")]
285 mod tests_std {
286 use bitvec::{bits, order::Msb0};
287 use hex_literal::hex;
288
289 use crate::{BitString, ToBer};
290
291 #[test]
292 fn tober_bitstring() {
293 let immut = bits![u8, Msb0; 0, 1, 0, 0, 1, 0, 0, 1];
294 let bitstring = BitString::from(immut);
295 let mut v: Vec<u8> = Vec::new();
296 bitstring.ber_encode(&mut v).expect("serialization failed");
297 assert_eq!(&v, &hex! {"03020049"});
298 }
299 }
300}