@@ -7,6 +7,7 @@ use crate::{
77 Result , Tag , ValueOrd , Writer ,
88} ;
99use core:: { cmp:: Ordering , iter:: FusedIterator } ;
10+ use unused_bits:: UnusedBits ;
1011
1112#[ cfg( feature = "flagset" ) ]
1213use core:: mem:: size_of_val;
@@ -20,40 +21,32 @@ use core::mem::size_of_val;
2021#[ derive( Copy , Clone , Debug , Eq , PartialEq , PartialOrd , Ord ) ]
2122pub struct BitStringRef < ' a > {
2223 /// Number of unused bits in the final octet.
23- unused_bits : u8 ,
24-
25- /// Length of this `BIT STRING` in bits.
26- bit_length : usize ,
24+ unused_bits : UnusedBits ,
2725
2826 /// Bitstring represented as a slice of bytes.
2927 inner : & ' a BytesRef ,
3028}
3129
3230impl < ' a > BitStringRef < ' a > {
33- /// Maximum number of unused bits allowed.
34- pub const MAX_UNUSED_BITS : u8 = 7 ;
35-
3631 /// Create a new ASN.1 `BIT STRING` from a byte slice.
3732 ///
3833 /// Accepts an optional number of "unused bits" (0-7) which are omitted
3934 /// from the final octet. This number is 0 if the value is octet-aligned.
4035 pub fn new ( unused_bits : u8 , bytes : & ' a [ u8 ] ) -> Result < Self > {
41- if ( unused_bits > Self :: MAX_UNUSED_BITS ) || ( unused_bits != 0 && bytes. is_empty ( ) ) {
42- return Err ( Self :: TAG . value_error ( ) . into ( ) ) ;
43- }
44-
36+ let unused_bits = UnusedBits :: new ( unused_bits, bytes) ?;
4537 let inner = BytesRef :: new ( bytes) . map_err ( |_| Self :: TAG . length_error ( ) ) ?;
38+ let value = Self :: new_unchecked ( unused_bits, inner) ;
39+ value
40+ . bit_len_checked ( )
41+ . ok_or_else ( || Error :: from ( ErrorKind :: Overflow ) ) ?;
42+ Ok ( value)
43+ }
4644
47- let bit_length = usize:: try_from ( inner. len ( ) ) ?
48- . checked_mul ( 8 )
49- . and_then ( |n| n. checked_sub ( usize:: from ( unused_bits) ) )
50- . ok_or ( ErrorKind :: Overflow ) ?;
51-
52- Ok ( Self {
53- unused_bits,
54- bit_length,
55- inner,
56- } )
45+ /// Internal function. Assumptions:
46+ /// - [`UnusedBits`] was checked for given [`BytesRef`],
47+ /// - [`BitStringRef::bit_len_checked`] was called and returned `Ok`.
48+ pub ( crate ) fn new_unchecked ( unused_bits : UnusedBits , inner : & ' a BytesRef ) -> Self {
49+ Self { unused_bits, inner }
5750 }
5851
5952 /// Create a new ASN.1 `BIT STRING` from the given bytes.
@@ -65,17 +58,31 @@ impl<'a> BitStringRef<'a> {
6558
6659 /// Get the number of unused bits in this byte slice.
6760 pub fn unused_bits ( & self ) -> u8 {
68- self . unused_bits
61+ * self . unused_bits
6962 }
7063
7164 /// Is the number of unused bits a value other than 0?
7265 pub fn has_unused_bits ( & self ) -> bool {
73- self . unused_bits != 0
66+ * self . unused_bits != 0
67+ }
68+
69+ /// Get the length of this `BIT STRING` in bits, or `None` if the value overflows.
70+ ///
71+ /// Ensured to be valid in the constructor.
72+ fn bit_len_checked ( & self ) -> Option < usize > {
73+ usize:: try_from ( self . inner . len ( ) )
74+ . ok ( )
75+ . and_then ( |n| n. checked_mul ( 8 ) )
76+ . and_then ( |n| n. checked_sub ( usize:: from ( * self . unused_bits ) ) )
7477 }
7578
7679 /// Get the length of this `BIT STRING` in bits.
7780 pub fn bit_len ( & self ) -> usize {
78- self . bit_length
81+ let bit_len = self . bit_len_checked ( ) ;
82+ debug_assert ! ( bit_len. is_some( ) ) ;
83+
84+ // Ensured to be valid in the constructor.
85+ bit_len. unwrap_or ( 0 )
7986 }
8087
8188 /// Get the number of bytes/octets needed to represent this `BIT STRING`
@@ -153,7 +160,7 @@ impl EncodeValue for BitStringRef<'_> {
153160 }
154161
155162 fn encode_value ( & self , writer : & mut impl Writer ) -> Result < ( ) > {
156- writer. write_byte ( self . unused_bits ) ?;
163+ writer. write_byte ( * self . unused_bits ) ?;
157164 writer. write ( self . raw_bytes ( ) )
158165 }
159166}
@@ -223,13 +230,48 @@ impl FixedTag for BitStringRef<'_> {
223230 const TAG : Tag = Tag :: BitString ;
224231}
225232
233+ /// Sealed, so that `UnusedBits` newtype can't be created directly
234+ mod unused_bits {
235+ use core:: ops:: Deref ;
236+
237+ use crate :: { Result , Tag } ;
238+
239+ /// Value in range `0..=7`
240+ ///
241+ /// Must be zero for empty `BIT STRING`.
242+ #[ derive( Copy , Clone , Debug , Eq , PartialEq , PartialOrd , Ord ) ]
243+ pub ( crate ) struct UnusedBits ( u8 ) ;
244+
245+ impl UnusedBits {
246+ /// Maximum number of unused bits allowed.
247+ pub const MAX_UNUSED_BITS : u8 = 7 ;
248+
249+ /// Represents number of "unused bits" (0-7) in `BIT STRING` which are omitted
250+ /// from the final octet. This number is 0 if the value is octet-aligned.
251+ pub fn new ( unused_bits : u8 , bytes : & [ u8 ] ) -> Result < Self > {
252+ if ( unused_bits > Self :: MAX_UNUSED_BITS ) || ( unused_bits != 0 && bytes. is_empty ( ) ) {
253+ Err ( Tag :: BitString . value_error ( ) . into ( ) )
254+ } else {
255+ Ok ( Self ( unused_bits) )
256+ }
257+ }
258+ }
259+ impl Deref for UnusedBits {
260+ type Target = u8 ;
261+
262+ fn deref ( & self ) -> & Self :: Target {
263+ & self . 0
264+ }
265+ }
266+ }
267+
226268// Implement by hand because the derive would create invalid values.
227269// Use the constructor to create a valid value.
228270#[ cfg( feature = "arbitrary" ) ]
229271impl < ' a > arbitrary:: Arbitrary < ' a > for BitStringRef < ' a > {
230272 fn arbitrary ( u : & mut arbitrary:: Unstructured < ' a > ) -> arbitrary:: Result < Self > {
231273 Self :: new (
232- u. int_in_range ( 0 ..=Self :: MAX_UNUSED_BITS ) ?,
274+ u. int_in_range ( 0 ..=UnusedBits :: MAX_UNUSED_BITS ) ?,
233275 <& ' a BytesRef >:: arbitrary ( u) ?. as_slice ( ) ,
234276 )
235277 . map_err ( |_| arbitrary:: Error :: IncorrectFormat )
@@ -256,10 +298,7 @@ mod allocating {
256298 #[ derive( Clone , Debug , Eq , PartialEq , PartialOrd , Ord ) ]
257299 pub struct BitString {
258300 /// Number of unused bits in the final octet.
259- unused_bits : u8 ,
260-
261- /// Length of this `BIT STRING` in bits.
262- bit_length : usize ,
301+ unused_bits : UnusedBits ,
263302
264303 /// Bitstring represented as a slice of bytes.
265304 inner : Vec < u8 > ,
@@ -277,11 +316,10 @@ mod allocating {
277316 let inner = bytes. into ( ) ;
278317
279318 // Ensure parameters parse successfully as a `BitStringRef`.
280- let bit_length = BitStringRef :: new ( unused_bits, & inner) ?. bit_length ;
319+ let ref_value = BitStringRef :: new ( unused_bits, & inner) ?;
281320
282321 Ok ( BitString {
283- unused_bits,
284- bit_length,
322+ unused_bits : ref_value. unused_bits ,
285323 inner,
286324 } )
287325 }
@@ -296,17 +334,34 @@ mod allocating {
296334 /// Get the number of unused bits in the octet serialization of this
297335 /// `BIT STRING`.
298336 pub fn unused_bits ( & self ) -> u8 {
299- self . unused_bits
337+ * self . unused_bits
300338 }
301339
302340 /// Is the number of unused bits a value other than 0?
303341 pub fn has_unused_bits ( & self ) -> bool {
304- self . unused_bits != 0
342+ * self . unused_bits != 0
343+ }
344+
345+ /// Returns inner [`BytesRef`] slice.
346+ pub ( crate ) fn bytes_ref ( & self ) -> & BytesRef {
347+ // Ensured to parse successfully in constructor
348+ BytesRef :: new_unchecked ( & self . inner )
349+ }
350+
351+ /// Get the length of this `BIT STRING` in bits, or `None` if the value overflows.
352+ ///
353+ /// Ensured to be valid in the constructor.
354+ fn bit_len_checked ( & self ) -> Option < usize > {
355+ BitStringRef :: new_unchecked ( self . unused_bits , self . bytes_ref ( ) ) . bit_len_checked ( )
305356 }
306357
307358 /// Get the length of this `BIT STRING` in bits.
308359 pub fn bit_len ( & self ) -> usize {
309- self . bit_length
360+ let bit_len = self . bit_len_checked ( ) ;
361+ debug_assert ! ( bit_len. is_some( ) ) ;
362+
363+ // Ensured to be valid in the constructor.
364+ bit_len. unwrap_or ( 0 )
310365 }
311366
312367 /// Is the inner byte slice empty?
@@ -364,7 +419,7 @@ mod allocating {
364419 }
365420
366421 fn encode_value ( & self , writer : & mut impl Writer ) -> Result < ( ) > {
367- writer. write_byte ( self . unused_bits ) ?;
422+ writer. write_byte ( * self . unused_bits ) ?;
368423 writer. write ( & self . inner )
369424 }
370425 }
@@ -376,8 +431,7 @@ mod allocating {
376431 impl < ' a > From < & ' a BitString > for BitStringRef < ' a > {
377432 fn from ( bit_string : & ' a BitString ) -> BitStringRef < ' a > {
378433 // Ensured to parse successfully in constructor
379- BitStringRef :: new ( bit_string. unused_bits , & bit_string. inner )
380- . expect ( "invalid BIT STRING" )
434+ BitStringRef :: new_unchecked ( bit_string. unused_bits , bit_string. bytes_ref ( ) )
381435 }
382436 }
383437
@@ -433,7 +487,6 @@ mod allocating {
433487 fn ref_to_owned ( & self ) -> Self :: Owned {
434488 BitString {
435489 unused_bits : self . unused_bits ,
436- bit_length : self . bit_length ,
437490 inner : Vec :: from ( self . inner . as_slice ( ) ) ,
438491 }
439492 }
0 commit comments