///|
/// Returns the content octets of this value, requiring a primitive universal
/// value with the given tag number.
fn expect_content(value : Der, number : Int) -> BytesView raise DerError {
match value {
Primitive(tag, content) => {
if tag.cls != Universal || tag.number != number {
raise ExpectedTag(
Tag::new(Universal, number).to_string(),
tag.to_string(),
)
}
content
}
Constructed(tag, _) =>
raise InvalidValue(
"expected " +
Tag::new(Universal, number).to_string() +
", got " +
tag.to_string(),
)
}
}
///|
/// Decodes this value as a BOOLEAN.
pub fn Der::as_boolean(self : Der) -> Bool raise DerError {
decode_boolean(expect_content(self, TAG_BOOLEAN))
}
///|
/// Decodes this value as an INTEGER.
pub fn Der::as_integer(self : Der) -> @bigint.BigInt raise DerError {
decode_integer(expect_content(self, TAG_INTEGER))
}
///|
/// Checks that this value is a NULL.
pub fn Der::as_null(self : Der) -> Unit raise DerError {
decode_null(expect_content(self, TAG_NULL))
}
///|
/// Decodes this value as an OBJECT IDENTIFIER.
pub fn Der::as_object_identifier(self : Der) -> ObjectIdentifier raise DerError {
decode_object_identifier(expect_content(self, TAG_OBJECT_IDENTIFIER))
}
///|
/// Returns a view of this value's OCTET STRING content.
pub fn Der::as_octet_string_view(self : Der) -> BytesView raise DerError {
expect_content(self, TAG_OCTET_STRING)
}
///|
/// Copies this value's OCTET STRING content into a fresh buffer.
pub fn Der::as_octet_string(self : Der) -> Bytes raise DerError {
@buffer.from_bytes(self.as_octet_string_view()).to_bytes()
}
///|
/// Decodes this value as a BIT STRING.
pub fn Der::as_bit_string(self : Der) -> (Int, Bytes) raise DerError {
decode_bit_string(expect_content(self, TAG_BIT_STRING))
}
///|
/// Decodes this value as a UTF8String.
pub fn Der::as_utf8_string(self : Der) -> String raise DerError {
decode_utf8_string(expect_content(self, TAG_UTF8_STRING))
}
///|
/// Decodes this value as a time: `UTCTime` or `GeneralizedTime`.
pub fn Der::as_time(self : Der) -> Asn1Time raise DerError {
match self {
Primitive(tag, content) =>
match tag.number {
TAG_UTC_TIME => decode_utc_time(content)
TAG_GENERALIZED_TIME => decode_generalized_time(content)
_ =>
raise InvalidValue(
"expected UTCTime or GeneralizedTime, got " + tag.to_string(),
)
}
Constructed(tag, _) =>
raise InvalidValue("expected a time, got " + tag.to_string())
}
}
///|
/// Decodes this value as a string, dispatching on the universal tag number.
///
/// `TeletexString` and `T61String` are not decoded; their content is usually
/// Latin-1, so callers should read it as bytes and convert explicitly.
pub fn Der::as_string(self : Der) -> String raise DerError {
match self {
Primitive(tag, content) =>
match tag.number {
TAG_UTF8_STRING => decode_utf8_string(content)
TAG_PRINTABLE_STRING => decode_printable_string(content)
TAG_IA5_STRING => decode_ia5_string(content)
TAG_NUMERIC_STRING => decode_numeric_string(content)
TAG_VISIBLE_STRING => decode_visible_string(content)
TAG_BMP_STRING => decode_bmp_string(content)
TAG_UNIVERSAL_STRING => decode_universal_string(content)
_ =>
raise InvalidValue("expected a string type, got " + tag.to_string())
}
Constructed(tag, _) =>
raise InvalidValue("expected a string, got " + tag.to_string())
}
}
///|
/// Returns the children of this value, accepting SEQUENCE and SET.
pub fn Der::as_sequence(self : Der) -> Array[Der] raise DerError {
match self {
Constructed(tag, children) =>
if tag.cls == Universal &&
(tag.number == TAG_SEQUENCE || tag.number == TAG_SET) {
children
} else {
raise InvalidValue("expected SEQUENCE or SET, got " + tag.to_string())
}
Primitive(tag, _) =>
raise InvalidValue("expected SEQUENCE or SET, got " + tag.to_string())
}
}
///|
/// Returns the single child of an explicitly tagged value (X.690, 8.14.3).
pub fn Der::as_explicit(self : Der, number : Int) -> Der raise DerError {
match self {
Constructed(tag, children) => {
if tag.cls != ContextSpecific || tag.number != number {
raise ExpectedTag(
Tag::new(ContextSpecific, number, constructed=true).to_string(),
tag.to_string(),
)
}
match children {
[child] => child
_ =>
raise InvalidValue(
"expected a single child inside " + tag.to_string(),
)
}
}
Primitive(tag, _) =>
raise InvalidValue(
"expected an explicitly tagged value, got " + tag.to_string(),
)
}
}