Skip to main content

rasn/ber/
enc.rs

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