1 // Copyright 2015 Brian Smith.
2 //
3 // Permission to use, copy, modify, and/or distribute this software for any
4 // purpose with or without fee is hereby granted, provided that the above
5 // copyright notice and this permission notice appear in all copies.
6 //
7 // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
8 // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
10 // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 
15 //! Building blocks for parsing DER-encoded ASN.1 structures.
16 //!
17 //! This module contains the foundational parts of an ASN.1 DER parser.
18 
19 use super::Positive;
20 use crate::error;
21 
22 pub const CONSTRUCTED: u8 = 1 << 5;
23 pub const CONTEXT_SPECIFIC: u8 = 2 << 6;
24 
25 #[derive(Clone, Copy, PartialEq)]
26 #[repr(u8)]
27 pub enum Tag {
28     Boolean = 0x01,
29     Integer = 0x02,
30     BitString = 0x03,
31     OctetString = 0x04,
32     Null = 0x05,
33     OID = 0x06,
34     Sequence = CONSTRUCTED | 0x10, // 0x30
35     UTCTime = 0x17,
36     GeneralizedTime = 0x18,
37 
38     ContextSpecificConstructed0 = CONTEXT_SPECIFIC | CONSTRUCTED | 0,
39     ContextSpecificConstructed1 = CONTEXT_SPECIFIC | CONSTRUCTED | 1,
40     ContextSpecificConstructed3 = CONTEXT_SPECIFIC | CONSTRUCTED | 3,
41 }
42 
43 impl From<Tag> for usize {
from(tag: Tag) -> Self44     fn from(tag: Tag) -> Self {
45         tag as Self
46     }
47 }
48 
49 impl From<Tag> for u8 {
from(tag: Tag) -> Self50     fn from(tag: Tag) -> Self {
51         tag as Self
52     } // XXX: narrowing conversion.
53 }
54 
expect_tag_and_get_value<'a>( input: &mut untrusted::Reader<'a>, tag: Tag, ) -> Result<untrusted::Input<'a>, error::Unspecified>55 pub fn expect_tag_and_get_value<'a>(
56     input: &mut untrusted::Reader<'a>,
57     tag: Tag,
58 ) -> Result<untrusted::Input<'a>, error::Unspecified> {
59     let (actual_tag, inner) = read_tag_and_get_value(input)?;
60     if usize::from(tag) != usize::from(actual_tag) {
61         return Err(error::Unspecified);
62     }
63     Ok(inner)
64 }
65 
read_tag_and_get_value<'a>( input: &mut untrusted::Reader<'a>, ) -> Result<(u8, untrusted::Input<'a>), error::Unspecified>66 pub fn read_tag_and_get_value<'a>(
67     input: &mut untrusted::Reader<'a>,
68 ) -> Result<(u8, untrusted::Input<'a>), error::Unspecified> {
69     let tag = input.read_byte()?;
70     if (tag & 0x1F) == 0x1F {
71         return Err(error::Unspecified); // High tag number form is not allowed.
72     }
73 
74     // If the high order bit of the first byte is set to zero then the length
75     // is encoded in the seven remaining bits of that byte. Otherwise, those
76     // seven bits represent the number of bytes used to encode the length.
77     let length = match input.read_byte()? {
78         n if (n & 0x80) == 0 => usize::from(n),
79         0x81 => {
80             let second_byte = input.read_byte()?;
81             if second_byte < 128 {
82                 return Err(error::Unspecified); // Not the canonical encoding.
83             }
84             usize::from(second_byte)
85         }
86         0x82 => {
87             let second_byte = usize::from(input.read_byte()?);
88             let third_byte = usize::from(input.read_byte()?);
89             let combined = (second_byte << 8) | third_byte;
90             if combined < 256 {
91                 return Err(error::Unspecified); // Not the canonical encoding.
92             }
93             combined
94         }
95         _ => {
96             return Err(error::Unspecified); // We don't support longer lengths.
97         }
98     };
99 
100     let inner = input.read_bytes(length)?;
101     Ok((tag, inner))
102 }
103 
bit_string_with_no_unused_bits<'a>( input: &mut untrusted::Reader<'a>, ) -> Result<untrusted::Input<'a>, error::Unspecified>104 pub fn bit_string_with_no_unused_bits<'a>(
105     input: &mut untrusted::Reader<'a>,
106 ) -> Result<untrusted::Input<'a>, error::Unspecified> {
107     nested(input, Tag::BitString, error::Unspecified, |value| {
108         let unused_bits_at_end = value.read_byte().map_err(|_| error::Unspecified)?;
109         if unused_bits_at_end != 0 {
110             return Err(error::Unspecified);
111         }
112         Ok(value.read_bytes_to_end())
113     })
114 }
115 
116 // TODO: investigate taking decoder as a reference to reduce generated code
117 // size.
nested<'a, F, R, E: Copy>( input: &mut untrusted::Reader<'a>, tag: Tag, error: E, decoder: F, ) -> Result<R, E> where F: FnOnce(&mut untrusted::Reader<'a>) -> Result<R, E>,118 pub fn nested<'a, F, R, E: Copy>(
119     input: &mut untrusted::Reader<'a>,
120     tag: Tag,
121     error: E,
122     decoder: F,
123 ) -> Result<R, E>
124 where
125     F: FnOnce(&mut untrusted::Reader<'a>) -> Result<R, E>,
126 {
127     let inner = expect_tag_and_get_value(input, tag).map_err(|_| error)?;
128     inner.read_all(error, decoder)
129 }
130 
nonnegative_integer<'a>( input: &mut untrusted::Reader<'a>, min_value: u8, ) -> Result<untrusted::Input<'a>, error::Unspecified>131 fn nonnegative_integer<'a>(
132     input: &mut untrusted::Reader<'a>,
133     min_value: u8,
134 ) -> Result<untrusted::Input<'a>, error::Unspecified> {
135     // Verify that |input|, which has had any leading zero stripped off, is the
136     // encoding of a value of at least |min_value|.
137     fn check_minimum(input: untrusted::Input, min_value: u8) -> Result<(), error::Unspecified> {
138         input.read_all(error::Unspecified, |input| {
139             let first_byte = input.read_byte()?;
140             if input.at_end() && first_byte < min_value {
141                 return Err(error::Unspecified);
142             }
143             let _ = input.read_bytes_to_end();
144             Ok(())
145         })
146     }
147 
148     let value = expect_tag_and_get_value(input, Tag::Integer)?;
149 
150     value.read_all(error::Unspecified, |input| {
151         // Empty encodings are not allowed.
152         let first_byte = input.read_byte()?;
153 
154         if first_byte == 0 {
155             if input.at_end() {
156                 // |value| is the legal encoding of zero.
157                 if min_value > 0 {
158                     return Err(error::Unspecified);
159                 }
160                 return Ok(value);
161             }
162 
163             let r = input.read_bytes_to_end();
164             r.read_all(error::Unspecified, |input| {
165                 let second_byte = input.read_byte()?;
166                 if (second_byte & 0x80) == 0 {
167                     // A leading zero is only allowed when the value's high bit
168                     // is set.
169                     return Err(error::Unspecified);
170                 }
171                 let _ = input.read_bytes_to_end();
172                 Ok(())
173             })?;
174             check_minimum(r, min_value)?;
175             return Ok(r);
176         }
177 
178         // Negative values are not allowed.
179         if (first_byte & 0x80) != 0 {
180             return Err(error::Unspecified);
181         }
182 
183         let _ = input.read_bytes_to_end();
184         check_minimum(value, min_value)?;
185         Ok(value)
186     })
187 }
188 
189 /// Parse as integer with a value in the in the range [0, 255], returning its
190 /// numeric value. This is typically used for parsing version numbers.
191 #[inline]
small_nonnegative_integer(input: &mut untrusted::Reader) -> Result<u8, error::Unspecified>192 pub fn small_nonnegative_integer(input: &mut untrusted::Reader) -> Result<u8, error::Unspecified> {
193     let value = nonnegative_integer(input, 0)?;
194     value.read_all(error::Unspecified, |input| {
195         let r = input.read_byte()?;
196         Ok(r)
197     })
198 }
199 
200 /// Parses a positive DER integer, returning the big-endian-encoded value,
201 /// sans any leading zero byte.
positive_integer<'a>( input: &mut untrusted::Reader<'a>, ) -> Result<Positive<'a>, error::Unspecified>202 pub fn positive_integer<'a>(
203     input: &mut untrusted::Reader<'a>,
204 ) -> Result<Positive<'a>, error::Unspecified> {
205     Ok(Positive::new_non_empty_without_leading_zeros(
206         nonnegative_integer(input, 1)?,
207     ))
208 }
209 
210 #[cfg(test)]
211 mod tests {
212     use super::*;
213     use crate::error;
214 
with_good_i<F, R>(value: &[u8], f: F) where F: FnOnce(&mut untrusted::Reader) -> Result<R, error::Unspecified>,215     fn with_good_i<F, R>(value: &[u8], f: F)
216     where
217         F: FnOnce(&mut untrusted::Reader) -> Result<R, error::Unspecified>,
218     {
219         let r = untrusted::Input::from(value).read_all(error::Unspecified, f);
220         assert!(r.is_ok());
221     }
222 
with_bad_i<F, R>(value: &[u8], f: F) where F: FnOnce(&mut untrusted::Reader) -> Result<R, error::Unspecified>,223     fn with_bad_i<F, R>(value: &[u8], f: F)
224     where
225         F: FnOnce(&mut untrusted::Reader) -> Result<R, error::Unspecified>,
226     {
227         let r = untrusted::Input::from(value).read_all(error::Unspecified, f);
228         assert!(r.is_err());
229     }
230 
231     static ZERO_INTEGER: &[u8] = &[0x02, 0x01, 0x00];
232 
233     static GOOD_POSITIVE_INTEGERS: &[(&[u8], u8)] = &[
234         (&[0x02, 0x01, 0x01], 0x01),
235         (&[0x02, 0x01, 0x02], 0x02),
236         (&[0x02, 0x01, 0x7e], 0x7e),
237         (&[0x02, 0x01, 0x7f], 0x7f),
238         // Values that need to have an 0x00 prefix to disambiguate them from
239         // them from negative values.
240         (&[0x02, 0x02, 0x00, 0x80], 0x80),
241         (&[0x02, 0x02, 0x00, 0x81], 0x81),
242         (&[0x02, 0x02, 0x00, 0xfe], 0xfe),
243         (&[0x02, 0x02, 0x00, 0xff], 0xff),
244     ];
245 
246     static BAD_NONNEGATIVE_INTEGERS: &[&[u8]] = &[
247         &[],           // At end of input
248         &[0x02],       // Tag only
249         &[0x02, 0x00], // Empty value
250         // Length mismatch
251         &[0x02, 0x00, 0x01],
252         &[0x02, 0x01],
253         &[0x02, 0x01, 0x00, 0x01],
254         &[0x02, 0x01, 0x01, 0x00], // Would be valid if last byte is ignored.
255         &[0x02, 0x02, 0x01],
256         // Negative values
257         &[0x02, 0x01, 0x80],
258         &[0x02, 0x01, 0xfe],
259         &[0x02, 0x01, 0xff],
260         // Values that have an unnecessary leading 0x00
261         &[0x02, 0x02, 0x00, 0x00],
262         &[0x02, 0x02, 0x00, 0x01],
263         &[0x02, 0x02, 0x00, 0x02],
264         &[0x02, 0x02, 0x00, 0x7e],
265         &[0x02, 0x02, 0x00, 0x7f],
266     ];
267 
268     #[test]
test_small_nonnegative_integer()269     fn test_small_nonnegative_integer() {
270         with_good_i(ZERO_INTEGER, |input| {
271             assert_eq!(small_nonnegative_integer(input)?, 0x00);
272             Ok(())
273         });
274         for &(test_in, test_out) in GOOD_POSITIVE_INTEGERS.iter() {
275             with_good_i(test_in, |input| {
276                 assert_eq!(small_nonnegative_integer(input)?, test_out);
277                 Ok(())
278             });
279         }
280         for &test_in in BAD_NONNEGATIVE_INTEGERS.iter() {
281             with_bad_i(test_in, |input| {
282                 let _ = small_nonnegative_integer(input)?;
283                 Ok(())
284             });
285         }
286     }
287 
288     #[test]
test_positive_integer()289     fn test_positive_integer() {
290         with_bad_i(ZERO_INTEGER, |input| {
291             let _ = positive_integer(input)?;
292             Ok(())
293         });
294         for &(test_in, test_out) in GOOD_POSITIVE_INTEGERS.iter() {
295             with_good_i(test_in, |input| {
296                 let test_out = [test_out];
297                 assert_eq!(
298                     positive_integer(input)?.big_endian_without_leading_zero_as_input(),
299                     untrusted::Input::from(&test_out[..])
300                 );
301                 Ok(())
302             });
303         }
304         for &test_in in BAD_NONNEGATIVE_INTEGERS.iter() {
305             with_bad_i(test_in, |input| {
306                 let _ = positive_integer(input)?;
307                 Ok(())
308             });
309         }
310     }
311 }
312