1 //! The identifier octets of a BER encoded value.
2 //!
3 //! This is a private module. Its public items are re-exported by the parent.
4 
5 use std::{fmt, io};
6 use crate::decode;
7 
8 
9 //------------ Tag -----------------------------------------------------------
10 
11 /// The tag of a BER encoded value.
12 ///
13 /// Each BER encoded value starts with a sequence of one or more octets called
14 /// the _identifier octets._ They encode both the tag of the value as well as
15 /// whether the value uses primitive or constructed encoding. The `Tag` type
16 /// represents the tag only. The distinction between primitive and constructed
17 /// encoding is captured by the decoder types [`Primitive`] and
18 /// [`Constructed`] instead.
19 ///
20 /// The tag in turn consists of two parts: the class and the number – the
21 /// `Tag` type includes both of them.
22 ///
23 /// # Limitations
24 ///
25 /// We can only decode up to four identifier octets. That is, we only support tag
26 /// numbers between 0 and 1fffff.
27 ///
28 /// [`Primitive`]: decode/struct.Primitive.html
29 /// [`Constructed`]: decode/struct.Constructed.html
30 //
31 //  For the moment, the tag is stored with the constructed bit always cleared.
32 #[derive(Clone, Copy, Eq, PartialEq)]
33 pub struct Tag([u8; 4]);
34 
35 /// # Constants for Often Used Tag Values
36 ///
37 impl Tag {
38     /// The mask for checking the class.
39     const CLASS_MASK: u8 = 0xc0;
40 
41     /// The mask for checking whether the value is a primitive
42     ///
43     /// A value of 0 indicates primitive.
44     const CONSTRUCTED_MASK: u8 = 0x20;
45 
46     /// The mask for the fourth octet data (bits 24-32).
47     ///
48     /// (5 bits – 0b0001_1111).
49     const SINGLEBYTE_DATA_MASK: u8 = 0x1f;
50 
51     /// The mask for octet data.
52     ///
53     /// (7 bits – 0b0111_1111).
54     const MULTIBYTE_DATA_MASK: u8 = 0x7f;
55 
56     /// The mask for the last octet with identifier data
57     ///
58     /// (1 bit – 0b1000_0000, it is cleared in the last octet).
59     const LAST_OCTET_MASK: u8 = 0x80;
60 
61     /// The largest tag number possible with three octets.
62     const MAX_VAL_SPAN_3_OCTETS: u32 = 0x001f_ffff;
63 
64     /// The largest tag number possible with two octets.
65     const MAX_VAL_SPAN_2_OCTETS: u32 = 0x3fff;
66 
67     /// The largest tag number possible with one octet.
68     const MAX_VAL_SPAN_1_OCTET: u32 = 0x7f;
69 
70     /// The largest tag number possible with the fourth octet.
71     const MAX_VAL_FOURTH_OCTET: u32 = 0x1e;
72 
73     /// The tag value representing for the ‘universal’ class.
74     const UNIVERSAL: u8 = 0x00;
75 
76     /// The tag value representing the ‘application’ class.
77     const APPLICATION: u8 = 0x40;
78 
79     /// The tag value representing the ‘context-specific’ class.
80     const CONTEXT_SPECIFIC: u8 = 0x80;
81 
82     /// The tag value representing the `private` class.
83     const PRIVATE: u8 = 0xc0;
84 
85     /// The tag marking the end-of-value in an indefinite length value.
86     ///
87     /// This is UNIVERSAL 0.
88     pub const END_OF_VALUE: Self = Tag([0, 0, 0, 0]);
89 
90     //--- Universal Tags
91     //
92     // See clause 8.4 of X.690.
93 
94     /// The tag for the BOOLEAN type, UNIVERSAL 1.
95     pub const BOOLEAN: Self = Tag([1, 0, 0, 0]);
96 
97     /// The tag for the INTEGER type, UNIVERSAL 2.
98     pub const INTEGER: Self = Tag([2, 0, 0, 0]);
99 
100     /// The tag for the BIT STRING type, UNIVERSAL 3.
101     pub const BIT_STRING: Self = Tag([3, 0, 0, 0]);
102 
103     /// The tag for the OCTET STRING type, UNIVERSAL 4.
104     pub const OCTET_STRING: Self = Tag([4, 0, 0, 0]);
105 
106     /// The tag for the NULL type, UNIVERSAL 5.
107     pub const NULL: Self = Tag([5, 0, 0, 0]);
108 
109     /// The tag for the OBJECT IDENTIFIER type, UNIVERSAL 6.
110     pub const OID: Self = Tag([6, 0, 0, 0]);
111 
112     /// The tag for the ObjectDescriptor type, UNIVERSAL 7.
113     pub const OBJECT_DESCRIPTOR: Self = Tag([7, 0, 0, 0]);
114 
115     /// The tag for the EXTERNAL and Instance-of types, UNIVERSAL 8.
116     pub const EXTERNAL: Self = Tag([8, 0, 0, 0]);
117 
118     /// The tag for the REAL type, UNIVERSAL 9.
119     pub const REAL: Self = Tag([9, 0, 0, 0]);
120 
121     /// The tag for the ENUMERATED type, UNIVERAL 10.
122     pub const ENUMERATED: Self = Tag([10, 0, 0, 0]);
123 
124     /// The tag for the EMBEDDED PDV type, UNIVERAL 11.
125     pub const EMBEDDED_PDV: Self = Tag([11, 0, 0, 0]);
126 
127     /// The tag for the UTF8String type, UNIVERSAL 12
128     pub const UTF8_STRING: Self = Tag([12, 0, 0, 0]);
129 
130     /// The tag for the RELATIVE-OID type, UNIVERAL 13.
131     pub const RELATIVE_OID: Self = Tag([13, 0, 0, 0]);
132 
133     /// The tag for the SEQUENCE and SEQUENCE OF types, UNIVERSAL 16.
134     pub const SEQUENCE: Self = Tag([16, 0, 0, 0]);
135 
136     /// The tag for the SET and SET OF types, UNIVERSAL 17.
137     pub const SET: Self = Tag([17, 0, 0, 0]);
138 
139     /// The tag for the NumericString type, UNIVERSAL 18.
140     pub const NUMERIC_STRING: Self = Tag([18, 0, 0, 0]);
141 
142     /// The tag for the PrintableString type, UNIVERSAL 19.
143     pub const PRINTABLE_STRING: Self = Tag([19, 0, 0, 0]);
144 
145     /// The tag for the TeletexString type, UNIVERSAL 20.
146     pub const TELETEX_STRING: Self = Tag([20, 0, 0, 0]);
147 
148     /// The tag for the VideotexString type, UNIVERSAL 21.
149     pub const VIDEOTEX_STRING: Self = Tag([21, 0, 0, 0]);
150 
151     /// The tag for the IA5String type, UNIVERSAL 22.
152     pub const IA5_STRING: Self = Tag([22, 0, 0, 0]);
153 
154     /// The tag for the UTCTime type, UNIVERSAL 23.
155     pub const UTC_TIME: Self = Tag([23, 0, 0, 0]);
156 
157     /// The tag for the GeneralizedType type, UNIVERAL 24.
158     pub const GENERALIZED_TIME: Self = Tag([24, 0, 0, 0]);
159 
160     /// The tag for the GraphicString type, UNIVERSAL 25.
161     pub const GRAPHIC_STRING: Self = Tag([25, 0, 0, 0]);
162 
163     /// The tag for the VisibleString type, UNIVERSAL 26.
164     pub const VISIBLE_STRING: Self = Tag([26, 0, 0, 0]);
165 
166     /// The tag for the GeneralString type, UNIVERSAL 27.
167     pub const GENERAL_STRING: Self = Tag([27, 0, 0, 0]);
168 
169     /// The tag for the UniversalString type, UNIVERSAL 28.
170     pub const UNIVERSAL_STRING: Self = Tag([28, 0, 0, 0]);
171 
172     /// The tag for the BMPString type, UNIVERSAL 29.
173     pub const BMP_STRING: Self = Tag([29, 0, 0, 0]);
174 
175     //--- The first few context-specific tags.
176     //
177     //    These will be removed once we can have `ctx` be a const fn.
178 
179     /// The tag context specific tag [0].
180     pub const CTX_0: Self = Tag([Tag::CONTEXT_SPECIFIC, 0, 0, 0]);
181 
182     /// The tag context specific tag [1].
183     pub const CTX_1: Self = Tag([Tag::CONTEXT_SPECIFIC | 1, 0, 0, 0]);
184 
185     /// The tag context specific tag [2].
186     pub const CTX_2: Self = Tag([Tag::CONTEXT_SPECIFIC | 2, 0, 0, 0]);
187 
188     /// The tag context specific tag [3].
189     pub const CTX_3: Self = Tag([Tag::CONTEXT_SPECIFIC | 3, 0, 0, 0]);
190 
191     /// The tag context specific tag [4].
192     pub const CTX_4: Self = Tag([Tag::CONTEXT_SPECIFIC | 4, 0, 0, 0]);
193 
194     /// The tag context specific tag [5].
195     pub const CTX_5: Self = Tag([Tag::CONTEXT_SPECIFIC | 5, 0, 0, 0]);
196 
197     /// The tag context specific tag [6].
198     pub const CTX_6: Self = Tag([Tag::CONTEXT_SPECIFIC | 6, 0, 0, 0]);
199 }
200 
201 impl Tag {
202     /// Encodes a number into the identifier representation.
203     ///
204     /// There are two forms:
205     /// * low tag number (for tag numbers between 0 and 30):
206     ///     One octet. Bits 8 and 7 specify the class, bit 6 indicates whether
207     ///     the encoding is primitive (0), and bits 5-1 give the tag number.
208     /// * high tag number (for tag numbers 31 and greater):
209     ///     Two or more octets. First octet is as in low-tag-number form,
210     ///     except that bits 5-1 all have value 1. Second and following octets
211     ///     give the tag number, base 128, most significant digit first, with
212     ///     as few digits as possible, and with the bit 8 of each octet except
213     ///     the last set to 1.
214     //
215     /// # Panics
216     ///
217     /// This function panics if the tag number is greater than
218     /// `Self::MAX_VAL_SPAN_3_OCTETS`.
219     #[inline]
new(class_mask: u8, number: u32) -> Self220     fn new(class_mask: u8, number: u32) -> Self {
221         assert!(number <= Tag::MAX_VAL_SPAN_3_OCTETS);
222         if number <= Tag::MAX_VAL_FOURTH_OCTET {
223             Tag([class_mask | number as u8, 0, 0, 0])
224         } else if number <= Tag::MAX_VAL_SPAN_1_OCTET {
225             // Fit the number in the third octets
226             let number = number as u8;
227             Tag([class_mask | Tag::SINGLEBYTE_DATA_MASK, number, 0, 0])
228         } else if number <= Tag::MAX_VAL_SPAN_2_OCTETS {
229             // Fit the number in the second and the third octets
230             let first_part = {
231                 Tag::MULTIBYTE_DATA_MASK & ((number >> 7) as u8)
232                 | Tag::LAST_OCTET_MASK
233             };
234             let second_part = Tag::MULTIBYTE_DATA_MASK & (number as u8);
235             Tag([
236                 class_mask | Tag::SINGLEBYTE_DATA_MASK, first_part,
237                 second_part, 0
238             ])
239         } else {
240             // Fit the number in the first, second and the third octets
241             let first_part = {
242                 Tag::MULTIBYTE_DATA_MASK & ((number >> 14) as u8)
243                 | Tag::LAST_OCTET_MASK
244             };
245             let second_part = {
246                 Tag::MULTIBYTE_DATA_MASK & ((number >> 7) as u8)
247                 | Tag::LAST_OCTET_MASK
248             };
249             let third_part = Tag::MULTIBYTE_DATA_MASK & (number as u8);
250             Tag([
251                 class_mask | Tag::SINGLEBYTE_DATA_MASK, first_part,
252                 second_part, third_part
253             ])
254         }
255     }
256 
257     /// Creates a new tag in the universal class with the given tag number.
258     ///
259     /// # Panics
260     ///
261     /// Currently, this function panics if the tag number is greater than
262     /// `MAX_VAL_SPAN_3_OCTETS`.
universal(number: u32) -> Self263     pub fn universal(number: u32) -> Self {
264         Tag::new(Tag::UNIVERSAL, number)
265     }
266 
267     /// Creates a new tag in the application class with the given tag number.
268     ///
269     /// # Panics
270     ///
271     /// Currently, this function panics if the tag number is greater than
272     /// `MAX_VAL_SPAN_3_OCTETS`.
application(number: u32) -> Self273     pub fn application(number: u32) -> Self {
274         Tag::new(Tag::APPLICATION, number)
275     }
276 
277     /// Creates a new tag in the context specific class.
278     ///
279     /// # Panics
280     ///
281     /// Currently, this function panics if the provided tag number is greater
282     /// than `MAX_VAL_SPAN_3_OCTETS`.
ctx(number: u32) -> Self283     pub fn ctx(number: u32) -> Self {
284         Tag::new(Tag::CONTEXT_SPECIFIC, number)
285     }
286 
287     /// Creates a new tag in the private class with the given tag number.
288     ///
289     /// # Panics
290     ///
291     /// Currently, this function panics if the provided tag number is greater
292     /// than `MAX_VAL_SPAN_3_OCTETS`.
private(number: u32) -> Self293     pub fn private(number: u32) -> Self {
294         Tag::new(Tag::PRIVATE, number)
295     }
296 
297     /// Returns whether the tag is of the universal class.
is_universal(self) -> bool298     pub fn is_universal(self) -> bool {
299         self.0[0] & Self::CLASS_MASK == Self::UNIVERSAL
300     }
301 
302     /// Returns whether the tag is of the application class.
is_application(self) -> bool303     pub fn is_application(self) -> bool {
304         self.0[0] & Self::CLASS_MASK == Self::APPLICATION
305     }
306 
307     /// Returns whether the tag is of the context specific class.
is_context_specific(self) -> bool308     pub fn is_context_specific(self) -> bool {
309         self.0[0] & Self::CLASS_MASK == Self::CONTEXT_SPECIFIC
310     }
311 
312     /// Returns whether the tag is of the private class.
is_private(self) -> bool313     pub fn is_private(self) -> bool {
314         self.0[0] & Self::CLASS_MASK == Self::PRIVATE
315     }
316 
317     /// Returns the number of the tag.
number(self) -> u32318     pub fn number(self) -> u32 {
319         if (Tag::SINGLEBYTE_DATA_MASK & self.0[0]) != Tag::SINGLEBYTE_DATA_MASK {
320             // It's a single byte identifier
321             u32::from(Tag::SINGLEBYTE_DATA_MASK & self.0[0])
322         } else if Tag::LAST_OCTET_MASK & self.0[1] == 0 {
323             // It's a multibyte that starts and ends in the third octet
324             u32::from(Tag::MULTIBYTE_DATA_MASK & self.0[1])
325         } else if Tag::LAST_OCTET_MASK & self.0[2] == 0 {
326             // It's a multibyte that starts in the second octet and ends in
327             // the third octet
328             u32::from(Tag::MULTIBYTE_DATA_MASK & self.0[1]) << 7
329             | u32::from(Tag::MULTIBYTE_DATA_MASK & self.0[2])
330         } else {
331             // It's a multibyte that spans the first three octets
332             u32::from(Tag::MULTIBYTE_DATA_MASK & self.0[1]) << 14
333             | u32::from(Tag::MULTIBYTE_DATA_MASK & self.0[2]) << 7
334             | u32::from(Tag::MULTIBYTE_DATA_MASK & self.0[3])
335         }
336     }
337 
338     /// Takes a tag from the beginning of a source.
339     ///
340     /// Upon success, returns both the tag and whether the value is
341     /// constructed. If there are no more octets available in the source,
342     /// an error is returned.
take_from<S: decode::Source>( source: &mut S, ) -> Result<(Self, bool), S::Err>343     pub fn take_from<S: decode::Source>(
344         source: &mut S,
345     ) -> Result<(Self, bool), S::Err> {
346         let byte = source.take_u8()?;
347         // clear constructed bit
348         let mut data = [byte & !Tag::CONSTRUCTED_MASK, 0, 0, 0];
349         let constructed = byte & Tag::CONSTRUCTED_MASK != 0;
350         if (data[0] & Tag::SINGLEBYTE_DATA_MASK) == Tag::SINGLEBYTE_DATA_MASK {
351             for i in 1..=3 {
352                 data[i] = source.take_u8()?;
353                 if data[i] & Tag::LAST_OCTET_MASK == 0 {
354                     return Ok((Tag(data), constructed));
355                 }
356             }
357         } else {
358             return Ok((Tag(data), constructed));
359         }
360         xerr!(Err(decode::Error::Unimplemented.into()))
361     }
362 
363     /// Takes a tag from the beginning of a resource if it matches this tag.
364     ///
365     /// If there is no more data available in the source or if the tag is
366     /// something else, returns `Ok(None)`. If the tag matches `self`, returns
367     /// whether the value is constructed.
take_from_if<S: decode::Source>( self, source: &mut S, ) -> Result<Option<bool>, S::Err>368     pub fn take_from_if<S: decode::Source>(
369         self,
370         source: &mut S,
371     ) -> Result<Option<bool>, S::Err> {
372         if source.request(1)? == 0 {
373             return Ok(None)
374         }
375         let byte = source.slice()[0];
376         // clear constructed bit
377         let mut data = [byte & !Tag::CONSTRUCTED_MASK, 0, 0, 0];
378         if (data[0] & Tag::SINGLEBYTE_DATA_MASK) == Tag::SINGLEBYTE_DATA_MASK {
379             let mut i = 1;
380             loop {
381                 if source.request(i + 1)? == 0 {
382                     // Not enough data for a complete tag.
383                     xerr!(return Err(decode::Error::Malformed.into()))
384                 }
385                 data[i] = source.slice()[i];
386                 if data[i] & Tag::LAST_OCTET_MASK == 0 {
387                     break
388                 }
389                 // We don’t support tags larger than 4 bytes.
390                 if i == 3 {
391                     xerr!(return Err(decode::Error::Unimplemented.into()))
392                 }
393                 i += 1;
394             }
395         }
396         let (tag, compressed) = (Tag(data), byte & Tag::CONSTRUCTED_MASK != 0);
397         if tag == self {
398             source.advance(tag.encoded_len())?;
399             Ok(Some(compressed))
400         }
401         else {
402             Ok(None)
403         }
404     }
405 
406     /// Returns the number of octets of the encoded form of the tag.
407     #[allow(clippy::trivially_copy_pass_by_ref)] // for possible multi-byte tags
encoded_len(&self) -> usize408     pub fn encoded_len(&self) -> usize {
409         if (Tag::SINGLEBYTE_DATA_MASK & self.0[0]) != Tag::SINGLEBYTE_DATA_MASK {
410             1
411         } else if Tag::LAST_OCTET_MASK & self.0[1] == 0 {
412             2
413         } else if Tag::LAST_OCTET_MASK & self.0[2] == 0 {
414             3
415         } else {
416             4
417         }
418     }
419 
420     /// Encodes the tag into a target.
421     ///
422     /// If `constructed` is `true`, the encoded tag will signal a value in
423     /// constructed encoding and primitive encoding otherwise.
424     #[allow(clippy::trivially_copy_pass_by_ref)] // for possible multi-byte tags
write_encoded<W: io::Write>( &self, constructed: bool, target: &mut W ) -> Result<(), io::Error>425     pub fn write_encoded<W: io::Write>(
426         &self,
427         constructed: bool,
428         target: &mut W
429     ) -> Result<(), io::Error> {
430         let mut buf = self.0;
431         if constructed {
432             buf[0] |= Tag::CONSTRUCTED_MASK
433         }
434         target.write_all(&buf[..self.encoded_len()])
435     }
436 }
437 
438 impl fmt::Display for Tag {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result439     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
440         match *self {
441             Tag::BOOLEAN => write!(f, "BOOLEAN"),
442             Tag::INTEGER => write!(f, "INTEGER"),
443             Tag::BIT_STRING => write!(f, "BIT STRING"),
444             Tag::OCTET_STRING => write!(f, "OCTET STRING"),
445             Tag::NULL => write!(f, "NULL"),
446             Tag::OID => write!(f, "OBJECT IDENTIFIER"),
447             Tag::OBJECT_DESCRIPTOR => write!(f, "ObjectDescriptor"),
448             Tag::EXTERNAL => write!(f, "EXTERNAL"),
449             Tag::REAL => write!(f, "REAL"),
450             Tag::ENUMERATED => write!(f, "ENUMERATED"),
451             Tag::EMBEDDED_PDV => write!(f, "EMBEDDED PDV"),
452             Tag::UTF8_STRING => write!(f, "UTF8String"),
453             Tag::RELATIVE_OID => write!(f, "RELATIVE-OID"),
454             Tag::SEQUENCE => write!(f, "SEQUENCE"),
455             Tag::SET => write!(f, "SET"),
456             Tag::NUMERIC_STRING => write!(f, "NumericString"),
457             Tag::PRINTABLE_STRING => write!(f, "PrintableString"),
458             Tag::TELETEX_STRING => write!(f, "TeletexString"),
459             Tag::VIDEOTEX_STRING => write!(f, "VideotexString"),
460             Tag::IA5_STRING => write!(f, "IA5String"),
461             Tag::UTC_TIME => write!(f, "UTCTime"),
462             Tag::GENERALIZED_TIME => write!(f, "GeneralizedTime"),
463             Tag::GRAPHIC_STRING => write!(f, "GraphicString"),
464             Tag::VISIBLE_STRING => write!(f, "VisibleString"),
465             Tag::GENERAL_STRING => write!(f, "GeneralString"),
466             Tag::UNIVERSAL_STRING => write!(f, "UniversalString"),
467             Tag::BMP_STRING => write!(f, "BMPString"),
468             tag => {
469                 match tag.0[0] & Tag::CLASS_MASK {
470                     Tag::UNIVERSAL => write!(f, "[UNIVERSAL ")?,
471                     Tag::APPLICATION => write!(f, "[APPLICATION ")?,
472                     Tag::CONTEXT_SPECIFIC => write!(f, "[")?,
473                     Tag::PRIVATE => write!(f, "[PRIVATE ")?,
474                     _ => unreachable!()
475                 }
476                 write!(f, "{}]", tag.number())
477             }
478         }
479     }
480 }
481 
482 impl fmt::Debug for Tag {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result483     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
484         write!(f, "Tag({})", self)
485     }
486 }
487 
488 //============ Tests =========================================================
489 
490 #[cfg(test)]
491 mod test {
492     use super::*;
493 
494     const TYPES: &[u8] = &[Tag::UNIVERSAL, Tag::APPLICATION, Tag::CONTEXT_SPECIFIC, Tag::PRIVATE];
495 
496     #[test]
test_single_octet_tags()497     fn test_single_octet_tags() {
498         // Test edge cases.
499         let range: Vec<u32> = (0..5).chain(
500             Tag::MAX_VAL_FOURTH_OCTET-5..Tag::MAX_VAL_FOURTH_OCTET
501         ).collect();
502         for &typ in TYPES {
503             for i in range.clone() {
504                 let tag = Tag::new(typ, i);
505                 let expected = Tag([typ | i as u8, 0, 0, 0]);
506                 let decoded = Tag::take_from(&mut &tag.0[..]).unwrap();
507                 assert_eq!(tag.take_from_if(&mut &tag.0[..]), Ok(Some(false)));
508                 // The value is not constructed.
509                 assert_eq!(decoded.1, false);
510                 // The tag is the same
511                 assert_eq!(decoded.0, expected);
512                 // We get the same number back.
513                 assert_eq!(tag.number(), i);
514                 // The representation is correct.
515                 assert_eq!(tag, expected);
516 
517             }
518         }
519     }
520 
521     #[test]
test_double_octets_tags()522     fn test_double_octets_tags() {
523         // Test edge cases.
524         let range: Vec<u32> = (
525             Tag::MAX_VAL_FOURTH_OCTET+1..Tag::MAX_VAL_FOURTH_OCTET+5
526         ).chain(
527             Tag::MAX_VAL_SPAN_1_OCTET-5..Tag::MAX_VAL_SPAN_1_OCTET
528         ).collect();
529         for &typ in TYPES {
530             for i in range.clone() {
531                 let tag = Tag::new(typ, i);
532                 let expected = Tag([
533                         Tag::SINGLEBYTE_DATA_MASK | typ, i as u8, 0, 0
534                 ]);
535                 let decoded = Tag::take_from(&mut &tag.0[..]).unwrap();
536                 assert_eq!(tag.take_from_if(&mut &tag.0[..]), Ok(Some(false)));
537                 // The value is not constructed.
538                 assert_eq!(decoded.1, false);
539                 // The tag is the same
540                 assert_eq!(decoded.0, expected);
541                 assert_eq!(tag.number(), i);
542                 assert_eq!(tag, expected);
543             }
544         }
545     }
546 
547     #[test]
test_three_octets_tags()548     fn test_three_octets_tags() {
549         // Test edge cases.
550         let range: Vec<u32> = (
551             Tag::MAX_VAL_SPAN_1_OCTET+1..Tag::MAX_VAL_SPAN_1_OCTET + 5
552         ).chain(
553             Tag::MAX_VAL_SPAN_2_OCTETS-5..Tag::MAX_VAL_SPAN_2_OCTETS
554         ).collect();
555         for &typ in TYPES {
556             for i in range.clone() {
557                 let tag = Tag::new(typ, i);
558                 let expected = Tag([
559                     Tag::SINGLEBYTE_DATA_MASK | typ,
560                     (i >> 7) as u8 | Tag::LAST_OCTET_MASK,
561                     i as u8 & !Tag::LAST_OCTET_MASK,
562                     0
563                 ]);
564                 let decoded = Tag::take_from(&mut &tag.0[..]).unwrap();
565                 assert_eq!(tag.take_from_if(&mut &tag.0[..]), Ok(Some(false)));
566                 // The value is not constructed.
567                 assert_eq!(decoded.1, false);
568                 // The tag is the same
569                 assert_eq!(decoded.0, expected);
570                 assert_eq!(tag.number(), i);
571                 assert_eq!(tag, expected);
572             }
573         }
574     }
575 
576     #[test]
test_four_octets_tags()577     fn test_four_octets_tags() {
578         // Test edge cases.
579         let range: Vec<u32> = (
580             Tag::MAX_VAL_SPAN_2_OCTETS+1..Tag::MAX_VAL_SPAN_2_OCTETS + 5
581         ).chain(
582             Tag::MAX_VAL_SPAN_3_OCTETS-5..Tag::MAX_VAL_SPAN_3_OCTETS
583         ).collect();
584         for &typ in TYPES {
585             for i in range.clone() {
586                 let tag = Tag::new(typ, i);
587                 let expected = Tag([
588                     Tag::SINGLEBYTE_DATA_MASK | typ,
589                     (i >> 14) as u8 | Tag::LAST_OCTET_MASK,
590                     (i >> 7) as u8 | Tag::LAST_OCTET_MASK,
591                     i as u8 & !Tag::LAST_OCTET_MASK
592                 ]);
593                 let decoded = Tag::take_from(&mut &tag.0[..]).unwrap();
594                 assert_eq!(tag.take_from_if(&mut &tag.0[..]), Ok(Some(false)));
595                 // The value is not constructed.
596                 assert_eq!(decoded.1, false);
597                 // The tag is the same
598                 assert_eq!(decoded.0, expected);
599                 assert_eq!(tag.number(), i);
600                 assert_eq!(tag, expected);
601             }
602         }
603     }
604 
605     #[test]
test_tags_failures()606     fn test_tags_failures() {
607         let large_tag = [
608             0b1111_1111, 0b1000_0000, 0b1000_0000, 0b1000_0000, 0b1000_0000
609         ];
610         assert_eq!(
611             Tag::take_from(&mut &large_tag[..]),
612             Err(decode::Error::Unimplemented)
613         );
614         let short_tag = [0b1111_1111, 0b1000_0000];
615         assert_eq!(
616             Tag::take_from(&mut &short_tag[..]),
617             Err(decode::Error::Malformed)
618         );
619     }
620 }
621