1pub mod de;
4pub mod enc;
5mod identifier;
6mod rules;
7
8pub use identifier::Identifier;
9pub(crate) use rules::EncodingRules;
10
11pub fn decode<T: crate::Decode>(input: &[u8]) -> Result<T, crate::error::DecodeError> {
15 T::decode(&mut de::Decoder::new(input, de::DecoderOptions::ber()))
16}
17
18pub fn decode_with_remainder<T: crate::Decode>(
23 input: &[u8],
24) -> Result<(T, &[u8]), crate::error::DecodeError> {
25 let decoder = &mut de::Decoder::new(input, de::DecoderOptions::ber());
26 let decoded_instance = T::decode(decoder)?;
27 Ok((decoded_instance, decoder.remaining()))
28}
29
30pub fn encode<T: crate::Encode>(
34 value: &T,
35) -> Result<alloc::vec::Vec<u8>, crate::error::EncodeError> {
36 let mut enc = enc::Encoder::new(enc::EncoderOptions::ber());
37
38 value.encode(&mut enc)?;
39
40 Ok(enc.output())
41}
42
43pub fn encode_scope(
47 encode_fn: impl FnOnce(&mut crate::ber::enc::Encoder) -> Result<(), crate::error::EncodeError>,
48) -> Result<alloc::vec::Vec<u8>, crate::error::EncodeError> {
49 let mut enc = crate::ber::enc::Encoder::new(crate::ber::enc::EncoderOptions::ber());
50
51 (encode_fn)(&mut enc)?;
52
53 Ok(enc.output())
54}
55
56#[cfg(test)]
57mod tests {
58 use crate::error::DecodeErrorKind;
59 use alloc::borrow::{Cow, ToOwned};
60 use alloc::vec;
61 use alloc::vec::Vec;
62 use bitvec::order::Msb0;
63 use chrono::{DateTime, FixedOffset, NaiveDate, Utc};
64
65 use crate::{
66 ber::{decode, encode},
67 types::*,
68 };
69
70 #[derive(Clone, Copy, Hash, Debug, PartialEq)]
71 struct C0;
72 impl AsnType for C0 {
73 const TAG: Tag = Tag::new(Class::Context, 0);
74 }
75
76 #[test]
77 fn oversized_integer() {
78 const DATA: &[u8] = &[0x02, 0x06, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66];
79
80 assert!(matches!(
81 &*decode::<u32>(DATA).unwrap_err().kind,
82 DecodeErrorKind::IntegerOverflow { max_width: 32 }
83 ));
84
85 assert!(matches!(
86 &*decode::<i32>(DATA).unwrap_err().kind,
87 DecodeErrorKind::IntegerOverflow { max_width: 32 }
88 ));
89 }
90
91 #[test]
92 fn leading_integer_bytes() {
93 const DATA: &[u8] = &[0x02, 0x06, 0x00, 0x00, 0x33, 0x44, 0x55, 0x66];
94 assert_eq!(decode::<u32>(DATA).unwrap(), 0x3344_5566_u32);
95
96 const SIGNED_DATA: &[u8] = &[0x02, 0x06, 0xFF, 0xFF, 0x83, 0x44, 0x55, 0x66];
97 assert_eq!(decode::<i32>(SIGNED_DATA).unwrap(), -2_092_673_690);
98 }
99
100 #[test]
101 fn bit_string() {
102 const DATA: &[u8] = &[0, 0xD0];
103 let small = BitString::from_vec(DATA.to_owned());
104 let bits = BitString::from_vec([0x0A, 0x3B, 0x5F, 0x29, 0x1C, 0xD0][..].to_owned());
105 let padding_test = BitString::from_element(0x42);
106 let padding_expected: &[u8] = &[0x03, 0x02, 0x00, 0x42];
107 let trailing_test = bitvec::bitvec![u8, Msb0; 1, 0, 0, 0, 0, 1, 1, 0];
108 let trailing_expected: &[u8] = &[0x03, 0x02, 0x00, 0x86];
109
110 assert_eq!(
111 small,
112 decode::<BitString>(&encode(&small).unwrap()).unwrap()
113 );
114 assert_eq!(bits, decode::<BitString>(&encode(&bits).unwrap()).unwrap());
115 assert_eq!(padding_expected, encode(&padding_test).unwrap());
116 assert_eq!(trailing_expected, encode(&trailing_test).unwrap());
117 }
118
119 #[test]
120 fn implicit_prefix() {
121 type MyInteger = Implicit<C0, u64>;
122
123 let new_int = MyInteger::new(5);
124
125 assert_eq!(new_int, decode(&encode(&new_int).unwrap()).unwrap());
126 }
127
128 #[test]
129 fn explicit_prefix() {
130 type MyInteger = Explicit<C0, u64>;
131
132 let new_int = MyInteger::new(5);
133 let data = &[0xA0, 3, 0x2, 0x1, 5][..];
134
135 assert_eq!(data, &encode(&new_int).unwrap());
136 assert_eq!(new_int, decode(&encode(&new_int).unwrap()).unwrap());
137 }
138
139 #[test]
140 fn implicit_tagged_constructed() {
141 type ImpVec = Implicit<C0, Vec<i32>>;
142
143 let value = ImpVec::new(vec![1, 2]);
144 let data = &[0xA0, 6, 2, 1, 1, 2, 1, 2][..];
145
146 assert_eq!(data, &*crate::ber::encode(&value).unwrap());
147 assert_eq!(value, crate::ber::decode::<ImpVec>(data).unwrap());
148 }
149
150 #[test]
151 fn explicit_empty_tag() {
152 use crate as rasn;
153 use rasn::prelude::*;
154 #[derive(Debug, AsnType, Encode, Decode, PartialEq)]
155 struct EmptyTag {
156 #[rasn(tag(explicit(0)))]
157 a: Option<()>,
158 }
159
160 let value = EmptyTag { a: None };
161 let data = &[0x30, 0][..];
163
164 assert_eq!(data, &*crate::ber::encode(&value).unwrap());
165 assert_eq!(value, crate::ber::decode::<EmptyTag>(data).unwrap());
166 }
167
168 #[test]
169 #[allow(clippy::items_after_statements)]
170 fn set() {
171 #[derive(Debug, PartialEq)]
172 struct Set {
173 age: u32,
174 name: Utf8String,
175 }
176
177 impl AsnType for Set {
178 const TAG: Tag = Tag::SET;
179 }
180
181 impl crate::types::Constructed<2, 0> for Set {
182 const FIELDS: crate::types::fields::Fields<2> =
183 crate::types::fields::Fields::from_static([
184 crate::types::fields::Field::new_required(0, u32::TAG, u32::TAG_TREE, "age"),
185 crate::types::fields::Field::new_required(
186 1,
187 Utf8String::TAG,
188 Utf8String::TAG_TREE,
189 "name",
190 ),
191 ]);
192 }
193
194 let example = Set {
195 age: 1,
196 name: "Jane".into(),
197 };
198 let age_then_name = [0x31, 0x9, 0x2, 0x1, 0x1, 0xC, 0x4, 0x4a, 0x61, 0x6e, 0x65];
199 let name_then_age = [0x31, 0x9, 0xC, 0x4, 0x4a, 0x61, 0x6e, 0x65, 0x2, 0x1, 0x1];
200
201 assert_eq!(&age_then_name[..], crate::ber::encode(&example).unwrap());
202
203 assert_eq!(
204 crate::ber::decode::<Set>(&age_then_name).unwrap(),
205 crate::ber::decode::<Set>(&name_then_age).unwrap()
206 );
207
208 impl crate::Decode for Set {
209 fn decode_with_tag_and_constraints<D: crate::Decoder>(
210 decoder: &mut D,
211 tag: Tag,
212 _: Constraints,
213 ) -> Result<Self, D::Error> {
214 use crate::de::Error;
215
216 #[derive(crate::AsnType, crate::Decode)]
217 #[rasn(crate_root = "crate")]
218 #[rasn(choice)]
219 pub enum Fields {
220 Age(u32),
221 Name(Utf8String),
222 }
223 let codec = decoder.codec();
224 decoder.decode_set::<2, 0, Fields, _, _, _>(
225 tag,
226 |decoder, indice, tag| match (indice, tag) {
227 (0, u32::TAG) => <_>::decode(decoder).map(Fields::Age),
228 (1, Utf8String::TAG) => <_>::decode(decoder).map(Fields::Name),
229 (_, _) => Err(D::Error::custom("unknown field", codec)),
230 },
231 |fields| {
232 let mut age = None;
233 let mut name = None;
234
235 for field in fields {
236 match field {
237 Fields::Age(value) => age = value.into(),
238 Fields::Name(value) => name = value.into(),
239 }
240 }
241
242 Ok(Self {
243 age: age.ok_or_else(|| D::Error::missing_field("age", codec))?,
244 name: name.ok_or_else(|| D::Error::missing_field("name", codec))?,
245 })
246 },
247 )
248 }
249 }
250
251 impl crate::Encode for Set {
252 fn encode_with_tag_and_constraints<'b, EN: crate::Encoder<'b>>(
253 &self,
254 encoder: &mut EN,
255 tag: crate::types::Tag,
256 _: Constraints,
257 _: crate::types::Identifier,
258 ) -> Result<(), EN::Error> {
259 encoder.encode_set::<2, 0, Self, _>(
260 tag,
261 |encoder| {
262 self.age.encode(encoder)?;
263 self.name.encode(encoder)?;
264 Ok(())
265 },
266 crate::types::Identifier::EMPTY,
267 )?;
268
269 Ok(())
270 }
271 }
272 }
273 #[test]
274 fn test_generalized_time() {
275 let offset = chrono::FixedOffset::east_opt(0).unwrap();
277 let dt = NaiveDate::from_ymd_opt(2080, 10, 9)
278 .unwrap()
279 .and_hms_micro_opt(13, 0, 5, 342_000)
280 .unwrap()
281 .and_local_timezone(offset);
282 round_trip!(
283 ber,
284 GeneralizedTime,
285 GeneralizedTime::from(dt.unwrap(),),
286 &[
287 0x18, 0x13, 0x32, 0x30, 0x38, 0x30, 0x31, 0x30, 0x30, 0x39, 0x31, 0x33, 0x30, 0x30,
288 0x30, 0x35, 0x2e, 0x33, 0x34, 0x32, 0x5a
289 ]
290 );
291
292 let data = [
294 24, 19, 43, 53, 49, 54, 49, 53, 32, 32, 48, 53, 50, 52, 48, 57, 52, 48, 50, 48, 90,
295 ];
296 assert!(crate::der::decode::<crate::types::Open>(&data).is_err());
297 assert!(crate::ber::decode::<crate::types::Open>(&data).is_err());
298
299 round_trip!(
301 ber,
302 GeneralizedTime,
303 GeneralizedTime::from(
304 NaiveDate::from_ymd_opt(2018, 1, 22)
305 .unwrap()
306 .and_hms_opt(13, 29, 0)
307 .unwrap()
308 .and_utc()
309 ),
310 &[
311 0x18, 0x0f, 0x32, 0x30, 0x31, 0x38, 0x30, 0x31, 0x32, 0x32, 0x31, 0x33, 0x32, 0x39,
312 0x30, 0x30, 0x5a
313 ]
314 );
315 round_trip!(
317 ber,
318 GeneralizedTime,
319 GeneralizedTime::from(
320 NaiveDate::from_ymd_opt(2018, 1, 22)
321 .unwrap()
322 .and_hms_opt(13, 0, 0)
323 .unwrap()
324 .and_utc()
325 ),
326 &[
327 0x18, 0x0f, 0x32, 0x30, 0x31, 0x38, 0x30, 0x31, 0x32, 0x32, 0x31, 0x33, 0x30, 0x30,
328 0x30, 0x30, 0x5a
329 ]
330 );
331
332 let offset = FixedOffset::east_opt(-3600 * 5).unwrap();
334 let dt1: DateTime<FixedOffset> = GeneralizedTime::from(DateTime::<Utc>::from(
335 NaiveDate::from_ymd_opt(2023, 1, 22)
336 .unwrap()
337 .and_hms_opt(13, 0, 0)
338 .unwrap()
339 .and_local_timezone(offset)
340 .unwrap(),
341 ));
342 round_trip!(
343 ber,
344 GeneralizedTime,
345 dt1,
346 &[
347 0x18, 0x0f, 0x32, 0x30, 0x32, 0x33, 0x30, 0x31, 0x32, 0x32, 0x31, 0x38, 0x30, 0x30,
348 0x30, 0x30, 0x5a
349 ]
350 );
351 let data = [
353 24, 19, 50, 48, 50, 51, 48, 49, 50, 50, 49, 51, 48, 48, 48, 48, 45, 48, 53, 48, 48,
354 ];
355 let result = crate::ber::decode::<crate::types::GeneralizedTime>(&data);
356 assert!(result.is_ok());
357 assert_eq!(dt1, result.unwrap());
358 let data = [
360 24, 14, 50, 48, 50, 51, 48, 49, 50, 50, 49, 51, 48, 48, 48, 48,
361 ];
362 let result = crate::ber::decode::<crate::types::GeneralizedTime>(&data);
363 if result.is_err() {
365 println!("{result:?}");
366 }
367 assert!(result.is_ok());
368 let data = [
369 24, 22, 50, 48, 50, 51, 48, 49, 50, 50, 49, 51, 48, 48, 48, 48, 45, 45, 0xE2, 0x82,
370 0xAC, 45, 45, 45,
371 ];
372 let result = crate::ber::decode::<crate::types::GeneralizedTime>(&data);
373 assert!(result.is_err());
374 }
375 #[test]
376 fn test_utc_time() {
377 round_trip!(
379 ber,
380 UtcTime,
381 UtcTime::from(
382 NaiveDate::from_ymd_opt(2018, 1, 22)
383 .unwrap()
384 .and_hms_opt(13, 29, 0)
385 .unwrap()
386 .and_utc()
387 ),
388 &[
389 0x17, 0x0d, 0x31, 0x38, 0x30, 0x31, 0x32, 0x32, 0x31, 0x33, 0x32, 0x39, 0x30, 0x30,
390 0x5a
391 ]
392 );
393 let offset = FixedOffset::east_opt(-3600 * 5).unwrap();
395 let dt1 = DateTime::<FixedOffset>::from_naive_utc_and_offset(
396 NaiveDate::from_ymd_opt(2023, 1, 22)
397 .unwrap()
398 .and_hms_opt(18, 0, 0)
399 .unwrap(),
400 offset,
401 );
402 round_trip!(
403 ber,
404 UtcTime,
405 dt1.into(),
406 &[
407 0x17, 0x0d, 0x32, 0x33, 0x30, 0x31, 0x32, 0x32, 0x31, 0x38, 0x30, 0x30, 0x30, 0x30,
408 0x5a
409 ]
410 );
411 let data = [
413 23, 17, 50, 51, 48, 49, 50, 50, 49, 51, 48, 48, 48, 48, 45, 48, 53, 48, 48,
414 ];
415 let result = crate::ber::decode::<crate::types::UtcTime>(&data);
416 assert!(result.is_ok());
417 assert_eq!(dt1, result.unwrap());
418 }
419
420 #[test]
421 fn test_date() {
422 round_trip!(
423 ber,
424 Date,
425 NaiveDate::from_ymd_opt(2012, 12, 21).unwrap(),
426 &[
427 0x1f, 0x1f, 0x08, 0x32, 0x30, 0x31, 0x32, 0x31, 0x32, 0x32, 0x31
428 ]
429 );
430 }
431 #[test]
432 fn test_extended_sequence() {
433 use crate as rasn;
434 use rasn::prelude::*;
435 #[derive(AsnType, Debug, Clone, Encode, Decode, PartialEq)]
436 #[rasn(automatic_tags)]
437 #[non_exhaustive]
438 pub struct ExtendedInteger {
439 #[rasn(extension_addition)]
440 pub extension: Option<u64>,
441 }
442 round_trip!(
443 ber,
444 ExtendedInteger,
445 ExtendedInteger {
446 extension: Some(42)
447 },
448 &[0x30, 0x03, 0x80, 0x01, 0x2A]
449 );
450 #[derive(AsnType, Debug, Clone, Encode, Decode, PartialEq)]
451 #[non_exhaustive]
452 pub struct ExtendedExplicitInteger {
453 #[rasn(extension_addition)]
454 #[rasn(tag(explicit(5)))]
455 pub extension: u64,
456 }
457
458 round_trip!(
459 ber,
460 ExtendedExplicitInteger,
461 ExtendedExplicitInteger { extension: 42 },
462 &[0x30, 0x05, 0xA5, 0x03, 0x02, 0x01, 0x2A]
463 );
464 }
465 #[test]
466 fn test_optional_any() {
467 use crate as rasn;
469 use rasn::prelude::*;
470
471 #[derive(Debug, AsnType, Decode, Encode, PartialEq, Eq)]
472 struct IncomingRequest {
473 #[rasn(tag(Context, 0))]
474 handshake: Option<Any>,
475 #[rasn(tag(Context, 1))]
476 user_data: Option<Any>,
477 }
478 let incoming: IncomingRequest = rasn::Codec::Ber
479 .decode_from_binary(&[0x30, 0x06, 0xA1, 0x04, 0x01, 0x02, 0x03, 0x04])
480 .unwrap();
481 let expected = IncomingRequest {
482 handshake: None,
483 user_data: Some(Any::new(vec![0x01, 0x02, 0x03, 0x04])),
484 };
485 assert_eq!(incoming, expected)
486 }
487
488 #[test]
489 fn test_optional_variants() {
490 use crate as rasn;
491 use rasn::prelude::*;
492
493 #[derive(AsnType, Debug, Clone, Encode, Decode, PartialEq)]
494 #[rasn(automatic_tags)]
495 #[rasn(choice)]
496 pub enum TestChoice {
497 Integer(i32),
498 Boolean(bool),
499 }
500
501 #[derive(AsnType, Debug, Clone, Encode, Decode, PartialEq)]
502 #[rasn(automatic_tags)]
503 pub struct TestSequence {
504 a: Option<u32>,
505 b: Option<TestChoice>,
506 c: Option<Any>,
507 d: bool, }
509
510 let value1 = TestSequence {
512 a: None,
513 b: None,
514 c: None,
515 d: true,
516 };
517 let expected1 = &[0x30, 0x03, 0x83, 0x01, 0xFF];
520 assert_eq!(encode(&value1).unwrap(), expected1);
521 assert_eq!(decode::<TestSequence>(expected1).unwrap(), value1);
522
523 let value2 = TestSequence {
525 a: Some(10),
526 b: None,
527 c: None,
528 d: true,
529 };
530 let expected2 = &[0x30, 0x06, 0x80, 0x01, 0x0A, 0x83, 0x01, 0xFF];
534 assert_eq!(encode(&value2).unwrap(), expected2);
535 assert_eq!(decode::<TestSequence>(expected2).unwrap(), value2);
536
537 let value3 = TestSequence {
539 a: None,
540 b: Some(TestChoice::Integer(20)),
541 c: None,
542 d: true,
543 };
544 let expected3 = &[0x30, 0x08, 0xA1, 0x03, 0x80, 0x01, 0x14, 0x83, 0x01, 0xFF];
549 assert_eq!(encode(&value3).unwrap(), expected3);
550 assert_eq!(decode::<TestSequence>(expected3).unwrap(), value3);
551
552 let any_payload = &[0x05, 0x00]; let value4 = TestSequence {
555 a: None,
556 b: None,
557 c: Some(Any::new(any_payload.to_vec())),
558 d: true,
559 };
560 let expected4 = &[0x30, 0x07, 0x82, 0x02, 0x05, 0x00, 0x83, 0x01, 0xFF];
564 assert_eq!(encode(&value4).unwrap(), expected4);
565 assert_eq!(decode::<TestSequence>(expected4).unwrap(), value4);
566
567 let value5 = TestSequence {
569 a: Some(255),
570 b: Some(TestChoice::Boolean(false)),
571 c: Some(Any::new(any_payload.to_vec())),
572 d: false,
573 };
574 let expected5 = &[
581 0x30, 0x10, 0x80, 0x02, 0x00, 0xFF, 0xA1, 0x03, 0x81, 0x01, 0x00, 0x82, 0x02, 0x05,
582 0x00, 0x83, 0x01, 0x00,
583 ];
584 assert_eq!(encode(&value5).unwrap(), expected5);
585 assert_eq!(decode::<TestSequence>(expected5).unwrap(), value5);
586
587 let value6 = TestSequence {
589 a: Some(1),
590 b: None,
591 c: Some(Any::new(any_payload.to_vec())),
592 d: true,
593 };
594 let expected6 = &[
599 0x30, 0x0A, 0x80, 0x01, 0x01, 0x82, 0x02, 0x05, 0x00, 0x83, 0x01, 0xFF,
600 ];
601 assert_eq!(encode(&value6).unwrap(), expected6);
602 assert_eq!(decode::<TestSequence>(expected6).unwrap(), value6);
603
604 #[derive(AsnType, Debug, Clone, Encode, Decode, PartialEq)]
606 #[rasn(automatic_tags)]
607 pub struct AnotherTestSequence {
608 a: Option<TestChoice>,
609 b: Option<Any>,
610 }
611 let value1 = AnotherTestSequence { a: None, b: None };
612 let expected1 = &[0x30, 0x00];
614 assert_eq!(encode(&value1).unwrap(), expected1);
615 assert_eq!(decode::<AnotherTestSequence>(expected1).unwrap(), value1);
616 let value2 = AnotherTestSequence {
617 a: Some(TestChoice::Boolean(true)),
618 b: None,
619 };
620 let expected2 = &[0x30, 0x05, 0xA0, 0x03, 0x81, 0x01, 0xFF];
624 assert_eq!(encode(&value2).unwrap(), expected2);
625 assert_eq!(decode::<AnotherTestSequence>(expected2).unwrap(), value2);
626 let value3 = AnotherTestSequence {
627 a: None,
628 b: Some(Any::new(any_payload.to_vec())),
629 };
630 let expected3 = &[0x30, 0x04, 0x81, 0x02, 0x05, 0x00];
633 assert_eq!(encode(&value3).unwrap(), expected3);
634 }
635
636 #[test]
637 fn test_cow_passthrough() {
638 use crate as rasn;
639 use rasn::prelude::*;
640
641 #[derive(AsnType, Debug, Clone, Encode, Decode, PartialEq)]
642 struct MyType {
643 name: Utf8String,
644 data: OctetString,
645 }
646
647 let my_type = MyType {
648 name: "test1".into(),
649 data: OctetString::from(vec![0, 1, 2, 3]),
650 };
651
652 let my_type_plain_ser = encode(&my_type).unwrap();
653 let my_type_cow_ser = encode(&Cow::Borrowed(&my_type)).unwrap();
654
655 assert_eq!(my_type_plain_ser, my_type_cow_ser);
656
657 let my_type_des_plain = decode::<MyType>(&my_type_plain_ser).unwrap();
658 let my_type_des_cow = decode::<Cow<'_, MyType>>(&my_type_cow_ser).unwrap();
659
660 assert_eq!(my_type_des_plain.name, Utf8String::from("test1"));
661 assert_eq!(my_type_des_plain.data, OctetString::from(vec![0, 1, 2, 3]));
662 assert_eq!(my_type_des_plain.name, my_type_des_cow.name);
663 assert_eq!(my_type_des_plain.data, my_type_des_cow.data);
664
665 assert!(matches!(my_type_des_cow, Cow::Owned(_)));
666 }
667}