1pub mod ber;
26#[cfg(feature = "der")]
27pub mod der;
28pub mod codec;
29pub mod parsing;
30pub(crate) mod utils;
31
32pub use crate::ber::*;
33pub use crate::codec::*;
34pub use crate::parsing::*;
35pub use crate::utils::primitive;
36
37use crate::utils::likely;
38use wildboar_asn1::error::{ASN1Error, ASN1ErrorCode, ASN1Result};
39use wildboar_asn1::{
40 ByteSlice, CharacterString, EmbeddedPDV, ExternalEncoding,
41 ExternalIdentification, GeneralizedTime,
42 PresentationContextSwitchingTypeIdentification, Tag, TagClass, TagNumber,
43 UTCTime,
44 UNIV_TAG_INTEGER,
45 UNIV_TAG_OBJECT_IDENTIFIER, UNIV_TAG_OCTET_STRING,
46 UNIV_TAG_OBJECT_DESCRIPTOR, BIT_STRING, BOOLEAN, DATE, DATE_TIME,
47 DURATION_EQUIVALENT, EXTERNAL, INTEGER, OBJECT_IDENTIFIER,
48 OCTET_STRING, REAL, RELATIVE_OID, TIME, TIME_OF_DAY,
49};
50use wildboar_asn1::{ENUMERATED, read_i64, DURATION, ComponentSpec, TagSelector};
51use std::borrow::Cow;
52use std::io::{Error, ErrorKind, Result, Write};
53use std::mem::size_of;
54use std::sync::Arc;
55use bytes::{Bytes, BytesMut, BufMut};
56
57pub const X690_TAG_CLASS_UNIVERSAL: u8 = 0b0000_0000;
59
60pub const X690_TAG_CLASS_APPLICATION: u8 = 0b0100_0000;
62
63pub const X690_TAG_CLASS_CONTEXT: u8 = 0b1000_0000;
65
66pub const X690_TAG_CLASS_PRIVATE: u8 = 0b1100_0000;
68
69pub const X690_SPECIAL_REAL_PLUS_INFINITY: u8 = 0b0000_0000;
71
72pub const X690_SPECIAL_REAL_MINUS_INFINITY: u8 = 0b0000_0001;
74
75pub const X690_SPECIAL_REAL_NOT_A_NUMBER: u8 = 0b0000_0010;
77
78pub const X690_SPECIAL_REAL_MINUS_ZERO: u8 = 0b0000_0011;
80
81pub const X690_REAL_SPECIAL: u8 = 0b0100_0000;
83
84pub const X690_REAL_BASE10: u8 = 0b0000_0000;
86
87pub const X690_REAL_BINARY: u8 = 0b1000_0000;
89
90pub const X690_REAL_POSITIVE: u8 = 0b0000_0000;
92
93pub const X690_REAL_NEGATIVE: u8 = 0b0100_0000;
95
96pub const X690_REAL_SIGN_MASK: u8 = 0b0100_0000;
98
99pub const X690_REAL_BASE_MASK: u8 = 0b0011_0000;
101
102pub const X690_REAL_BASE_2: u8 = 0b0000_0000;
104
105pub const X690_REAL_BASE_8: u8 = 0b0001_0000;
107
108pub const X690_REAL_BASE_16: u8 = 0b0010_0000;
110
111pub const X690_REAL_BASE_RESERVED: u8 = 0b0011_0000;
113
114pub const X690_REAL_BINARY_SCALING_MASK: u8 = 0b0000_1100;
116
117pub const X690_REAL_EXPONENT_FORMAT_MASK: u8 = 0b0000_0011;
119
120pub const X690_REAL_EXPONENT_FORMAT_1_OCTET: u8 = 0b0000_0000;
122
123pub const X690_REAL_EXPONENT_FORMAT_2_OCTET: u8 = 0b0000_0001;
125
126pub const X690_REAL_EXPONENT_FORMAT_3_OCTET: u8 = 0b0000_0010;
128
129pub const X690_REAL_EXPONENT_FORMAT_VAR_OCTET: u8 = 0b0000_0011;
131
132pub const X690_REAL_NR1: u8 = 1;
134
135pub const X690_REAL_NR2: u8 = 2;
137
138pub const X690_REAL_NR3: u8 = 3;
140
141#[derive(Clone, Debug, Hash, Copy, PartialEq, Eq)]
146pub enum X690Length {
147 Definite(usize),
149 Indefinite,
151}
152
153#[derive(Clone, Debug, Hash)]
158pub enum X690Value {
159 Primitive(Bytes),
161 Constructed(Arc<Vec<X690Element>>),
163 Serialized(Bytes),
165}
166
167impl X690Value {
168
169 pub fn len(&self) -> usize {
175 match self {
176 X690Value::Primitive(v) => v.len(),
177 X690Value::Constructed(components) => {
178 let mut sum: usize = 0;
179 for component in components.iter() {
180 sum += component.len();
181 }
182 sum
183 },
184 X690Value::Serialized(v) => {
185 match BER.decode_from_slice(&v) {
186 Ok((_, el)) => el.len(),
187 Err(_) => return 0,
188 }
189 }
190 }
191 }
192
193 #[inline]
197 pub fn from_explicit(inner: X690Element) -> Self {
198 X690Value::Constructed(Arc::new(Vec::from([ inner ])))
199 }
200
201 pub fn components(&self) -> ASN1Result<Arc<Vec<X690Element>>> {
207 match self {
208 X690Value::Constructed(components) => Ok(components.clone()),
209 X690Value::Serialized(v) => {
210 let (_, el) = BER.decode_from_slice(&v)?;
211 el.value.components()
212 },
213 _ => Err(ASN1Error::new(ASN1ErrorCode::invalid_construction)),
214 }
215 }
216
217}
218
219#[derive(Clone, Debug, Hash)]
225pub struct X690Element {
226 pub tag: Tag,
228 pub value: X690Value,
230}
231
232impl X690Element {
233
234 #[inline]
236 pub const fn new(tag: Tag, value: X690Value) -> X690Element {
237 X690Element { tag, value }
238 }
239
240 pub fn len(&self) -> usize {
244 let tag_length: usize = get_written_x690_tag_length(self.tag.tag_number);
245 let value_length = self.value.len();
246 let length_length: usize = get_written_x690_length_length(value_length);
247 let ret = tag_length + length_length + value_length;
248 ret
249 }
250
251 #[inline]
257 pub fn is_constructed (&self) -> bool {
258 if let X690Value::Serialized(v) = &self.value {
259 return v.get(0).is_some_and(|b| (*b & 0b0010_0000) == 0b0010_0000);
260 }
261 if let X690Value::Constructed(_) = self.value {
262 true
263 } else {
264 false
265 }
266 }
267
268 #[inline]
272 pub fn components (&self) -> ASN1Result<Arc<Vec<X690Element>>> {
273 self.value.components()
274 }
275
276 pub fn inner(&self) -> ASN1Result<X690Element> {
281 match &self.value {
282 X690Value::Constructed(components) => {
283 if components.len() != 1 {
284 return Err(self.to_asn1_error(ASN1ErrorCode::invalid_construction));
285 }
286 Ok(components[0].clone())
287 },
288 X690Value::Serialized(v) => {
289 let (_, el) = BER.decode_from_slice(&v)?;
290 el.inner()
291 },
292 _ => Err(self.to_asn1_error(ASN1ErrorCode::invalid_construction)),
293 }
294 }
295
296 pub fn content_octets <'a> (&'a self) -> ASN1Result<Cow<'a, [u8]>> {
302 match &self.value {
303 X690Value::Primitive(v) => Ok(Cow::Borrowed(&v)),
304 X690Value::Constructed(_) => {
305 let mut output = BytesMut::with_capacity(self.len()).writer();
306 x690_write_value(&mut output, &self.value)?;
307 Ok(Cow::Owned(output.into_inner().into()))
308 },
309 X690Value::Serialized(v) => {
310 let (_, el) = BER.decode_from_slice(v).unwrap();
311 match el.value {
312 X690Value::Primitive(inner) => Ok(Cow::Owned(inner.to_vec())),
313 X690Value::Constructed(_) => {
314 let mut output = BytesMut::with_capacity(el.len()).writer();
315 x690_write_value(&mut output, &el.value)?;
316 Ok(Cow::Owned(output.into_inner().into()))
317 },
318 _ => panic!("ASN.1 / X.690 decoding returned serialized value"),
319 }
320 }
321 }
322 }
323
324 #[inline]
329 pub fn to_asn1_error (&self, errcode: ASN1ErrorCode) -> ASN1Error {
330 ASN1Error {
331 error_code: errcode,
332 component_name: None,
333 tag: Some(Tag::new(self.tag.tag_class, self.tag.tag_number)),
334 length: Some(self.len()),
335 constructed: Some(self.is_constructed()),
336 value_preview: None,
337 bytes_read: None,
338 values_read: None,
339 err_source: None,
340 }
341 }
342
343 pub fn to_asn1_err_named (&self, errcode: ASN1ErrorCode, name: &str) -> ASN1Error {
348 let mut e = self.to_asn1_error(errcode);
349 e.component_name = Some(name.to_string());
350 e
351 }
352
353 #[inline]
359 pub fn is_empty (&self) -> bool {
360 match &self.value {
361 X690Value::Primitive(v) => v.len() == 0,
362 X690Value::Constructed(components) => components.len() == 0,
363 X690Value::Serialized(v) => v.len() <= 2,
364 }
365 }
366
367}
368
369impl From<i8> for X690Element {
370 #[inline]
372 fn from(value: i8) -> Self {
373 BER.encode_i8(value).unwrap()
374 }
375}
376
377impl From<i16> for X690Element {
378 #[inline]
380 fn from(value: i16) -> Self {
381 BER.encode_i16(value).unwrap()
382 }
383}
384
385impl From<i32> for X690Element {
386 #[inline]
388 fn from(value: i32) -> Self {
389 BER.encode_i32(value).unwrap()
390 }
391}
392
393impl From<i64> for X690Element {
394 #[inline]
396 fn from(value: i64) -> Self {
397 BER.encode_i64(value).unwrap()
398 }
399}
400
401impl From<u8> for X690Element {
402 #[inline]
404 fn from(value: u8) -> Self {
405 BER.encode_u8(value).unwrap()
406 }
407}
408
409impl From<u16> for X690Element {
410 #[inline]
412 fn from(value: u16) -> Self {
413 BER.encode_u16(value).unwrap()
414 }
415}
416
417impl From<u32> for X690Element {
418 #[inline]
420 fn from(value: u32) -> Self {
421 BER.encode_u32(value).unwrap()
422 }
423}
424
425impl From<u64> for X690Element {
426 #[inline]
428 fn from(value: u64) -> Self {
429 BER.encode_u64(value).unwrap()
430 }
431}
432
433impl From<OBJECT_IDENTIFIER> for X690Element {
434 #[inline]
436 fn from(value: OBJECT_IDENTIFIER) -> Self {
437 X690Element::from(&value)
438 }
439}
440
441impl From<&OBJECT_IDENTIFIER> for X690Element {
442 #[inline]
444 fn from(value: &OBJECT_IDENTIFIER) -> Self {
445 BER.encode_object_identifier(value).unwrap()
446 }
447}
448
449impl From<bool> for X690Element {
450 #[inline]
452 fn from(value: bool) -> Self {
453 BER.encode_boolean(&value).unwrap()
454 }
455}
456
457impl From<DATE> for X690Element {
458 #[inline]
460 fn from(value: DATE) -> Self {
461 BER.encode_date(&value).unwrap()
462 }
463}
464
465impl From<TIME_OF_DAY> for X690Element {
466 #[inline]
468 fn from(value: TIME_OF_DAY) -> Self {
469 BER.encode_time_of_day(&value).unwrap()
470 }
471}
472
473impl From<DATE_TIME> for X690Element {
474 #[inline]
476 fn from(value: DATE_TIME) -> Self {
477 BER.encode_date_time(&value).unwrap()
478 }
479}
480
481impl From<TIME> for X690Element {
482 #[inline]
484 fn from(value: TIME) -> Self {
485 BER.encode_time(&value).unwrap()
486 }
487}
488
489impl From<DURATION> for X690Element {
490 #[inline]
492 fn from(value: DURATION) -> Self {
493 BER.encode_duration(&value).unwrap()
494 }
495}
496
497impl TryInto<i8> for X690Element {
498 type Error = ASN1Error;
499 #[inline]
501 fn try_into(self) -> ASN1Result<i8> {
502 BER.decode_i8(&self)
503 }
504}
505
506impl TryInto<i16> for X690Element {
507 type Error = ASN1Error;
508 #[inline]
510 fn try_into(self) -> ASN1Result<i16> {
511 BER.decode_i16(&self)
512 }
513}
514
515impl TryInto<i32> for X690Element {
516 type Error = ASN1Error;
517 #[inline]
519 fn try_into(self) -> ASN1Result<i32> {
520 BER.decode_i32(&self)
521 }
522}
523
524impl TryInto<i64> for X690Element {
525 type Error = ASN1Error;
526 #[inline]
528 fn try_into(self) -> ASN1Result<i64> {
529 BER.decode_i64(&self)
530 }
531}
532
533impl TryInto<i128> for X690Element {
534 type Error = ASN1Error;
535 #[inline]
537 fn try_into(self) -> ASN1Result<i128> {
538 BER.decode_i128(&self)
539 }
540}
541
542impl TryInto<u8> for X690Element {
543 type Error = ASN1Error;
544 #[inline]
546 fn try_into(self) -> ASN1Result<u8> {
547 BER.decode_u8(&self)
548 }
549}
550
551impl TryInto<u16> for X690Element {
552 type Error = ASN1Error;
553 #[inline]
555 fn try_into(self) -> ASN1Result<u16> {
556 BER.decode_u16(&self)
557 }
558}
559
560impl TryInto<u32> for X690Element {
561 type Error = ASN1Error;
562 #[inline]
564 fn try_into(self) -> ASN1Result<u32> {
565 BER.decode_u32(&self)
566 }
567}
568
569impl TryInto<u64> for X690Element {
570 type Error = ASN1Error;
571 #[inline]
573 fn try_into(self) -> ASN1Result<u64> {
574 BER.decode_u64(&self)
575 }
576}
577
578impl TryInto<u128> for X690Element {
579 type Error = ASN1Error;
580 #[inline]
582 fn try_into(self) -> ASN1Result<u128> {
583 BER.decode_u128(&self)
584 }
585}
586
587impl TryInto<BOOLEAN> for X690Element {
588 type Error = ASN1Error;
589 #[inline]
591 fn try_into(self) -> ASN1Result<BOOLEAN> {
592 BER.decode_boolean(&self)
593 }
594}
595
596impl PartialEq for X690Element {
597 fn eq(&self, other: &Self) -> bool {
603 fn as_decoded<'a>(el: &'a X690Element) -> Cow<'a, X690Element> {
605 match &el.value {
606 X690Value::Serialized(bytes) => {
607 match BER.decode_from_slice(bytes) {
608 Ok((_, decoded)) => Cow::Owned(decoded),
609 Err(_) => Cow::Borrowed(el), }
611 }
612 _ => Cow::Borrowed(el),
613 }
614 }
615
616 let left = as_decoded(self);
617 let right = as_decoded(other);
618
619 match (&left.value, &right.value) {
620 (X690Value::Primitive(a), X690Value::Primitive(b)) => a == b,
621 (X690Value::Constructed(a), X690Value::Constructed(b)) => {
622 if a.len() != b.len() {
623 return false;
624 }
625 a.iter().zip(b.iter()).all(|(x, y)| x == y)
626 }
627 (X690Value::Primitive(_), _) | (X690Value::Constructed(_), _) | (_, X690Value::Primitive(_)) | (_, X690Value::Constructed(_)) => false,
628 _ => false,
630 }
631 }
632}
633
634impl Eq for X690Element {}
635
636pub fn x690_decode_tag(bytes: ByteSlice) -> ASN1Result<(usize, Tag, bool)> {
645 if bytes.len() == 0 {
646 return Err(ASN1Error::new(ASN1ErrorCode::tlv_truncated));
647 }
648 let mut bytes_read = 1;
649 let tag_class = match (bytes[0] & 0b1100_0000) >> 6 {
650 0 => TagClass::UNIVERSAL,
651 1 => TagClass::APPLICATION,
652 2 => TagClass::CONTEXT,
653 3 => TagClass::PRIVATE,
654 _ => panic!("Impossible tag class"),
655 };
656 let constructed = (bytes[0] & 0b0010_0000) > 0;
657 let mut tag_number: TagNumber = 0;
658
659 if (bytes[0] & 0b00011111) == 0b00011111 {
660 for byte in bytes[1..].iter() {
662 let final_byte: bool = ((*byte) & 0b1000_0000) == 0;
663 if (tag_number > 0) && !final_byte {
664 return Err(ASN1Error::new(ASN1ErrorCode::tag_too_big));
667 }
668 let seven_bits = ((*byte) & 0b0111_1111) as u16;
669 if !final_byte && (seven_bits == 0) {
670 return Err(ASN1Error::new(ASN1ErrorCode::padding_in_tag_number));
672 }
673 tag_number <<= 7;
674 tag_number += seven_bits;
675 bytes_read += 1;
676 if final_byte {
677 break;
678 }
679 }
680 if tag_number <= 30 {
681 return Err(ASN1Error::new(ASN1ErrorCode::tag_number_could_have_used_short_form));
683 }
684 } else {
685 tag_number = (bytes[0] & 0b00011111) as TagNumber;
686 }
687
688 let tag = Tag::new(tag_class, tag_number);
689 Ok((bytes_read, tag, constructed))
690}
691
692pub fn get_x690_tag_and_length_length(bytes: ByteSlice) -> usize {
697 if bytes.len() == 0 {
698 return 0;
699 }
700 let mut len: usize = 1;
701 if (bytes[0] & 0b00011111) == 0b00011111 {
702 for byte in bytes[1..].iter() {
704 len += 1; if ((*byte) & 0b1000_0000) == 0 {
706 break;
707 }
708 }
709 }
710 if len >= bytes.len() {
711 return len;
712 }
713 let length_byte_0 = bytes[len - 1];
714 len += 1;
715 if (length_byte_0 & 0b1000_0000) == 0 {
716 return len;
718 }
719 (length_byte_0 & 0b0111_1111) as usize
720}
721
722const fn base_128_len(num: u32) -> usize {
727 if likely(num < 128) {
728 return 1;
729 }
730 let mut l = 0;
731 let mut i = num;
732 while i > 0 {
733 l += 1;
734 i >>= 7;
735 }
736 return l;
737}
738
739fn write_base_128<W>(output: &mut W, mut num: u32) -> Result<usize>
746where
747 W: Write,
748{
749 #[cfg(feature = "likely_stable")]
750 if likely(num < 128) {
751 return output.write(&[num as u8]);
752 }
753
754 let mut encoded: [u8; 5] = [0; 5];
756 let mut byte_count: usize = 0;
757 while num > 0b0111_1111 {
758 encoded[byte_count] = (num & 0b0111_1111) as u8 | 0b1000_0000;
759 byte_count += 1;
760 num >>= 7;
761 }
762 encoded[byte_count] = num as u8;
763 output.write(&encoded[0..byte_count+1])
764}
765
766pub const fn get_written_x690_tag_length(tagnum: TagNumber) -> usize {
771 if tagnum < 31 {
772 return 1;
774 }
775 base_128_len(tagnum as u32) + 1
776}
777
778pub const fn get_written_x690_length_length(len: usize) -> usize {
783 if len <= 127 {
784 return 1;
786 }
787 let octets_needed: usize = match len {
788 0..=255 => 1,
789 256..=65535 => 2,
790 65536..=16777215 => 3,
791 16777216..=4294967295 => 4,
792 _ => return 5, };
794 octets_needed + 1
795}
796
797pub fn x690_write_tag<W>(
804 output: &mut W,
805 class: TagClass,
806 constructed: bool,
807 tagnum: TagNumber,
808) -> Result<usize>
809where
810 W: Write,
811{
812 let k: u8 = match class {
813 TagClass::UNIVERSAL => X690_TAG_CLASS_UNIVERSAL,
814 TagClass::APPLICATION => X690_TAG_CLASS_APPLICATION,
815 TagClass::CONTEXT => X690_TAG_CLASS_CONTEXT,
816 TagClass::PRIVATE => X690_TAG_CLASS_PRIVATE,
817 };
818 if tagnum < 31 {
819 return output.write(&[k
821 | if constructed {
822 0b0010_0000
823 } else {
824 0b0000_0000
825 }
826 | tagnum as u8]);
827 } else {
828 let first_byte_result = output.write(&[k
829 | if constructed {
830 0b0010_0000
831 } else {
832 0b0000_0000
833 }
834 | 0b0001_1111u8]);
835 if let Err(e) = first_byte_result {
836 return Err(e);
837 }
838 return write_base_128(output, tagnum.into());
839 }
840}
841
842pub fn x690_write_length<W>(output: &mut W, length: usize) -> Result<usize>
849where
850 W: Write,
851{
852 if length <= 127 {
853 return output.write(&[length as u8]);
855 } else {
856 let octets_needed: u8 = match length {
859 0..=255 => 1,
860 256..=65535 => 2,
861 65536..=16777215 => 3,
862 16777216..=4294967295 => 4,
863 _ => return Err(Error::from(ErrorKind::Unsupported)),
864 };
865 let length_bytes = length.to_be_bytes();
866 output.write(&[0b1000_0000 | octets_needed])?;
867 output.write(&length_bytes[std::mem::size_of::<usize>()-octets_needed as usize..])
868 }
869}
870
871#[inline]
877pub fn x690_write_boolean_value<W>(output: &mut W, value: &BOOLEAN) -> Result<usize>
878where
879 W: Write,
880{
881 if *value {
882 return output.write(&[0xFF]);
883 } else {
884 return output.write(&[0x00]);
885 }
886}
887
888#[inline]
894pub fn x690_write_integer_value<W>(output: &mut W, value: &INTEGER) -> Result<usize>
895where
896 W: Write,
897{
898 if value.len() == 0 {
899 return Err(std::io::Error::from(ErrorKind::InvalidData));
900 }
901 if value.len() == 1 {
902 return output.write(value);
903 }
904 if value[0] == 0x00 && (value[1] & 0b1000_0000) == 0 {
905 return Err(std::io::Error::from(ErrorKind::InvalidData));
906 }
907 if value[0] == 0xFF && (value[1] & 0b1000_0000) > 0 {
908 return Err(std::io::Error::from(ErrorKind::InvalidData));
909 }
910 output.write(value)
911}
912
913pub fn x690_write_i64_value<W>(output: &mut W, value: i64) -> Result<usize>
920where
921 W: Write,
922{
923 let bytes: [u8; 8] = value.to_be_bytes();
924 let padding_byte: u8 = if value >= 0 { 0x00 } else { 0xFF };
925 let mut number_of_padding_bytes: usize = 0;
926 for byte in bytes {
927 if byte == padding_byte {
928 number_of_padding_bytes += 1;
929 } else {
930 break;
931 }
932 }
933 let mut bytes_written: usize = 0;
934 if (number_of_padding_bytes == size_of::<i64>())
935 || (value >= 0 && ((bytes[number_of_padding_bytes] & 0b1000_0000) > 0))
936 || (value < 0 && ((bytes[number_of_padding_bytes] & 0b1000_0000) == 0)) {
937 bytes_written += output.write(&[padding_byte])?;
938 }
939 bytes_written += output.write(&(bytes[number_of_padding_bytes..size_of::<i64>()]))?;
940 Ok(bytes_written)
941}
942
943#[inline]
949pub fn x690_write_enum_value<W>(output: &mut W, value: &ENUMERATED) -> Result<usize>
950where
951 W: Write,
952{
953 x690_write_i64_value(output, *value)
954}
955
956pub fn x690_write_bit_string_value<W>(output: &mut W, value: &BIT_STRING) -> Result<usize>
962where
963 W: Write,
964{
965 let trailing_bits = value.get_trailing_bits_count();
966 output.write(&[trailing_bits])?;
967 if trailing_bits == 0 {
968 let bytes_written = output.write(value.get_bytes_ref())?;
969 return Ok(bytes_written + 1);
970 }
971 let maybe_last_byte = value.get_bytes_ref().last();
973 let der_violated;
974 let bytes = value.get_bytes_ref();
975 let correct_last_byte: u8;
976 if let Some(last_byte) = maybe_last_byte {
977 let trailing_bits_mask = !(0xFFu8 << trailing_bits);
978 der_violated = (last_byte & trailing_bits_mask) > 0;
979 correct_last_byte = last_byte & (0xFFu8 << trailing_bits);
980 } else {
981 return Err(std::io::Error::from(ErrorKind::InvalidData));
982 }
983
984 if likely(!der_violated) {
986 let bytes_written = output.write(value.get_bytes_ref())?;
987 return Ok(bytes_written + 1);
988 }
989
990 debug_assert!(maybe_last_byte.is_some());
991 let mut bytes_written = output.write(&bytes[..bytes.len() - 1])?;
992 bytes_written += output.write(&[ correct_last_byte ])?;
993 Ok(bytes_written + 1)
994}
995
996#[inline]
1002pub fn x690_write_octet_string_value<W>(output: &mut W, value: &OCTET_STRING) -> Result<usize>
1003where
1004 W: Write,
1005{
1006 output.write(value)
1007}
1008
1009#[inline]
1015pub fn x690_write_object_identifier_value<W>(
1016 output: &mut W,
1017 value: &OBJECT_IDENTIFIER,
1018) -> Result<usize>
1019where
1020 W: Write,
1021{
1022 output.write(value.as_x690_slice())
1023}
1024
1025#[inline]
1031pub fn x690_write_object_descriptor_value<W>(
1032 output: &mut W,
1033 value: &str,
1034) -> Result<usize>
1035where
1036 W: Write,
1037{
1038 output.write(value.as_bytes())
1039}
1040
1041pub fn x690_encode_external_components (value: &EXTERNAL) -> Result<Vec<X690Element>> {
1055 let mut inner_elements: Vec<X690Element> = Vec::with_capacity(4);
1056 match &value.identification {
1057 ExternalIdentification::syntax(oid) => {
1058 let mut bytes = BytesMut::new().writer();
1059 x690_write_object_identifier_value(&mut bytes, &oid)?;
1060 let element = X690Element::new(
1061 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_OBJECT_IDENTIFIER),
1062 X690Value::Primitive(bytes.into_inner().into()),
1063 );
1064 inner_elements.push(element);
1065 }
1066 ExternalIdentification::presentation_context_id(pci) => {
1067 let mut bytes = BytesMut::new().writer();
1068 x690_write_integer_value(&mut bytes, pci)?;
1069 let element = X690Element::new(
1070 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_INTEGER),
1071 X690Value::Primitive(bytes.into_inner().into()),
1072 );
1073 inner_elements.push(element);
1074 }
1075 ExternalIdentification::context_negotiation(cn) => {
1076 let mut direct_ref_bytes = BytesMut::new().writer();
1077 x690_write_object_identifier_value(&mut direct_ref_bytes, &cn.transfer_syntax)?;
1078 let direct_ref_element = X690Element::new(
1079 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_OBJECT_IDENTIFIER),
1080 X690Value::Primitive(direct_ref_bytes.into_inner().into()),
1081 );
1082 inner_elements.push(direct_ref_element);
1083 let mut indirect_ref_bytes = BytesMut::new().writer();
1084 x690_write_integer_value(&mut indirect_ref_bytes, &cn.presentation_context_id)?;
1085 let indirect_ref_element = X690Element::new(
1086 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_INTEGER),
1087 X690Value::Primitive(indirect_ref_bytes.into_inner().into()),
1088 );
1089 inner_elements.push(indirect_ref_element);
1090 }
1091 };
1092 match &value.data_value_descriptor {
1093 Some(dvd) => {
1094 let mut bytes = BytesMut::new().writer();
1095 x690_write_object_descriptor_value(&mut bytes, &dvd)?;
1096 let element = X690Element::new(
1097 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_OBJECT_DESCRIPTOR),
1098 X690Value::Primitive(bytes.into_inner().into()),
1099 );
1100 inner_elements.push(element);
1101 }
1102 None => (),
1103 };
1104 let mut data_value_bytes = BytesMut::new().writer();
1105 match &value.data_value {
1106 ExternalEncoding::single_ASN1_type(t) => {
1107 let el = BER.encode_any(t)?;
1108 x690_write_tlv(&mut data_value_bytes, &el)?
1109 },
1110 ExternalEncoding::octet_aligned(o) => x690_write_octet_string_value(&mut data_value_bytes, o)?,
1111 ExternalEncoding::arbitrary(b) => x690_write_bit_string_value(&mut data_value_bytes, b)?,
1112 };
1113 let data_value_element = X690Element::new(
1114 Tag::new(TagClass::CONTEXT, 1),
1115 X690Value::Primitive(data_value_bytes.into_inner().into()),
1116 );
1117 inner_elements.push(data_value_element);
1118 Ok(inner_elements)
1119}
1120
1121pub fn x690_write_external_value<W>(output: &mut W, value: &EXTERNAL) -> Result<usize>
1136where
1137 W: Write,
1138{
1139 let components = x690_encode_external_components(value)?;
1140 let mut bytes_written: usize = 0;
1141 for component in components {
1142 bytes_written += x690_write_tlv(output, &component)?;
1143 }
1144 Ok(bytes_written)
1145}
1146
1147pub fn x690_write_real_value<W>(output: &mut W, value: &REAL) -> Result<usize>
1164where
1165 W: Write,
1166{
1167 let is_zero = *value == 0.0;
1171 if is_zero {
1173 return Ok(0);
1174 }
1175 if is_zero && value.is_sign_negative() {
1177 return output.write(&[X690_REAL_SPECIAL | X690_SPECIAL_REAL_MINUS_ZERO]);
1178 }
1179
1180 if value.is_nan() {
1181 return output.write(&[X690_REAL_SPECIAL | X690_SPECIAL_REAL_NOT_A_NUMBER]);
1182 }
1183
1184 if value.is_infinite() {
1185 if value.is_sign_negative() {
1186 return output.write(&[X690_REAL_SPECIAL | X690_SPECIAL_REAL_MINUS_INFINITY]);
1187 } else {
1188 return output.write(&[X690_REAL_SPECIAL | X690_SPECIAL_REAL_PLUS_INFINITY]);
1189 }
1190 }
1191
1192 let sign_bit: u8 = if value.is_sign_negative() {
1193 X690_REAL_NEGATIVE
1194 } else {
1195 X690_REAL_POSITIVE
1196 };
1197 let base_bits: u8 = X690_REAL_BASE_2;
1198 let scaling_factor: u8 = 0;
1199 let bits = value.to_bits();
1200 let mantissa_mask = (1u64 << 52) - 1;
1201 let mantissa: u64 = bits & mantissa_mask;
1202 let biased_exp = ((bits >> 52) & 0x7FF) as u16;
1203
1204 let mut mantissa = if biased_exp != 0 { mantissa | (1u64 << 52) } else { mantissa };
1206 let mut exponent = if biased_exp != 0 { biased_exp as i16 - 1023 - 52 } else { -1023 - 51 };
1207
1208 while mantissa > 0 && mantissa & 1 == 0 {
1210 mantissa >>= 1;
1211 exponent += 1;
1212 }
1213
1214 let e_bytes = exponent.to_be_bytes();
1215 let mut bytes_written: usize = 0;
1216 if exponent > u8::MAX as i16 {
1217 let byte0: u8 = X690_REAL_BINARY
1218 | sign_bit
1219 | base_bits
1220 | scaling_factor
1221 | X690_REAL_EXPONENT_FORMAT_2_OCTET;
1222 bytes_written += output.write(&[byte0, e_bytes[0], e_bytes[1]])?;
1223 } else {
1224 let byte0: u8 = X690_REAL_BINARY
1225 | sign_bit
1226 | base_bits
1227 | scaling_factor
1228 | X690_REAL_EXPONENT_FORMAT_1_OCTET;
1229 bytes_written += output.write(&[byte0, e_bytes[1]])?;
1230 };
1231
1232 return match x690_write_i64_value(output, mantissa as i64) {
1233 Err(e) => return Err(e),
1234 Ok(wrote) => Ok(wrote + bytes_written),
1235 };
1236}
1237
1238pub fn x690_encode_context_switching_identification(
1252 id: &PresentationContextSwitchingTypeIdentification,
1253) -> Result<X690Element> {
1254 match id {
1255 PresentationContextSwitchingTypeIdentification::syntaxes(syntaxes) => {
1256 let mut abstract_value_bytes = BytesMut::new().writer();
1257 let mut transfer_value_bytes = BytesMut::new().writer();
1258 x690_write_object_identifier_value(
1259 &mut abstract_value_bytes,
1260 &syntaxes.r#abstract,
1261 )?;
1262 x690_write_object_identifier_value(&mut transfer_value_bytes, &syntaxes.transfer)?;
1263 let mut syntaxes_elements: Vec<X690Element> = Vec::with_capacity(2);
1264 syntaxes_elements.push(X690Element::new(
1265 Tag::new(TagClass::CONTEXT, 0),
1266 X690Value::Primitive(abstract_value_bytes.into_inner().into()),
1267 ));
1268 syntaxes_elements.push(X690Element::new(
1269 Tag::new(TagClass::CONTEXT, 1),
1270 X690Value::Primitive(transfer_value_bytes.into_inner().into()),
1271 ));
1272 let element = X690Element::new(
1273 Tag::new(TagClass::CONTEXT, 0),
1274 X690Value::Constructed(Arc::new(syntaxes_elements)),
1275 );
1276 return Ok(X690Element::new(
1277 Tag::new(TagClass::CONTEXT, 0),
1278 X690Value::Constructed(Arc::new(Vec::from([ element ]))),
1279 ));
1280 }
1281 PresentationContextSwitchingTypeIdentification::syntax(oid) => {
1282 let mut bytes = BytesMut::with_capacity(oid.as_x690_slice().len()).writer();
1284 x690_write_object_identifier_value(&mut bytes, &oid)?;
1285 let element = X690Element::new(
1286 Tag::new(TagClass::CONTEXT, 1),
1287 X690Value::Primitive(bytes.into_inner().into()),
1288 );
1289 return Ok(X690Element::new(
1290 Tag::new(TagClass::CONTEXT, 0),
1291 X690Value::Constructed(Arc::new(Vec::from([ element ]))),
1292 ));
1293 }
1294 PresentationContextSwitchingTypeIdentification::presentation_context_id(pci) => {
1295 let mut bytes = BytesMut::with_capacity(pci.len()).writer();
1296 x690_write_integer_value(&mut bytes, pci)?;
1297 let element = X690Element::new(
1298 Tag::new(TagClass::CONTEXT, 2),
1299 X690Value::Primitive(bytes.into_inner().into()),
1300 );
1301 return Ok(X690Element::new(
1302 Tag::new(TagClass::CONTEXT, 0),
1303 X690Value::Constructed(Arc::new(Vec::from([ element ]))),
1304 ));
1305 }
1306 PresentationContextSwitchingTypeIdentification::context_negotiation(cn) => {
1307 let mut pci_bytes = BytesMut::new().writer();
1308 x690_write_integer_value(&mut pci_bytes, &cn.presentation_context_id)?;
1309 let pci_element = X690Element::new(
1310 Tag::new(TagClass::CONTEXT, 0),
1311 X690Value::Primitive(pci_bytes.into_inner().into()),
1312 );
1313 let mut transfer_syntax_bytes = BytesMut::new().writer();
1314 x690_write_object_identifier_value(
1315 &mut transfer_syntax_bytes,
1316 &cn.transfer_syntax,
1317 )?;
1318 let transfer_syntax_element = X690Element::new(
1319 Tag::new(TagClass::CONTEXT, 1),
1320 X690Value::Primitive(transfer_syntax_bytes.into_inner().into()),
1321 );
1322 let cn_elements: Vec<X690Element> = vec![pci_element, transfer_syntax_element];
1323 let element = X690Element::new(
1324 Tag::new(TagClass::CONTEXT, 3),
1325 X690Value::Constructed(Arc::new(cn_elements)),
1326 );
1327 return Ok(X690Element::new(
1328 Tag::new(TagClass::CONTEXT, 0),
1329 X690Value::Constructed(Arc::new(Vec::from([ element ]))),
1330 ));
1331 }
1332 PresentationContextSwitchingTypeIdentification::transfer_syntax(ts) => {
1333 let mut bytes = BytesMut::new().writer();
1334 x690_write_object_identifier_value(&mut bytes, &ts)?;
1335 let element = X690Element::new(
1336 Tag::new(TagClass::CONTEXT, 4),
1337 X690Value::Primitive(bytes.into_inner().into()),
1338 );
1339 return Ok(X690Element::new(
1340 Tag::new(TagClass::CONTEXT, 0),
1341 X690Value::Constructed(Arc::new(Vec::from([ element ]))),
1342 ));
1343 }
1344 PresentationContextSwitchingTypeIdentification::fixed => {
1345 let element = X690Element::new(
1346 Tag::new(TagClass::CONTEXT, 5),
1347 X690Value::Primitive(Bytes::new()),
1348 );
1349 return Ok(X690Element::new(
1350 Tag::new(TagClass::CONTEXT, 0),
1351 X690Value::Constructed(Arc::new(Vec::from([ element ]))),
1352 ));
1353 }
1354 }
1355}
1356
1357pub fn x690_encode_embedded_pdv_components (value: &EmbeddedPDV) -> Result<Vec<X690Element>> {
1368 let id = x690_encode_context_switching_identification(&value.identification)?;
1369 let mut data_value_bytes = BytesMut::new().writer();
1370 x690_write_octet_string_value(&mut data_value_bytes, &value.data_value)?;
1371 let data_value_element = X690Element::new(
1372 Tag::new(TagClass::CONTEXT, 1),
1373 X690Value::Primitive(data_value_bytes.into_inner().into()),
1374 );
1375 Ok(vec![id, data_value_element])
1376}
1377
1378pub fn x690_write_embedded_pdv_value<W>(output: &mut W, value: &EmbeddedPDV) -> Result<usize>
1392where
1393 W: Write,
1394{
1395 let components: Vec<X690Element> = x690_encode_embedded_pdv_components(value)?;
1396 let mut bytes_written: usize = 0;
1397 for component in components {
1398 bytes_written += x690_write_tlv(output, &component)?;
1399 }
1400 Ok(bytes_written)
1401}
1402
1403#[inline]
1405pub fn x690_write_utf8_string_value<W>(output: &mut W, value: &str) -> Result<usize>
1406where
1407 W: Write,
1408{
1409 output.write(value.as_bytes())
1410}
1411
1412#[inline]
1414pub fn x690_write_relative_oid_value<W>(output: &mut W, value: &RELATIVE_OID) -> Result<usize>
1415where
1416 W: Write,
1417{
1418 output.write(value.as_x690_slice())
1419}
1420
1421#[inline]
1423pub fn x690_write_time_value<W>(output: &mut W, value: &TIME) -> Result<usize>
1424where
1425 W: Write,
1426{
1427 output.write(value.as_bytes())
1428}
1429
1430#[inline]
1432pub fn x690_write_utc_time_value<W>(output: &mut W, value: &UTCTime) -> Result<usize>
1433where
1434 W: Write,
1435{
1436 output.write(value.to_string().as_bytes())
1437}
1438
1439#[inline]
1441pub fn x690_write_generalized_time_value<W>(
1442 output: &mut W,
1443 value: &GeneralizedTime,
1444) -> Result<usize>
1445where
1446 W: Write,
1447{
1448 output.write(value.to_string().as_bytes())
1449}
1450
1451#[inline]
1453pub fn x690_write_universal_string_value<W>(
1454 output: &mut W,
1455 value: &[u32],
1456) -> Result<usize>
1457where
1458 W: Write,
1459{
1460 for c in value {
1461 output.write(&c.to_be_bytes())?;
1462 }
1463 Ok(value.len() * 4)
1464}
1465
1466pub fn x690_encode_character_string_components (value: &CharacterString) -> Result<Vec<X690Element>> {
1480 let id = x690_encode_context_switching_identification(&value.identification)?;
1481 let mut data_value_bytes = BytesMut::new().writer();
1482 x690_write_octet_string_value(&mut data_value_bytes, &value.string_value)?;
1483 let data_value_element = X690Element::new(
1484 Tag::new(TagClass::CONTEXT, 1),
1485 X690Value::Primitive(data_value_bytes.into_inner().into()),
1486 );
1487 Ok(vec![id, data_value_element])
1488}
1489
1490pub fn x690_write_character_string_value<W>(
1503 output: &mut W,
1504 value: &CharacterString,
1505) -> Result<usize>
1506where
1507 W: Write,
1508{
1509 let components: Vec<X690Element> = x690_encode_character_string_components(value)?;
1510 let mut bytes_written: usize = 0;
1511 for component in components {
1512 bytes_written += x690_write_tlv(output, &component)?;
1513 }
1514 Ok(bytes_written)
1515}
1516
1517pub fn x690_write_bmp_string_value<W>(output: &mut W, value: &[u16]) -> Result<usize>
1519where
1520 W: Write,
1521{
1522 for c in value {
1523 output.write(&c.to_be_bytes())?;
1524 }
1525 Ok(value.len() * 2)
1526}
1527
1528#[inline]
1530pub fn x690_write_string_value<W>(output: &mut W, value: &str) -> Result<usize>
1531where
1532 W: Write,
1533{
1534 output.write(value.as_bytes())
1535}
1536
1537pub fn x690_write_date_value<W>(output: &mut W, value: &DATE) -> Result<usize>
1539where
1540 W: Write,
1541{
1542 if value.month > 12 || value.month == 0 || value.day > 31 || value.day == 0 {
1543 return Err(Error::from(ErrorKind::InvalidData));
1544 }
1545 output.write(value.to_num_string().as_bytes())
1546}
1547
1548pub fn x690_write_time_of_day_value<W>(output: &mut W, value: &TIME_OF_DAY) -> Result<usize>
1550where
1551 W: Write,
1552{
1553 if value.hour > 23 || value.minute > 59 || value.second > 59 {
1554 return Err(Error::from(ErrorKind::InvalidData));
1555 }
1556 output.write(value.to_num_string().as_bytes())
1557}
1558
1559pub fn x690_write_date_time_value<W>(output: &mut W, value: &DATE_TIME) -> Result<usize>
1561where
1562 W: Write,
1563{
1564 output.write(value.to_num_string().as_bytes())
1565}
1566
1567pub fn x690_write_duration_value<W>(output: &mut W, value: &DURATION_EQUIVALENT) -> Result<usize>
1569where
1570 W: Write,
1571{
1572 output.write(&value.to_string().as_bytes()[1..]) }
1574
1575fn x690_write_value<W>(output: &mut W, encoding: &X690Value) -> Result<usize>
1577where
1578 W: Write,
1579{
1580 match encoding {
1581 X690Value::Primitive(v) => output.write(&v),
1582 X690Value::Constructed(components) => {
1583 let mut sum: usize = 0;
1584 for component in components.iter() {
1585 sum += x690_write_tlv(output, component)?;
1586 }
1587 Ok(sum)
1588 },
1589 X690Value::Serialized(v) => {
1590 let (_, el) = BER.decode_from_slice(&v)?;
1591 x690_write_value(output, &el.value)
1592 }
1593 }
1594}
1595
1596pub fn x690_write_tlv<W>(output: &mut W, node: &X690Element) -> Result<usize>
1598where
1599 W: Write,
1600{
1601 if let X690Value::Serialized(serialized) = &node.value {
1602 return output.write(&serialized);
1603 }
1604 let mut bytes_written: usize = 0;
1605 bytes_written += x690_write_tag(output, node.tag.tag_class, node.is_constructed(), node.tag.tag_number)?;
1606 bytes_written += x690_write_length(output, node.value.len())?;
1607 bytes_written += x690_write_value(output, &node.value)?;
1608 Ok(bytes_written)
1609}
1610
1611pub fn deconstruct<'a>(el: &'a X690Element) -> ASN1Result<Cow<'a, [u8]>> {
1625 match &el.value {
1626 X690Value::Primitive(bytes) => Ok(Cow::Borrowed(bytes)),
1627 X690Value::Constructed(children) => {
1628 let mut deconstructed_value = BytesMut::new();
1629 for child in children.iter() {
1630 if child.tag.tag_class != TagClass::UNIVERSAL
1633 || child.tag.tag_number != UNIV_TAG_OCTET_STRING
1634 {
1635 let mut err =
1636 ASN1Error::new(ASN1ErrorCode::string_constructed_with_invalid_tagging);
1637 err.tag = Some(Tag::new(el.tag.tag_class, el.tag.tag_number));
1638 err.length = Some(el.len());
1639 err.constructed = Some(true);
1640 return Err(err);
1641 }
1642 let deconstructed_child = deconstruct(&child)?;
1643 deconstructed_value.put(deconstructed_child.as_ref());
1644 }
1645 Ok(Cow::Owned(Vec::<u8>::from(deconstructed_value)))
1646 },
1647 X690Value::Serialized(v) => {
1648 let (_, el) = BER.decode_from_slice(&v)?;
1649 Ok(Cow::Owned(deconstruct(&el)?.into_owned()))
1650 }
1651 }
1652}
1653
1654pub const fn x690_read_boolean_value(value_bytes: ByteSlice) -> ASN1Result<BOOLEAN> {
1656 if value_bytes.len() != 1 {
1657 let err = ASN1Error::new(ASN1ErrorCode::x690_boolean_not_one_byte);
1658 return Err(err);
1659 }
1660 Ok(value_bytes[0] > 0)
1661}
1662
1663#[inline]
1665pub fn x690_read_integer_value(value_bytes: ByteSlice) -> ASN1Result<INTEGER> {
1666 Ok(Vec::from(value_bytes))
1669}
1670
1671#[inline]
1673pub fn x690_read_i64_value(value_bytes: ByteSlice) -> ASN1Result<i64> {
1674 match read_i64(value_bytes) {
1675 Some(v) => Ok(v),
1676 None => Err(ASN1Error::new(ASN1ErrorCode::value_too_big)),
1677 }
1678}
1679
1680#[inline]
1682pub fn x690_read_enum_value(value_bytes: ByteSlice) -> ASN1Result<ENUMERATED> {
1683 x690_read_i64_value(value_bytes)
1684}
1685
1686#[inline]
1688pub fn x690_read_object_identifier_value(value_bytes: ByteSlice) -> ASN1Result<OBJECT_IDENTIFIER> {
1689 OBJECT_IDENTIFIER::from_x690_encoding_slice(value_bytes)
1690}
1691
1692#[inline]
1694pub fn x690_read_relative_oid_value(value_bytes: ByteSlice) -> ASN1Result<RELATIVE_OID> {
1695 RELATIVE_OID::from_x690_encoding_slice(value_bytes)
1696}
1697
1698#[inline]
1700pub fn x690_read_date_value(value_bytes: ByteSlice) -> ASN1Result<DATE> {
1701 DATE::try_from(value_bytes)
1702}
1703
1704#[inline]
1706pub fn x690_read_time_of_day_value(value_bytes: ByteSlice) -> ASN1Result<TIME_OF_DAY> {
1707 TIME_OF_DAY::try_from(value_bytes)
1708}
1709
1710#[inline]
1712pub fn x690_read_date_time_value(value_bytes: ByteSlice) -> ASN1Result<DATE_TIME> {
1713 DATE_TIME::try_from(value_bytes)
1714}
1715
1716#[inline]
1718pub fn x690_read_duration_value(value_bytes: ByteSlice) -> ASN1Result<DURATION> {
1719 DURATION::try_from(value_bytes)
1720}
1721
1722pub trait RelateTLV {
1724
1725 fn relate_tlv (&mut self, el: &X690Element);
1727}
1728
1729impl RelateTLV for ASN1Error {
1730 fn relate_tlv (&mut self, el: &X690Element) {
1731 self.tag = Some(el.tag);
1732 self.constructed = Some(el.is_constructed());
1733 self.length = Some(el.len());
1734 }
1735}
1736
1737pub const _RCTL1_FOR_EXTERNAL: &[ComponentSpec; 4] = &[
1753 ComponentSpec::new(
1754 "direct-reference",
1755 true,
1756 TagSelector::tag((
1757 TagClass::UNIVERSAL,
1758 UNIV_TAG_OBJECT_IDENTIFIER,
1759 )),
1760 None,
1761 None,
1762 ),
1763 ComponentSpec::new(
1764 "indirect-reference",
1765 true,
1766 TagSelector::tag((TagClass::UNIVERSAL, UNIV_TAG_INTEGER)),
1767 None,
1768 None,
1769 ),
1770 ComponentSpec::new(
1771 "data-value-descriptor",
1772 true,
1773 TagSelector::tag((
1774 TagClass::UNIVERSAL,
1775 UNIV_TAG_OBJECT_DESCRIPTOR,
1776 )),
1777 None,
1778 None,
1779 ),
1780 ComponentSpec::new(
1781 "encoding",
1782 false,
1783 TagSelector::or(&[
1784 &TagSelector::tag((TagClass::CONTEXT, 0)),
1785 &TagSelector::tag((TagClass::CONTEXT, 1)),
1786 &TagSelector::tag((TagClass::CONTEXT, 2)),
1787 ]),
1788 None,
1789 None,
1790 ),
1791];
1792
1793pub const _EAL_FOR_EXTERNAL: &[ComponentSpec; 0] = &[];
1797
1798pub const _RCTL2_FOR_EXTERNAL: &[ComponentSpec; 0] = &[];
1802
1803#[cfg(test)]
1804mod tests {
1805
1806 use super::*;
1807 use std::sync::Arc;
1808 use wildboar_asn1::{
1809 Tag,
1810 TagClass,
1811 UNIV_TAG_OCTET_STRING,
1812 UNIV_TAG_BOOLEAN,
1813 UNIV_TAG_SEQUENCE,
1814 };
1815 use bytes::Bytes;
1816
1817 #[test]
1818 fn test_x690_write_boolean_value() {
1819 let mut output = BytesMut::new().writer();
1820 crate::x690_write_boolean_value(&mut output, &true).unwrap();
1821 crate::x690_write_boolean_value(&mut output, &false).unwrap();
1822 let output: Bytes = output.into_inner().into();
1823 assert_eq!(output.len(), 2);
1824 assert!(output.starts_with(&[0xFF, 0x00]));
1825 }
1826
1827 #[test]
1828 fn test_x690_write_integer_value() {
1829 let mut output = BytesMut::new();
1830 let mut i = 0;
1831 for value in -128i8..127i8 {
1832 let mut out = output.writer();
1833 crate::x690_write_enum_value(&mut out, &i64::from(value)).unwrap();
1834 output = out.into_inner();
1835 assert_eq!(output[i] as i8, value);
1836 i += 1;
1837 }
1838 assert_eq!(output.len(), 255);
1839 }
1840
1841 #[test]
1842 fn test_x690_write_octet_string_value() {
1843 let mut output = BytesMut::new().writer();
1844 let bytes: Vec<u8> = vec![1, 3, 5, 7, 9];
1845 crate::x690_write_octet_string_value(&mut output, &bytes).unwrap();
1846 let output: Bytes = output.into_inner().into();
1847 assert_eq!(output.len(), 5);
1848 assert!(output.starts_with(&[1, 3, 5, 7, 9]));
1849 }
1850
1851 #[test]
1852 fn test_x690_write_object_identifier_value() {
1853 let mut output = BytesMut::new().writer();
1854 let oid = wildboar_asn1::OBJECT_IDENTIFIER::try_from(vec![2u32, 5, 4, 3]).unwrap();
1855 crate::x690_write_object_identifier_value(&mut output, &oid).unwrap();
1856 let output: Bytes = output.into_inner().into();
1857 assert_eq!(output.len(), 3);
1858 assert!(output.starts_with(&[0x55, 0x04, 0x03]));
1859 }
1860
1861 #[test]
1862 fn test_x690_write_object_descriptor_value() {
1863 let mut output = BytesMut::new().writer();
1864 let value = String::from("commonName");
1865 crate::x690_write_object_descriptor_value(&mut output, &value).unwrap();
1866 let output: Bytes = output.into_inner().into();
1867 assert_eq!(output.len(), value.len());
1868 assert_eq!(
1869 String::from_utf8(output.into()).unwrap(),
1870 String::from("commonName")
1871 );
1872 }
1873
1874 #[test]
1875 fn test_x690_write_real_value() {
1876 let output = BytesMut::new();
1877 let value = 1.2345;
1878 crate::x690_write_real_value(&mut output.writer(), &value).unwrap();
1879 }
1880
1881 #[test]
1882 fn test_constructed_encoding() {
1883 let asn1_data = X690Element::new(
1884 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_SEQUENCE),
1885 crate::X690Value::Constructed(Arc::new(vec![
1886 X690Element::new(
1887 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_BOOLEAN),
1888 crate::X690Value::Primitive(Bytes::copy_from_slice(&[ 0xFF ])),
1889 ),
1890 X690Element::new(
1891 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_INTEGER),
1892 crate::X690Value::Primitive(Bytes::copy_from_slice(&[ 0x01, 0x03 ])),
1893 ),
1894 ])),
1895 );
1896 let mut output = Vec::new();
1897 match x690_write_tlv(&mut output, &asn1_data) {
1898 Ok(bytes_written) => {
1899 assert_eq!(bytes_written, 9);
1900 }
1901 Err(e) => panic!("{}", e),
1902 }
1903 assert!(output.starts_with(&[
1904 X690_TAG_CLASS_UNIVERSAL
1905 | 0b0010_0000 | UNIV_TAG_SEQUENCE as u8,
1907 0x07,
1908 0x01,
1909 0x01,
1910 0xFF,
1911 0x02,
1912 0x02,
1913 0x01,
1914 0x03,
1915 ]));
1916 }
1917
1918 #[test]
1919 fn test_ber_decode_definite_short() {
1920 let encoded_data: Vec<u8> = vec![
1921 X690_TAG_CLASS_UNIVERSAL
1922 | 0b0010_0000 | UNIV_TAG_SEQUENCE as u8,
1924 0x06,
1925 0x01,
1926 0x01,
1927 0xFF,
1928 0x02,
1929 0x01,
1930 0x7F,
1931 ];
1932 match BER.decode_from_slice(encoded_data.as_slice()) {
1933 Ok((bytes_read, el)) => {
1934 assert_eq!(bytes_read, 8);
1935 assert_eq!(el.tag.tag_class, TagClass::UNIVERSAL);
1936 assert_eq!(el.tag.tag_number, UNIV_TAG_SEQUENCE);
1937 if let X690Value::Constructed(children) = el.value {
1938 assert_eq!(children.len(), 2);
1939 assert_eq!(children[0].tag.tag_class, TagClass::UNIVERSAL);
1940 assert_eq!(children[1].tag.tag_class, TagClass::UNIVERSAL);
1941 assert_eq!(children[0].tag.tag_number, UNIV_TAG_BOOLEAN);
1942 assert_eq!(children[1].tag.tag_number, UNIV_TAG_INTEGER);
1943 } else {
1944 panic!("Decoded non-constructed.");
1945 }
1946 }
1947 Err(e) => panic!("{}", e),
1948 };
1949 }
1950
1951 #[test]
1952 fn test_ber_decode_indefinite() {
1953 let encoded_data: Vec<u8> = vec![
1954 X690_TAG_CLASS_UNIVERSAL
1955 | 0b0010_0000 | UNIV_TAG_SEQUENCE as u8,
1957 0x80, 0x01,
1959 0x01,
1960 0xFF,
1961 0x02,
1962 0x01,
1963 0x7F,
1964 0x00, 0x00,
1966 ];
1967 match BER.decode_from_slice(encoded_data.as_slice()) {
1968 Ok((bytes_read, el)) => {
1969 assert_eq!(bytes_read, 10);
1970 assert_eq!(el.tag.tag_class, TagClass::UNIVERSAL);
1971 assert_eq!(el.tag.tag_number, UNIV_TAG_SEQUENCE);
1972 if let X690Value::Constructed(children) = el.value {
1973 assert_eq!(children.len(), 2);
1974 assert_eq!(children[0].tag.tag_class, TagClass::UNIVERSAL);
1975 assert_eq!(children[1].tag.tag_class, TagClass::UNIVERSAL);
1976 assert_eq!(children[0].tag.tag_number, UNIV_TAG_BOOLEAN);
1977 assert_eq!(children[1].tag.tag_number, UNIV_TAG_INTEGER);
1978 } else {
1979 panic!("Decoded non-constructed.");
1980 }
1981 }
1982 Err(e) => panic!("{}", e),
1983 };
1984 }
1985
1986 #[test]
1987 fn test_deconstruct_primitive() {
1988 let bytes = Bytes::copy_from_slice(&[0x01, 0x02, 0x03, 0x04]);
1990 let element = X690Element::new(
1991 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_OCTET_STRING),
1992 X690Value::Primitive(bytes.clone()),
1993 );
1994
1995 let result = deconstruct(&element).unwrap();
1996 assert_eq!(result.as_ref(), &[0x01, 0x02, 0x03, 0x04]);
1997 assert!(matches!(result, Cow::Borrowed(_)));
1999 }
2000
2001 #[test]
2002 fn test_deconstruct_constructed_valid() {
2003 let child1 = X690Element::new(
2005 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_OCTET_STRING),
2006 X690Value::Primitive(Bytes::copy_from_slice(&[0x01, 0x02])),
2007 );
2008 let child2 = X690Element::new(
2009 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_OCTET_STRING),
2010 X690Value::Primitive(Bytes::copy_from_slice(&[0x03, 0x04])),
2011 );
2012
2013 let element = X690Element::new(
2014 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_OCTET_STRING),
2015 X690Value::Constructed(Arc::new(vec![child1, child2])),
2016 );
2017
2018 let result = deconstruct(&element).unwrap();
2019 assert_eq!(result.as_ref(), &[0x01, 0x02, 0x03, 0x04]);
2020 assert!(matches!(result, Cow::Owned(_)));
2022 }
2023
2024 #[test]
2025 fn test_deconstruct_constructed_invalid_tag_class() {
2026 let child = X690Element::new(
2028 Tag::new(TagClass::APPLICATION, UNIV_TAG_OCTET_STRING), X690Value::Primitive(Bytes::copy_from_slice(&[0x01, 0x02])),
2030 );
2031
2032 let element = X690Element::new(
2033 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_OCTET_STRING),
2034 X690Value::Constructed(Arc::new(vec![child])),
2035 );
2036
2037 let result = deconstruct(&element);
2038 assert!(result.is_err());
2039 let err = result.unwrap_err();
2040 assert_eq!(err.error_code, ASN1ErrorCode::string_constructed_with_invalid_tagging);
2041 }
2042
2043 #[test]
2044 fn test_deconstruct_constructed_invalid_tag_number() {
2045 let child = X690Element::new(
2047 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_INTEGER), X690Value::Primitive(Bytes::copy_from_slice(&[0x01, 0x02])),
2049 );
2050
2051 let element = X690Element::new(
2052 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_OCTET_STRING),
2053 X690Value::Constructed(Arc::new(vec![child])),
2054 );
2055
2056 let result = deconstruct(&element);
2057 assert!(result.is_err());
2058 let err = result.unwrap_err();
2059 assert_eq!(err.error_code, ASN1ErrorCode::string_constructed_with_invalid_tagging);
2060 }
2061
2062 #[test]
2063 fn test_deconstruct_constructed_nested() {
2064 let grandchild1 = X690Element::new(
2066 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_OCTET_STRING),
2067 X690Value::Primitive(Bytes::copy_from_slice(&[0x01, 0x02])),
2068 );
2069 let grandchild2 = X690Element::new(
2070 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_OCTET_STRING),
2071 X690Value::Primitive(Bytes::copy_from_slice(&[0x03, 0x04])),
2072 );
2073
2074 let child = X690Element::new(
2075 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_OCTET_STRING),
2076 X690Value::Constructed(Arc::new(vec![grandchild1, grandchild2])),
2077 );
2078
2079 let element = X690Element::new(
2080 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_OCTET_STRING),
2081 X690Value::Constructed(Arc::new(vec![child])),
2082 );
2083
2084 let result = deconstruct(&element).unwrap();
2085 assert_eq!(result.as_ref(), &[0x01, 0x02, 0x03, 0x04]);
2086 }
2087
2088 #[test]
2089 fn test_deconstruct_constructed_empty() {
2090 let element = X690Element::new(
2092 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_OCTET_STRING),
2093 X690Value::Constructed(Arc::new(vec![])),
2094 );
2095
2096 let result = deconstruct(&element).unwrap();
2097 let empty: [u8; 0] = [];
2098 assert_eq!(result.as_ref(), &empty);
2099 }
2100
2101 #[test]
2102 fn test_deconstruct_serialized() {
2103 let inner_bytes = Bytes::copy_from_slice(&[0x01, 0x02, 0x03, 0x04]);
2105 let inner_element = X690Element::new(
2106 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_OCTET_STRING),
2107 X690Value::Primitive(inner_bytes),
2108 );
2109
2110 let mut serialized = Vec::new();
2112 x690_write_tlv(&mut serialized, &inner_element).unwrap();
2113
2114 let element = X690Element::new(
2115 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_OCTET_STRING),
2116 X690Value::Serialized(Bytes::copy_from_slice(&serialized)),
2117 );
2118
2119 let result = deconstruct(&element).unwrap();
2120 assert_eq!(result.as_ref(), &[0x01, 0x02, 0x03, 0x04]);
2121 assert!(matches!(result, Cow::Owned(_)));
2123 }
2124
2125 #[test]
2126 fn test_deconstruct_serialized_constructed() {
2127 let child1 = X690Element::new(
2129 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_OCTET_STRING),
2130 X690Value::Primitive(Bytes::copy_from_slice(&[0x01, 0x02])),
2131 );
2132 let child2 = X690Element::new(
2133 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_OCTET_STRING),
2134 X690Value::Primitive(Bytes::copy_from_slice(&[0x03, 0x04])),
2135 );
2136
2137 let inner_element = X690Element::new(
2138 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_OCTET_STRING),
2139 X690Value::Constructed(Arc::new(vec![child1, child2])),
2140 );
2141
2142 let mut serialized = Vec::new();
2144 x690_write_tlv(&mut serialized, &inner_element).unwrap();
2145
2146 let element = X690Element::new(
2147 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_OCTET_STRING),
2148 X690Value::Serialized(Bytes::copy_from_slice(&serialized)),
2149 );
2150
2151 let result = deconstruct(&element).unwrap();
2152 assert_eq!(result.as_ref(), &[0x01, 0x02, 0x03, 0x04]);
2153 }
2154
2155 #[test]
2156 fn test_deconstruct_mixed_constructed() {
2157 let primitive_child = X690Element::new(
2159 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_OCTET_STRING),
2160 X690Value::Primitive(Bytes::copy_from_slice(&[0x01, 0x02])),
2161 );
2162
2163 let grandchild1 = X690Element::new(
2164 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_OCTET_STRING),
2165 X690Value::Primitive(Bytes::copy_from_slice(&[0x03, 0x04])),
2166 );
2167 let grandchild2 = X690Element::new(
2168 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_OCTET_STRING),
2169 X690Value::Primitive(Bytes::copy_from_slice(&[0x05, 0x06])),
2170 );
2171
2172 let constructed_child = X690Element::new(
2173 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_OCTET_STRING),
2174 X690Value::Constructed(Arc::new(vec![grandchild1, grandchild2])),
2175 );
2176
2177 let element = X690Element::new(
2178 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_OCTET_STRING),
2179 X690Value::Constructed(Arc::new(vec![primitive_child, constructed_child])),
2180 );
2181
2182 let result = deconstruct(&element).unwrap();
2183 assert_eq!(result.as_ref(), &[0x01, 0x02, 0x03, 0x04, 0x05, 0x06]);
2184 }
2185
2186 #[test]
2187 fn test_deconstruct_large_data() {
2188 let mut children = Vec::new();
2190 let mut expected = Vec::new();
2191
2192 for i in 0..100 {
2193 let data = vec![i as u8, (i + 1) as u8, (i + 2) as u8];
2194 expected.extend_from_slice(&data);
2195
2196 let child = X690Element::new(
2197 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_OCTET_STRING),
2198 X690Value::Primitive(Bytes::copy_from_slice(&data)),
2199 );
2200 children.push(child);
2201 }
2202
2203 let element = X690Element::new(
2204 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_OCTET_STRING),
2205 X690Value::Constructed(Arc::new(children)),
2206 );
2207
2208 let result = deconstruct(&element).unwrap();
2209 assert_eq!(result.as_ref(), &expected);
2210 }
2211
2212 #[test]
2213 fn test_deconstruct_serialized_invalid_data() {
2214 let element = X690Element::new(
2216 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_OCTET_STRING),
2217 X690Value::Serialized(Bytes::copy_from_slice(&[0x01, 0x02, 0x03])), );
2219
2220 let result = deconstruct(&element);
2221 assert!(result.is_err());
2222 }
2223
2224 #[test]
2225 fn test_element_equality_1() {
2226 let element1 = X690Element::new(
2227 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_OCTET_STRING),
2228 X690Value::Primitive(Bytes::copy_from_slice(&[0x01, 0x02])),
2229 );
2230 let element2 = X690Element::new(
2231 Tag::new(TagClass::UNIVERSAL, UNIV_TAG_OCTET_STRING),
2232 X690Value::Primitive(Bytes::copy_from_slice(&[0x01, 0x02])),
2233 );
2234 assert_eq!(element1, element2);
2235 }
2236
2237}