1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
//! BER-encoded bit strings.
//!
//! This is a private module. Its public items are re-exported by the parent.

use std::io;
use bytes::Bytes;
use crate::{decode, encode};
use crate::decode::Source;
use crate::length::Length;
use crate::mode::Mode;
use crate::tag::Tag;


//------------ BitString -----------------------------------------------------

/// A bit string value.
///
/// Bit strings are a sequence of bits. Unlike [`OctetString`]s, they do not
/// need to contain a multiple of eight bits.
/// 
/// You can parse a bit string value out of a constructed value using the
/// [`take_from`] method. The [`from_content`] method parses the
/// content octets of a bit string value and can be used of the bit string is
/// implcitely tagged. Alternatively, you can create a new simple bit string
/// via the [`new`] method.
///
/// There are two types of methods for accessing the data in a bit string.
/// Methods starting with `bit` operate on the individual bits while those
/// prefixed with `octet` access entire octets and ignore the fact that there
/// may be unused bits in the final octet.
///
/// # BER Encoding
///
/// When encoded in BER, bit strings can either be a primitive or
/// constructed value.
///
/// If encoded as a primitive value, the first octet of the
/// content contains the number of unused bits in the last octet and the
/// following octets contain the bits with the first bit in the most
/// significant bit of the octet.
///
/// In the constructed encoding, the bit string is represented as a sequence
/// of bit strings which in turn may either be constructed or primitive
/// encodings. The only limitation in this nesting is that only the last
/// primitively encoded bit string may have a non-zero number of unused bits.
///
/// With BER, the sender can choose either form of encoding. With CER, the
/// primitive encoding should be chosen if its length would be no more than
/// 1000 octets long. Otherwise, the constructed encoding is to be chosen
/// which must contain a sequence of primitively encoded bit strings. Each of
/// these except for the last one must have content of exactly 1000 octets.
/// The last one must be a least one and at most 1000 octets of content.
/// With DER, only the primitive form is allowed.
///
/// # Limitation
///
/// At this time, the `BitString` type does not implement the constructed
/// encoding of a bit string.
///
/// [`OctetString`]: ../ostring/struct.OctetString.html
/// [`take_from`]: #method.take_from
/// [`from_content`]: #method.from_content
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct BitString {
    /// The number of unused bits in the last byte.
    unused: u8,

    /// The bytes of the bit string.
    bits: Bytes,
}

impl BitString {
    /// Creates a new bit string.
    pub fn new(unused: u8, bits: Bytes) -> Self {
        Self { unused, bits}
    }

    /// Returns the value of the given bit.
    pub fn bit(&self, bit: usize) -> bool {
        let idx = bit >> 3;
        if self.bits.len() <= idx {
            return false
        }
        let bit = 7 - (bit as u8 & 7);
        if self.bits.len() + 1 == idx && self.unused > bit {
            return false
        }
        self.bits[idx] & (1 << bit) != 0
    }

    /// Returns the number of bits in the bit string.
    pub fn bit_len(&self) -> usize {
        (self.bits.len() << 3) - (self.unused as usize)
    }

    /// Returns the number of unused bits in the last octet.
    pub fn unused(&self) -> u8 {
        self.unused
    }

    /// Returns the number of octets in the bit string.
    pub fn octet_len(&self) -> usize {
        self.bits.len()
    }

    /// Returns an iterator over the octets in the bit string.
    pub fn octets(&self) -> BitStringIter {
        BitStringIter(self.bits.iter())
    }

    /// Returns a slice of the octets in the bit string if available.
    ///
    /// The method will return `None` if the bit string is constructed from
    /// several parts.
    pub fn octet_slice(&self) -> Option<&[u8]> {
        Some(self.bits.as_ref())
    }

    /// Returns a bytes value of the octets of the bit string.
    ///
    /// This will be cheap for primitively encoded bit strings but requires
    /// allocations for complex ones.
    pub fn octet_bytes(&self) -> Bytes {
        self.bits.clone()
    }
}

/// # Decoding and Encoding
///
impl BitString {
    /// Takes a single bit string value from constructed content.
    pub fn take_from<S: decode::Source>(
        constructed: &mut decode::Constructed<S>
    ) -> Result<Self, S::Err> {
        constructed.take_value_if(Tag::BIT_STRING, Self::from_content)
    }

    /// Skip over a single bit string value inside constructed content.
    pub fn skip_in<S: decode::Source>(
        cons: &mut decode::Constructed<S>
    ) -> Result<(), S::Err> {
        cons.take_value_if(Tag::BIT_STRING, Self::skip_content)
    }
 
