1#![doc = include_str!("../README.md")]
2#![allow(non_camel_case_types)]
3#![allow(non_upper_case_globals)]
5
6pub mod bitstring;
7pub mod constants;
8pub mod construction;
9pub mod date;
10pub mod datetime;
11pub mod display;
12pub mod duration;
13pub mod error;
14pub mod external;
15pub mod gentime;
16pub mod oid;
17pub mod roid;
18pub mod strings;
19pub mod tag;
20pub mod time_of_day;
21pub mod utctime;
22pub mod utils;
23
24pub use bitstring::*;
25pub use constants::*;
26pub use construction::*;
27pub use date::*;
28pub use datetime::*;
29pub use display::*;
30pub use duration::*;
31pub use error::*;
32pub use external::*;
33pub use gentime::*;
34pub use oid::*;
35pub use roid::*;
36pub use strings::*;
37pub use tag::*;
38pub use time_of_day::*;
39pub use utctime::*;
40pub use utils::*;
41
42pub const TRUE: bool = true;
44
45pub const FALSE: bool = false;
47
48pub type ByteSlice<'a> = &'a [u8];
50
51pub type OPTIONAL<T> = Option<T>;
53
54#[derive(Debug, Hash, Eq, PartialEq, Clone, Copy)]
56pub struct UTCOffset {
57 pub hour: i8,
60 pub minute: u8,
62}
63
64impl UTCOffset {
65
66 #[inline]
68 pub const fn new(hour: i8, minute: u8) -> Self {
69 UTCOffset { hour, minute }
70 }
71
72 #[inline]
75 pub const fn is_zero(&self) -> bool {
76 self.hour == 0 && self.minute == 0
77 }
78
79 #[inline]
81 pub const fn utc() -> Self {
82 UTCOffset{ hour: 0, minute: 0 }
83 }
84}
85
86impl Default for UTCOffset {
87
88 #[inline]
90 fn default() -> Self {
91 UTCOffset::utc()
92 }
93}
94
95#[derive(Debug, Hash, Eq, PartialEq, Clone, Copy)]
97#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
98pub struct FractionalPart {
99 pub number_of_digits: u8,
101
102 pub fractional_value: u32,
106}
107
108impl FractionalPart {
109
110 #[inline]
112 pub const fn new(number_of_digits: u8, fractional_value: u32) -> Self {
113 FractionalPart {
114 number_of_digits,
115 fractional_value,
116 }
117 }
118}
119
120pub type BOOLEAN = bool;
124
125pub type INTEGER = Vec<u8>;
127
128pub type BIT_INDEX = usize;
130
131pub type OCTET_STRING = Vec<u8>;
133
134pub type NULL = ();
136
137pub type OID_ARC = u32;
139
140pub type ObjectDescriptor = GraphicString;
147
148pub type EXTERNAL = crate::external::External;
150
151pub type REAL = f64;
153
154pub type ENUMERATED = i64;
156
157pub type EMBEDDED_PDV = crate::external::EmbeddedPDV;
159
160pub type UTF8String = String;
162
163pub type TIME = String;
165pub type SEQUENCE = Vec<ASN1Value>;
169
170pub type SEQUENCE_OF<T> = Vec<T>;
172
173pub type SET = Vec<ASN1Value>;
175
176pub type SET_OF<T> = Vec<T>;
178
179pub type NumericString = String;
181
182pub type PrintableString = String;
184
185pub type T61String = Vec<u8>;
187
188pub type TeletexString = T61String;
190
191pub type VideotexString = Vec<u8>;
193
194pub type IA5String = String;
196
197pub type GraphicString = String;
199
200pub type VisibleString = String;
202
203pub type GeneralString = String;
205
206#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, Default)]
211pub struct UniversalString(pub Vec<u32>);
212
213pub type CHARACTER_STRING = crate::external::CharacterString;
218
219#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, Default)]
226pub struct BMPString(pub Vec<u16>);
227
228pub type DURATION = crate::duration::DURATION_EQUIVALENT;
234
235pub type OID_IRI = String;
237pub type RELATIVE_OID_IRI = String;
239
240pub type INSTANCE_OF = crate::external::InstanceOf;
251
252#[derive(Debug, Clone, PartialEq, Eq, Hash)]
270pub struct TYPE_IDENTIFIER {
271 pub id: OBJECT_IDENTIFIER,
273}
274
275#[derive(Debug, Clone, PartialEq)]
280pub enum ASN1Value {
281 BitStringValue(crate::bitstring::BIT_STRING),
283 BooleanValue(BOOLEAN),
284 ChoiceValue(Box<ASN1Value>),
285 EmbeddedPDVValue(EMBEDDED_PDV),
287 EnumeratedValue(ENUMERATED),
288 ExternalValue(EXTERNAL),
289 InstanceOfValue(INSTANCE_OF),
290 IntegerValue(INTEGER),
291 IRIValue(OID_IRI),
292 NullValue,
293 ObjectIdentifierValue(OBJECT_IDENTIFIER),
294 ObjectDescriptor(ObjectDescriptor),
295 OctetStringValue(OCTET_STRING),
296 RealValue(REAL),
297 RelativeIRIValue(RELATIVE_OID_IRI),
298 RelativeOIDValue(crate::roid::RELATIVE_OID),
299 SequenceValue(SEQUENCE),
300 SequenceOfValue(SEQUENCE_OF<ASN1Value>),
301 SetValue(SET),
302 SetOfValue(SET_OF<ASN1Value>),
303 UnrestrictedCharacterStringValue(CHARACTER_STRING),
305 BMPString(BMPString),
307 GeneralString(GeneralString),
308 GraphicString(GraphicString),
309 IA5String(IA5String),
310 ISO646String(VisibleString), NumericString(NumericString),
312 PrintableString(PrintableString),
313 TeletexString(T61String), T61String(T61String),
315 UniversalString(UniversalString),
316 UTF8String(UTF8String),
317 VideotexString(VideotexString),
318 VisibleString(VisibleString),
319 TaggedValue(TaggedASN1Value),
321 TimeValue(TIME),
322 UTCTime(crate::utctime::UTCTime),
323 GeneralizedTime(GeneralizedTime),
324 DATE(DATE),
325 TIME_OF_DAY(TIME_OF_DAY),
326 DATE_TIME(crate::datetime::DATE_TIME),
327 DURATION(DURATION),
328
329 UnknownBytes(std::sync::Arc<Vec<u8>>),
333}
334
335impl ASN1Value {
336
337 pub fn tag_number (&self) -> TagNumber {
339 match self {
340 ASN1Value::BitStringValue(_) => UNIV_TAG_BIT_STRING,
341 ASN1Value::BooleanValue(_) => UNIV_TAG_BOOLEAN,
342 ASN1Value::ChoiceValue(v) => v.tag_number(),
343 ASN1Value::EmbeddedPDVValue(_) => UNIV_TAG_EMBEDDED_PDV,
344 ASN1Value::EnumeratedValue(_) => UNIV_TAG_ENUMERATED,
345 ASN1Value::ExternalValue(_) => UNIV_TAG_EXTERNAL,
346 ASN1Value::InstanceOfValue(_) => UNIV_TAG_INSTANCE_OF,
347 ASN1Value::IntegerValue(_) => UNIV_TAG_INTEGER,
348 ASN1Value::IRIValue(_) => UNIV_TAG_OID_IRI,
349 ASN1Value::NullValue => UNIV_TAG_NULL,
350 ASN1Value::ObjectIdentifierValue(_) => UNIV_TAG_OBJECT_IDENTIFIER,
351 ASN1Value::ObjectDescriptor(_) => UNIV_TAG_OBJECT_DESCRIPTOR,
352 ASN1Value::OctetStringValue(_) => UNIV_TAG_OCTET_STRING,
353 ASN1Value::RealValue(_) => UNIV_TAG_REAL,
354 ASN1Value::RelativeIRIValue(_) => UNIV_TAG_RELATIVE_OID_IRI,
355 ASN1Value::RelativeOIDValue(_) => UNIV_TAG_RELATIVE_OID,
356 ASN1Value::SequenceValue(_) => UNIV_TAG_SEQUENCE,
357 ASN1Value::SequenceOfValue(_) => UNIV_TAG_SEQUENCE_OF,
358 ASN1Value::SetValue(_) => UNIV_TAG_SET,
359 ASN1Value::SetOfValue(_) => UNIV_TAG_SET_OF,
360 ASN1Value::UnrestrictedCharacterStringValue(_) => UNIV_TAG_CHARACTER_STRING,
361 ASN1Value::BMPString(_) => UNIV_TAG_BMP_STRING,
362 ASN1Value::GeneralString(_) => UNIV_TAG_GENERAL_STRING,
363 ASN1Value::GraphicString(_) => UNIV_TAG_GRAPHIC_STRING,
364 ASN1Value::IA5String(_) => UNIV_TAG_IA5_STRING,
365 ASN1Value::ISO646String(_) => UNIV_TAG_VISIBLE_STRING,
366 ASN1Value::NumericString(_) => UNIV_TAG_NUMERIC_STRING,
367 ASN1Value::PrintableString(_) => UNIV_TAG_PRINTABLE_STRING,
368 ASN1Value::TeletexString(_) => UNIV_TAG_T61_STRING,
369 ASN1Value::T61String(_) => UNIV_TAG_T61_STRING,
370 ASN1Value::UniversalString(_) => UNIV_TAG_UNIVERSAL_STRING,
371 ASN1Value::UTF8String(_) => UNIV_TAG_UTF8_STRING,
372 ASN1Value::VideotexString(_) => UNIV_TAG_VIDEOTEX_STRING,
373 ASN1Value::VisibleString(_) => UNIV_TAG_VISIBLE_STRING,
374 ASN1Value::TaggedValue(v) => v.tag.tag_number,
375 ASN1Value::TimeValue(_) => UNIV_TAG_TIME,
376 ASN1Value::UTCTime(_) => UNIV_TAG_UTC_TIME,
377 ASN1Value::GeneralizedTime(_) => UNIV_TAG_GENERALIZED_TIME,
378 ASN1Value::DATE(_) => UNIV_TAG_DATE,
379 ASN1Value::TIME_OF_DAY(_) => UNIV_TAG_TIME_OF_DAY,
380 ASN1Value::DATE_TIME(_) => UNIV_TAG_DATE_TIME,
381 ASN1Value::DURATION(_) => UNIV_TAG_DURATION,
382 ASN1Value::UnknownBytes(_) => UNIV_TAG_OCTET_STRING,
384 }
385 }
386
387 pub fn tag (&self) -> Tag {
388 match self {
389 ASN1Value::TaggedValue(v) => v.tag,
390 _ => Tag::new(TagClass::UNIVERSAL, self.tag_number()),
391 }
392 }
393
394}
395pub const UNIV_TAG_END_OF_CONTENT: TagNumber = 0;
397pub const UNIV_TAG_BOOLEAN: TagNumber = 1;
399pub const UNIV_TAG_INTEGER: TagNumber = 2;
401pub const UNIV_TAG_BIT_STRING: TagNumber = 3;
403pub const UNIV_TAG_OCTET_STRING: TagNumber = 4;
405pub const UNIV_TAG_NULL: TagNumber = 5;
407pub const UNIV_TAG_OBJECT_IDENTIFIER: TagNumber = 6;
409pub const UNIV_TAG_OBJECT_DESCRIPTOR: TagNumber = 7;
411pub const UNIV_TAG_EXTERNAL: TagNumber = 8;
413pub const UNIV_TAG_INSTANCE_OF: TagNumber = UNIV_TAG_EXTERNAL;
415pub const UNIV_TAG_REAL: TagNumber = 9;
417pub const UNIV_TAG_ENUMERATED: TagNumber = 10;
419pub const UNIV_TAG_EMBEDDED_PDV: TagNumber = 11;
421pub const UNIV_TAG_UTF8_STRING: TagNumber = 12;
423pub const UNIV_TAG_RELATIVE_OID: TagNumber = 13;
425pub const UNIV_TAG_TIME: TagNumber = 14;
427pub const UNIV_TAG_RESERVED_15: TagNumber = 15;
429pub const UNIV_TAG_SEQUENCE: TagNumber = 16;
431pub const UNIV_TAG_SEQUENCE_OF: TagNumber = UNIV_TAG_SEQUENCE;
433pub const UNIV_TAG_SET: TagNumber = 17;
435pub const UNIV_TAG_SET_OF: TagNumber = UNIV_TAG_SET;
437pub const UNIV_TAG_NUMERIC_STRING: TagNumber = 18;
439pub const UNIV_TAG_PRINTABLE_STRING: TagNumber = 19;
441pub const UNIV_TAG_T61_STRING: TagNumber = 20;
443pub const UNIV_TAG_VIDEOTEX_STRING: TagNumber = 21;
445pub const UNIV_TAG_IA5_STRING: TagNumber = 22;
447pub const UNIV_TAG_UTC_TIME: TagNumber = 23;
449pub const UNIV_TAG_GENERALIZED_TIME: TagNumber = 24;
451pub const UNIV_TAG_GRAPHIC_STRING: TagNumber = 25;
453pub const UNIV_TAG_VISIBLE_STRING: TagNumber = 26;
455pub const UNIV_TAG_GENERAL_STRING: TagNumber = 27;
457pub const UNIV_TAG_UNIVERSAL_STRING: TagNumber = 28;
459pub const UNIV_TAG_CHARACTER_STRING: TagNumber = 29;
461pub const UNIV_TAG_BMP_STRING: TagNumber = 30;
463pub const UNIV_TAG_DATE: TagNumber = 31;
465pub const UNIV_TAG_TIME_OF_DAY: TagNumber = 32;
467pub const UNIV_TAG_DATE_TIME: TagNumber = 33;
469pub const UNIV_TAG_DURATION: TagNumber = 34;
471pub const UNIV_TAG_OID_IRI: TagNumber = 35;
473pub const UNIV_TAG_RELATIVE_OID_IRI: TagNumber = 36;
475
476pub trait ASN1Codec {
478
479 fn transfer_syntax_oid (&self) -> OBJECT_IDENTIFIER;
481
482 fn transfer_syntax_oid_iri (&self) -> Option<OID_IRI> {
484 None
485 }
486
487}
488
489pub trait ISO8601Timestampable {
491
492 fn to_iso_8601_string (&self) -> String;
494
495}
496
497pub trait X690Validate {
509
510 fn validate_x690_encoding (content_octets: &[u8]) -> ASN1Result<()>;
513
514}
515
516#[derive(Debug, Clone)]
519pub struct NamedType <'a, Type = ASN1Value> {
520
521 pub identifier: &'a str,
523
524 pub value: Type,
526}
527
528pub trait X690KnownSize {
544
545 fn x690_size (&self) -> usize;
548
549}
550
551#[macro_export]
555macro_rules! octs {
556 () => {
557 std::vec![]
558 };
559 ( $( $x:expr ),+ ) => {
560 std::vec![$($x,)*]
561 };
562}
563
564
565#[cfg(test)]
566mod tests {
567
568 #[test]
569 fn test_octs_macro () {
570 let octets = octs!(1,3,6,4,1);
571 assert_eq!(octets.len(), 5);
572 }
573
574}