diff --git a/der/src/tag/class.rs b/der/src/tag/class.rs index 2a3bba533..144118118 100644 --- a/der/src/tag/class.rs +++ b/der/src/tag/class.rs @@ -2,19 +2,30 @@ use core::fmt; +/// `UNIVERSAL`: built-in types whose meaning is the same in all +/// applications. +pub const CLASS_UNIVERSAL: u8 = 0b00000000; +/// `APPLICATION`: types whose meaning is specific to an application. +pub const CLASS_APPLICATION: u8 = 0b01000000; +/// `CONTEXT-SPECIFIC`: types whose meaning is specific to a given +/// structured type. +pub const CLASS_CONTEXT_SPECIFIC: u8 = 0b10000000; +/// `PRIVATE`: types whose meaning is specific to a given enterprise. +pub const CLASS_PRIVATE: u8 = 0b11000000; + /// Class of an ASN.1 tag. #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] #[repr(u8)] pub enum Class { /// `UNIVERSAL`: built-in types whose meaning is the same in all /// applications. - Universal = 0b00000000, + Universal = CLASS_UNIVERSAL, /// `APPLICATION`: types whose meaning is specific to an application, /// /// Types in two different applications may have the same /// application-specific tag and different meanings. - Application = 0b01000000, + Application = CLASS_APPLICATION, /// `CONTEXT-SPECIFIC`: types whose meaning is specific to a given /// structured type. @@ -23,10 +34,10 @@ pub enum Class { /// with the same underlying tag within the context of a given structured /// type, and component types in two different structured types may have /// the same tag and different meanings. - ContextSpecific = 0b10000000, + ContextSpecific = CLASS_CONTEXT_SPECIFIC, /// `PRIVATE`: types whose meaning is specific to a given enterprise. - Private = 0b11000000, + Private = CLASS_PRIVATE, } impl fmt::Display for Class { @@ -39,3 +50,26 @@ impl fmt::Display for Class { }) } } + +impl Class { + /// Returns class as 2 most-significant bits (mask 0b11000000) + pub const fn bits(&self) -> u8 { + *self as u8 + } + + /// Returns class extracted from 2 most-significant bits (mask 0b11000000) + pub const fn from_bits(bits: u8) -> Self { + match (bits >> 6) & 0b11 { + 0b00 => Class::Universal, + 0b01 => Class::Application, + 0b10 => Class::ContextSpecific, + 0b11 => Class::Private, + _ => unreachable!(), + } + } +} +impl From for Class { + fn from(value: u8) -> Self { + Class::from_bits(value) + } +} diff --git a/der/tests/derive.rs b/der/tests/derive.rs index d7a8fc87c..d42f320bf 100644 --- a/der/tests/derive.rs +++ b/der/tests/derive.rs @@ -499,7 +499,7 @@ mod sequence { pub owned_optional_implicit_bytes: Option>, #[asn1( - type = "OCTET STRING", + type = "BIT STRING", context_specific = "6", optional = "true", tag_mode = "EXPLICIT"