    /// Parses the content octets of a bit string value.
    pub fn from_content<S: decode::Source>(
        content: &mut decode::Content<S>
    ) -> Result<Self, S::Err> {
        match *content {
            decode::Content::Primitive(ref mut inner) => {
                if inner.mode() == Mode::Cer && inner.remaining() > 1000 {
                    xerr!(return Err(decode::Error::Malformed.into()))
                }
                Ok(BitString {
                    unused: inner.take_u8()?,
                    bits: inner.take_all()?,
                })
            }
            decode::Content::Constructed(ref inner) => {
                if inner.mode() == Mode::Der {
                    xerr!(Err(decode::Error::Malformed.into()))
                }
                else {
                    xerr!(Err(decode::Error::Unimplemented.into()))
                }
            }
        }
    }

    /// Skips over the content octets of a bit string value.
    pub fn skip_content<S: decode::Source>(
        content: &mut decode::Content<S>
    ) -> Result<(), S::Err> {
        match *content {
            decode::Content::Primitive(ref mut inner) => {
                if inner.mode() == Mode::Cer && inner.remaining() > 1000 {
                    xerr!(return Err(decode::Error::Malformed.into()))
                }
                inner.skip_all()
            }
            decode::Content::Constructed(ref inner) => {
                if inner.mode() == Mode::Der {
                    xerr!(Err(decode::Error::Malformed.into()))
                }
                else {
                    xerr!(Err(decode::Error::Unimplemented.into()))
                }
            }
        }
    }

    /// Returns a value encoder that encodes a bytes slice as an octet string.
    pub fn encode_slice<T>(value: T, unused: u8) -> BitSliceEncoder<T> {
        Self::encode_slice_as(value, unused, Tag::BIT_STRING)
    }

    /// Returns a value encoder that encodes a bytes slice as an octet string.
    pub fn encode_slice_as<T>(
        value: T,
        unused: u8,
        tag: Tag
    ) -> BitSliceEncoder<T> {
        BitSliceEncoder::new(value, unused, tag)
    }
}


//--- PrimitiveContent

impl encode::PrimitiveContent for BitString {
    const TAG: Tag = Tag::BIT_STRING;

    fn encoded_len(&self, _: Mode) -> usize {
        self.bits.len() + 1
    }

    fn write_encoded<W: io::Write>(
        &self,
        _: Mode,
        target: &mut W
    ) -> Result<(), io::Error> {
        target.write_all(&[self.unused])?;
        target.write_all(self.bits.as_ref())
    }
}


//------------ BitStringIter -------------------------------------------------

/// An iterator over the octets in the bit string.
#[derive(Clone, Debug)]
pub struct BitStringIter<'a>(::std::slice::Iter<'a, u8>);

impl<'a> Iterator for BitStringIter<'a> {
    type Item = u8;

    fn next(&mut self) -> Option<u8> {
        self.0.next().cloned()
    }
}


//------------ BitSliceEncoder -----------------------------------------------

/// A value encoder for a bytes slice as a bit string.
#[derive(Clone, Debug)]
pub struct BitSliceEncoder<T> {
    /// The slice to encode.
    slice: T,

    /// The unused bits in the last byte.
    unused: u8,

    /// The tag to be used for encoded value.
    tag: Tag,
}

impl<T> BitSliceEncoder<T> {
    /// Creates a new bit slice encoder.
    fn new(slice: T, unused: u8, tag: Tag) -> Self {
        BitSliceEncoder { slice, unused, tag }
    }
}


//--- encode::Values

impl<T: AsRef<[u8]>> encode::Values for BitSliceEncoder<T> {
    fn encoded_len(&self, mode: Mode) -> usize {
        if mode == Mode::Cer {
            unimplemented!()
        }
        let len = self.slice.as_ref().len() + 1;
        self.tag.encoded_len() + Length::Definite(len).encoded_len() + len
    }

    fn write_encoded<W: io::Write>(
        &self,
        mode: Mode,
        target: &mut W
    ) -> Result<(), io::Error> {
        if mode == Mode::Cer {
            unimplemented!()
        }
        self.tag.write_encoded(false, target)?;
        Length::Definite(self.slice.as_ref().len() + 1).write_encoded(target)?;
        target.write_all(&[self.unused])?;
        target.write_all(self.slice.as_ref())
    }
}