rasn/ber/
enc.rs

1//! # Encoding BER.
2
3mod config;
4
5use alloc::{borrow::ToOwned, collections::VecDeque, string::ToString, vec::Vec};
6use chrono::Timelike;
7
8use super::Identifier;
9use crate::{
10    bits::octet_string_ascending,
11    types::{
12        self,
13        oid::{MAX_OID_FIRST_OCTET, MAX_OID_SECOND_OCTET},
14        Constraints, Enumerated, Tag,
15    },
16    Codec, Encode,
17};
18
19pub use crate::error::{BerEncodeErrorKind, EncodeError, EncodeErrorKind};
20pub use config::EncoderOptions;
21
22const START_OF_CONTENTS: u8 = 0x80;
23const END_OF_CONTENTS: &[u8] = &[0, 0];
24
25/// A BER and variants encoder. Capable of encoding to BER, CER, and DER.
26pub struct Encoder {
27    output: Vec<u8>,
28    config: EncoderOptions,
29    is_set_encoding: bool,
30    set_buffer: alloc::collections::BTreeMap<Tag, Vec<u8>>,
31}
32
33/// A convenience type around results needing to return one or many bytes.
34enum ByteOrBytes {
35    Single(u8),
36    Many(Vec<u8>),
37}
38
39impl Encoder {
40    /// Creates a new instance from the given `config`.
41    #[must_use]
42    pub fn new(config: EncoderOptions) -> Self {
43        Self {
44            config,
45            is_set_encoding: false,
46            output: <_>::default(),
47            set_buffer: <_>::default(),
48        }
49    }
50    #[must_use]
51    pub fn codec(&self) -> crate::Codec {
52        self.config.current_codec()
53    }
54
55    /// Creates a new instance from the given `config`, and uses SET encoding
56    /// logic, ensuring that all messages are encoded in order by tag.
57    #[must_use]
58    pub fn new_set(config: EncoderOptions) -> Self {
59        Self {
60            config,
61            is_set_encoding: true,
62            output: <_>::default(),
63            set_buffer: <_>::default(),
64        }
65    }
66
67    /// Creates a new instance from the given `config` and a user-supplied
68    /// `Vec<u8>` buffer. This allows reuse of an existing buffer instead of
69    /// allocating a new encoding buffer each time an [`Encoder`] is created.
70    /// The buffer will be cleared before use.
71    pub fn new_with_buffer(config: EncoderOptions, mut buffer: Vec<u8>) -> Self {
72        buffer.clear();
73        Self {
74            output: buffer,
75            config,
76            is_set_encoding: false,
77            set_buffer: <_>::default(),
78        }
79    }
80
81    /// Consumes the encoder and returns the output of the encoding.
82    pub fn output(self) -> Vec<u8> {
83        if self.is_set_encoding {
84            self.set_buffer
85                .into_values()
86                .fold(Vec::new(), |mut acc, mut field| {
87                    acc.append(&mut field);
88                    acc
89                })
90        } else {
91            self.output
92        }
93    }
94
95    fn append_byte_or_bytes(&mut self, bytes: ByteOrBytes) {
96        match bytes {
97            ByteOrBytes::Single(b) => self.output.push(b),
98            ByteOrBytes::Many(mut bs) => self.output.append(&mut bs),
99        }
100    }
101
102    pub(super) fn encode_as_base128(&self, number: u32, buffer: &mut Vec<u8>) {
103        const WIDTH: u8 = 7;
104        const SEVEN_BITS: u8 = 0x7F;
105        const EIGHTH_BIT: u8 = 0x80;
106
107        if number < EIGHTH_BIT as u32 {
108            buffer.push(number as u8);
109        } else {
110            let mut n: u8;
111            let mut bits_left = 35;
112            let mut cont = false;
113            while bits_left > 0 {
114                bits_left -= WIDTH;
115                n = ((number >> bits_left) as u8) & SEVEN_BITS;
116                if n > 0 || cont {
117                    buffer.push(if bits_left > 0 { EIGHTH_BIT } else { 0 } | (n & SEVEN_BITS));
118                    cont = true;
119                }
120            }
121        }
122    }
123
124    /// Encodes the identifier of a type in BER/CER/DER. An identifier consists
125    /// of a "class", encoding bit, and tag number. If our tag number is
126    /// greater than 30 we to encode the number as stream of a 7 bit integers
127    /// in big endian delimited by the leading bit of each byte.
128    ///
129    /// ```text
130    /// ---------------------------------
131    /// | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
132    /// ---------------------------------
133    /// | class | E |        Tag        |
134    /// ---------------------------------
135    /// ```
136    fn encode_identifier(
137        &mut self,
138        Identifier {
139            tag,
140            is_constructed,
141        }: Identifier,
142    ) -> ByteOrBytes {
143        const FIVE_BITS: u32 = (1 << 5) - 1;
144        let mut tag_byte = tag.class as u8;
145        let tag_number = tag.value;
146
147        // Constructed is a single bit.
148        tag_byte <<= 1;
149        tag_byte |= match tag {
150            Tag::EXTERNAL | Tag::SEQUENCE | Tag::SET => 1,
151            _ if is_constructed => 1,
152            _ => 0,
153        };
154
155        tag_byte <<= 5;
156
157        if tag_number >= FIVE_BITS {
158            let mut buffer = alloc::vec![tag_byte | FIVE_BITS as u8];
159            self.encode_as_base128(tag_number, &mut buffer);
160            ByteOrBytes::Many(buffer)
161        } else {
162            tag_byte |= tag_number as u8;
163            ByteOrBytes::Single(tag_byte)
164        }
165    }
166
167    fn encode_length(&mut self, identifier: Identifier, value: &[u8]) {
168        if identifier.is_primitive() || !self.config.encoding_rules.is_cer() {
169            let len_bytes = self.encode_definite_length(value.len());
170            self.append_byte_or_bytes(len_bytes);
171            self.output.extend_from_slice(value);
172        } else {
173            self.output.push(START_OF_CONTENTS);
174            self.output.extend_from_slice(value);
175            self.output.extend_from_slice(END_OF_CONTENTS);
176        }
177    }
178
179    fn encode_definite_length(&mut self, len: usize) -> ByteOrBytes {
180        if len <= 127 {
181            ByteOrBytes::Single(len as u8)
182        } else {
183            let mut length = len;
184            let mut length_buffer = VecDeque::new();
185
186            while length != 0 {
187                length_buffer.push_front((length & 0xff) as u8);
188                length >>= 8;
189            }
190
191            length_buffer.push_front(length_buffer.len() as u8 | 0x80);
192
193            ByteOrBytes::Many(length_buffer.into())
194        }
195    }
196
197    fn encode_octet_string_(&mut self, tag: Tag, value: &[u8]) -> Result<(), EncodeError> {
198        self.encode_string(tag, Tag::OCTET_STRING, value)
199    }
200
201    /// "STRING" types in ASN.1 BER (OCTET STRING, UTF8 STRING) are either
202    /// primitive encoded, or in certain variants like CER they are constructed
203    /// encoded containing primitive encoded chunks.
204    fn encode_string(
205        &mut self,
206        tag: Tag,
207        nested_tag: Tag,
208        value: &[u8],
209    ) -> Result<(), EncodeError> {
210        let max_string_length = self.config.encoding_rules.max_string_length();
211
212        if value.len() > max_string_length {
213            let ident_bytes = self.encode_identifier(Identifier::from_tag(tag, true));
214            self.append_byte_or_bytes(ident_bytes);
215
216            self.output.push(START_OF_CONTENTS);
217
218            for chunk in value.chunks(max_string_length) {
219                self.encode_primitive(nested_tag, chunk);
220            }
221
222            self.output.extend_from_slice(END_OF_CONTENTS);
223            self.encode_to_set(tag);
224        } else {
225            self.encode_primitive(tag, value);
226        }
227
228        Ok(())
229    }
230
231    fn encode_primitive(&mut self, tag: Tag, value: &[u8]) {
232        self.encode_value(Identifier::from_tag(tag, false), value);
233    }
234
235    fn encode_constructed(&mut self, tag: Tag, value: &[u8]) {
236        self.encode_value(Identifier::from_tag(tag, true), value);
237    }
238
239    /// Encodes a given ASN.1 BER value with the `identifier`.
240    fn encode_value(&mut self, identifier: Identifier, value: &[u8]) {
241        let ident_bytes = self.encode_identifier(identifier);
242        self.append_byte_or_bytes(ident_bytes);
243        self.encode_length(identifier, value);
244        self.encode_to_set(identifier.tag);
245    }
246
247    /// Runs at the end of a complete value encoding to decide whether to sort
248    /// the output by the tag of each value.
249    fn encode_to_set(&mut self, tag: Tag) {
250        if self.is_set_encoding {
251            self.set_buffer
252                .insert(tag, core::mem::take(&mut self.output));
253        }
254    }
255    /// Converts an object identifier into a byte vector in BER format.
256    /// Reusable function by other codecs.
257    pub fn object_identifier_as_bytes(&mut self, oid: &[u32]) -> Result<Vec<u8>, EncodeError> {
258        if oid.len() < 2 {
259            return Err(BerEncodeErrorKind::invalid_object_identifier(oid.to_owned()).into());
260        }
261        let mut bytes = Vec::new();
262
263        let first = oid[0];
264        let second = oid[1];
265
266        if first > MAX_OID_FIRST_OCTET {
267            return Err(BerEncodeErrorKind::invalid_object_identifier(oid.to_owned()).into());
268        }
269        self.encode_as_base128((first * (MAX_OID_SECOND_OCTET + 1)) + second, &mut bytes);
270        for component in oid.iter().skip(2) {
271            self.encode_as_base128(*component, &mut bytes);
272        }
273        Ok(bytes)
274    }
275    #[must_use]
276    /// Canonical byte presentation for CER/DER as defined in X.690 section 11.7.
277    /// Also used for BER on this crate.
278    pub fn datetime_to_canonical_generalized_time_bytes(
279        value: &chrono::DateTime<chrono::FixedOffset>,
280    ) -> Vec<u8> {
281        let mut string;
282        // Convert to UTC so we can always append Z.
283        let value = value.naive_utc();
284        if value.nanosecond() > 0 {
285            string = value.format("%Y%m%d%H%M%S.%f").to_string();
286            // No trailing zeros with fractions
287            while string.ends_with('0') {
288                string.pop();
289            }
290        } else {
291            string = value.format("%Y%m%d%H%M%S").to_string();
292        }
293        string.push('Z');
294        string.into_bytes()
295    }
296
297    #[must_use]
298    /// Canonical byte presentation for CER/DER UTCTime as defined in X.690 section 11.8.
299    /// Also used for BER on this crate.
300    pub fn datetime_to_canonical_utc_time_bytes(value: &chrono::DateTime<chrono::Utc>) -> Vec<u8> {
301        value
302            .naive_utc()
303            .format("%y%m%d%H%M%SZ")
304            .to_string()
305            .into_bytes()
306    }
307}
308
309impl crate::Encoder for Encoder {
310    type Ok = ();
311    type Error = EncodeError;
312
313    fn codec(&self) -> Codec {
314        Self::codec(self)
315    }
316    fn encode_any(&mut self, _: Tag, value: &types::Any) -> Result<Self::Ok, Self::Error> {
317        if self.is_set_encoding {
318            return Err(BerEncodeErrorKind::AnyInSet.into());
319        }
320
321        self.output.extend_from_slice(&value.contents);
322
323        Ok(())
324    }
325
326    fn encode_bit_string(
327        &mut self,
328        tag: Tag,
329        _constraints: Constraints,
330        value: &types::BitStr,
331    ) -> Result<Self::Ok, Self::Error> {
332        if value.is_empty() {
333            self.encode_primitive(tag, &[]);
334            Ok(())
335        } else {
336            let bit_length = value.len();
337            let vec = value.to_bitvec();
338            let bytes = vec.as_raw_slice();
339            let unused_bits: u8 = ((bytes.len() * 8) - bit_length).try_into().map_err(|err| {
340                EncodeError::from_kind(
341                    EncodeErrorKind::FailedBitStringUnusedBitsToU8 { err },
342                    self.codec(),
343                )
344            })?;
345            let mut encoded = Vec::with_capacity(bytes.len() + 1);
346            encoded.push(unused_bits);
347            encoded.extend(bytes);
348
349            self.encode_string(tag, Tag::BIT_STRING, &encoded)
350        }
351    }
352
353    fn encode_bool(&mut self, tag: Tag, value: bool) -> Result<Self::Ok, Self::Error> {
354        self.encode_primitive(tag, &[if value { 0xff } else { 0x00 }]);
355        Ok(())
356    }
357
358    fn encode_choice<E: Encode>(
359        &mut self,
360        _: Constraints,
361        _t: Tag,
362        encode_fn: impl FnOnce(&mut Self) -> Result<Tag, Self::Error>,
363    ) -> Result<Self::Ok, Self::Error> {
364        (encode_fn)(self).map(drop)
365    }
366
367    fn encode_enumerated<E: Enumerated>(
368        &mut self,
369        tag: Tag,
370        value: &E,
371    ) -> Result<Self::Ok, Self::Error> {
372        let value = E::discriminant(value);
373        self.encode_integer(tag, <_>::default(), &value.into())
374    }
375
376    fn encode_integer(
377        &mut self,
378        tag: Tag,
379        _constraints: Constraints,
380        value: &num_bigint::BigInt,
381    ) -> Result<Self::Ok, Self::Error> {
382        self.encode_primitive(tag, &value.to_signed_bytes_be());
383        Ok(())
384    }
385
386    fn encode_null(&mut self, tag: Tag) -> Result<Self::Ok, Self::Error> {
387        self.encode_primitive(tag, &[]);
388        Ok(())
389    }
390
391    fn encode_object_identifier(&mut self, tag: Tag, oid: &[u32]) -> Result<Self::Ok, Self::Error> {
392        let bytes = self.object_identifier_as_bytes(oid)?;
393        self.encode_primitive(tag, &bytes);
394        Ok(())
395    }
396
397    fn encode_octet_string(
398        &mut self,
399        tag: Tag,
400        _constraints: Constraints,
401        value: &[u8],
402    ) -> Result<Self::Ok, Self::Error> {
403        self.encode_octet_string_(tag, value)
404    }
405
406    fn encode_visible_string(
407        &mut self,
408        tag: Tag,
409        _constraints: Constraints,
410        value: &types::VisibleString,
411    ) -> Result<Self::Ok, Self::Error> {
412        self.encode_octet_string_(tag, value.as_iso646_bytes())
413    }
414
415    fn encode_ia5_string(
416        &mut self,
417        tag: Tag,
418        _constraints: Constraints,
419        value: &types::Ia5String,
420    ) -> Result<Self::Ok, Self::Error> {
421        self.encode_octet_string_(tag, value.as_iso646_bytes())
422    }
423
424    fn encode_general_string(
425        &mut self,
426        tag: Tag,
427        _constraints: Constraints,
428        value: &types::GeneralString,
429    ) -> Result<Self::Ok, Self::Error> {
430        self.encode_octet_string_(tag, value)
431    }
432
433    fn encode_printable_string(
434        &mut self,
435        tag: Tag,
436        _constraints: Constraints,
437        value: &types::PrintableString,
438    ) -> Result<Self::Ok, Self::Error> {
439        self.encode_octet_string_(tag, value.as_bytes())
440    }
441
442    fn encode_numeric_string(
443        &mut self,
444        tag: Tag,
445        _constraints: Constraints,
446        value: &types::NumericString,
447    ) -> Result<Self::Ok, Self::Error> {
448        self.encode_octet_string_(tag, value.as_bytes())
449    }
450
451    fn encode_teletex_string(
452        &mut self,
453        tag: Tag,
454        _: Constraints,
455        value: &types::TeletexString,
456    ) -> Result<Self::Ok, Self::Error> {
457        self.encode_octet_string_(tag, value)
458    }
459
460    fn encode_bmp_string(
461        &mut self,
462        tag: Tag,
463        _constraints: Constraints,
464        value: &types::BmpString,
465    ) -> Result<Self::Ok, Self::Error> {
466        self.encode_octet_string_(tag, &value.to_bytes())
467    }
468
469    fn encode_utf8_string(
470        &mut self,
471        tag: Tag,
472        _: Constraints,
473        value: &str,
474    ) -> Result<Self::Ok, Self::Error> {
475        self.encode_octet_string_(tag, value.as_bytes())
476    }
477
478    fn encode_utc_time(
479        &mut self,
480        tag: Tag,
481        value: &types::UtcTime,
482    ) -> Result<Self::Ok, Self::Error> {
483        self.encode_primitive(
484            tag,
485            Self::datetime_to_canonical_utc_time_bytes(value).as_slice(),
486        );
487
488        Ok(())
489    }
490
491    fn encode_generalized_time(
492        &mut self,
493        tag: Tag,
494        value: &types::GeneralizedTime,
495    ) -> Result<Self::Ok, Self::Error> {
496        self.encode_primitive(
497            tag,
498            Self::datetime_to_canonical_generalized_time_bytes(value).as_slice(),
499        );
500
501        Ok(())
502    }
503
504    fn encode_some<E: Encode>(&mut self, value: &E) -> Result<Self::Ok, Self::Error> {
505        value.encode(self)
506    }
507
508    fn encode_some_with_tag<E: Encode>(
509        &mut self,
510        tag: Tag,
511        value: &E,
512    ) -> Result<Self::Ok, Self::Error> {
513        value.encode_with_tag(self, tag)
514    }
515
516    fn encode_some_with_tag_and_constraints<E: Encode>(
517        &mut self,
518        tag: Tag,
519        constraints: Constraints,
520        value: &E,
521    ) -> Result<Self::Ok, Self::Error> {
522        value.encode_with_tag_and_constraints(self, tag, constraints)
523    }
524
525    fn encode_none<E: Encode>(&mut self) -> Result<Self::Ok, Self::Error> {
526        self.encode_none_with_tag(E::TAG)
527    }
528
529    fn encode_none_with_tag(&mut self, _: Tag) -> Result<Self::Ok, Self::Error> {
530        Ok(())
531    }
532
533    fn encode_sequence_of<E: Encode>(
534        &mut self,
535        tag: Tag,
536        values: &[E],
537        _constraints: Constraints,
538    ) -> Result<Self::Ok, Self::Error> {
539        let mut sequence_encoder = Self::new(self.config);
540
541        for value in values {
542            value.encode(&mut sequence_encoder)?;
543        }
544
545        self.encode_constructed(tag, &sequence_encoder.output);
546
547        Ok(())
548    }
549
550    fn encode_set_of<E: Encode>(
551        &mut self,
552        tag: Tag,
553        values: &types::SetOf<E>,
554        _constraints: Constraints,
555    ) -> Result<Self::Ok, Self::Error> {
556        let mut encoded_values = values
557            .iter()
558            .map(|val| {
559                let mut sequence_encoder = Self::new(self.config);
560                val.encode(&mut sequence_encoder)
561                    .map(|_| sequence_encoder.output)
562            })
563            .collect::<Result<Vec<Vec<u8>>, _>>()?;
564
565        // The encodings of the component values of a set-of value shall appear in ascending order,
566        // the encodings being compared as octet strings [...]
567        encoded_values.sort_by(octet_string_ascending);
568        let sorted_elements: Vec<u8> = encoded_values.into_iter().flatten().collect();
569
570        self.encode_constructed(tag, &sorted_elements);
571
572        Ok(())
573    }
574
575    fn encode_explicit_prefix<V: Encode>(
576        &mut self,
577        tag: Tag,
578        value: &V,
579    ) -> Result<Self::Ok, Self::Error> {
580        let mut encoder = Self::new(self.config);
581        value.encode(&mut encoder)?;
582        self.encode_constructed(tag, &encoder.output);
583        Ok(())
584    }
585
586    fn encode_sequence<C, F>(&mut self, tag: Tag, encoder_scope: F) -> Result<Self::Ok, Self::Error>
587    where
588        C: crate::types::Constructed,
589        F: FnOnce(&mut Self) -> Result<Self::Ok, Self::Error>,
590    {
591        let mut encoder = Self::new(self.config);
592
593        (encoder_scope)(&mut encoder)?;
594
595        self.encode_constructed(tag, &encoder.output);
596
597        Ok(())
598    }
599
600    fn encode_set<C, F>(&mut self, tag: Tag, encoder_scope: F) -> Result<Self::Ok, Self::Error>
601    where
602        C: crate::types::Constructed,
603        F: FnOnce(&mut Self) -> Result<Self::Ok, Self::Error>,
604    {
605        let mut encoder = Self::new_set(self.config);
606
607        (encoder_scope)(&mut encoder)?;
608
609        self.encode_constructed(tag, &encoder.output());
610
611        Ok(())
612    }
613
614    fn encode_extension_addition<E: Encode>(
615        &mut self,
616        tag: Tag,
617        constraints: Constraints,
618        value: E,
619    ) -> Result<Self::Ok, Self::Error> {
620        value.encode_with_tag_and_constraints(self, tag, constraints)
621    }
622
623    /// Encode a extension addition group value.
624    fn encode_extension_addition_group<E>(
625        &mut self,
626        value: Option<&E>,
627    ) -> Result<Self::Ok, Self::Error>
628    where
629        E: Encode + crate::types::Constructed,
630    {
631        value.encode(self)
632    }
633}
634
635#[cfg(test)]
636mod tests {
637    use super::*;
638    use alloc::borrow::ToOwned;
639    use alloc::vec;
640
641    #[derive(Clone, Copy, Hash, Debug, PartialEq)]
642    struct C0;
643    impl crate::AsnType for C0 {
644        const TAG: Tag = Tag::new(crate::types::Class::Context, 0);
645    }
646
647    #[test]
648    fn bit_string() {
649        let bitstring =
650            types::BitString::from_vec([0x0A, 0x3B, 0x5F, 0x29, 0x1C, 0xD0][..].to_owned());
651
652        let primitive_encoded = &[0x03, 0x07, 0x00, 0x0A, 0x3B, 0x5F, 0x29, 0x1C, 0xD0][..];
653
654        assert_eq!(primitive_encoded, super::super::encode(&bitstring).unwrap());
655    }
656
657    #[test]
658    fn identifier() {
659        fn ident_to_bytes(ident: Identifier) -> Vec<u8> {
660            let mut enc = Encoder::new(EncoderOptions::ber());
661            let bytes = enc.encode_identifier(ident);
662            enc.append_byte_or_bytes(bytes);
663            enc.output
664        }
665
666        assert_eq!(
667            &[0xFF, 0x7F,][..],
668            ident_to_bytes(Identifier::from_tag(
669                Tag::new(crate::types::Class::Private, 127),
670                true,
671            ))
672        );
673    }
674
675    #[test]
676    fn encoding_oid() {
677        fn oid_to_bytes(oid: &[u32]) -> Vec<u8> {
678            use crate::Encoder;
679            let mut enc = self::Encoder::new(EncoderOptions::ber());
680            enc.encode_object_identifier(Tag::OBJECT_IDENTIFIER, oid)
681                .unwrap();
682            enc.output
683        }
684
685        // example from https://stackoverflow.com/questions/5929050/how-does-asn-1-encode-an-object-identifier
686        assert_eq!(
687            &vec![0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01],
688            &oid_to_bytes(&[1, 3, 6, 1, 5, 5, 7, 48, 1])
689        );
690
691        // example from https://docs.microsoft.com/en-us/windows/win32/seccertenroll/about-object-identifier
692        assert_eq!(
693            &vec![0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x14],
694            &oid_to_bytes(&[1, 3, 6, 1, 4, 1, 311, 21, 20])
695        );
696
697        // commonName (X.520 DN component)
698        assert_eq!(
699            &vec![0x06, 0x03, 0x55, 0x04, 0x03],
700            &oid_to_bytes(&[2, 5, 4, 3])
701        );
702
703        // example oid
704        assert_eq!(
705            &vec![0x06, 0x03, 0x88, 0x37, 0x01],
706            &oid_to_bytes(&[2, 999, 1])
707        );
708    }
709
710    #[test]
711    fn base128_test() {
712        fn encode(n: u32) -> Vec<u8> {
713            let enc = self::Encoder::new(EncoderOptions::ber());
714            let mut buffer: Vec<u8> = vec![];
715            enc.encode_as_base128(n, &mut buffer);
716            buffer
717        }
718
719        assert_eq!(&vec![0x0], &encode(0x0));
720        assert_eq!(&vec![0x7F], &encode(0x7F));
721        assert_eq!(&vec![0x81, 0x00], &encode(0x80));
722        assert_eq!(&vec![0xC0, 0x00], &encode(0x2000));
723        assert_eq!(&vec![0xFF, 0x7F], &encode(0x3FFF));
724        assert_eq!(&vec![0x81, 0x80, 0x00], &encode(0x4000));
725        assert_eq!(&vec![0xFF, 0xFF, 0x7F], &encode(0x001FFFFF));
726        assert_eq!(&vec![0x81, 0x80, 0x80, 0x00], &encode(0x00200000));
727        assert_eq!(&vec![0xC0, 0x80, 0x80, 0x00], &encode(0x08000000));
728        assert_eq!(&vec![0xFF, 0xFF, 0xFF, 0x7F], &encode(0x0FFFFFFF));
729    }
730
731    #[test]
732    fn any() {
733        let bitstring =
734            types::BitString::from_vec([0x0A, 0x3B, 0x5F, 0x29, 0x1C, 0xD0][..].to_owned());
735
736        let primitive_encoded = &[0x03, 0x07, 0x00, 0x0A, 0x3B, 0x5F, 0x29, 0x1C, 0xD0][..];
737        let any = types::Any {
738            contents: primitive_encoded.into(),
739        };
740
741        assert_eq!(primitive_encoded, super::super::encode(&bitstring).unwrap());
742        assert_eq!(
743            super::super::encode(&bitstring).unwrap(),
744            super::super::encode(&any).unwrap()
745        );
746    }
747
748    #[test]
749    fn set() {
750        use crate::{
751            types::{AsnType, Implicit},
752            Encoder as _,
753        };
754
755        struct C0;
756        struct C1;
757        struct C2;
758
759        impl AsnType for C0 {
760            const TAG: Tag = Tag::new(crate::types::Class::Context, 0);
761        }
762
763        impl AsnType for C1 {
764            const TAG: Tag = Tag::new(crate::types::Class::Context, 1);
765        }
766
767        impl AsnType for C2 {
768            const TAG: Tag = Tag::new(crate::types::Class::Context, 2);
769        }
770
771        type Field1 = Implicit<C0, u32>;
772        type Field2 = Implicit<C1, u32>;
773        type Field3 = Implicit<C2, u32>;
774
775        let field1: Field1 = 1.into();
776        let field2: Field2 = 2.into();
777        let field3: Field3 = 3.into();
778
779        struct Set;
780
781        impl crate::types::Constructed for Set {
782            const FIELDS: crate::types::fields::Fields =
783                crate::types::fields::Fields::from_static(&[
784                    crate::types::fields::Field::new_required(C0::TAG, C0::TAG_TREE, "field1"),
785                    crate::types::fields::Field::new_required(C1::TAG, C1::TAG_TREE, "field2"),
786                    crate::types::fields::Field::new_required(C2::TAG, C2::TAG_TREE, "field3"),
787                ]);
788        }
789
790        let output = {
791            let mut encoder = Encoder::new_set(EncoderOptions::ber());
792            encoder
793                .encode_set::<Set, _>(Tag::SET, |encoder| {
794                    field3.encode(encoder)?;
795                    field2.encode(encoder)?;
796                    field1.encode(encoder)?;
797                    Ok(())
798                })
799                .unwrap();
800
801            encoder.output()
802        };
803
804        assert_eq!(
805            vec![0x31, 0x9, 0x80, 0x1, 0x1, 0x81, 0x1, 0x2, 0x82, 0x1, 0x3],
806            output,
807        );
808    }
809}