#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, string::ToString, vec::Vec};
use core::fmt;
use crate::der::decoder::Decoder;
use crate::types::oid::ObjectIdentifier;
use crate::types::primitive::{Boolean, Integer, Null, Real};
use crate::types::string::{
BmpString, GeneralString, NumericString, TeletexString, UniversalString, VisibleString,
};
use crate::types::time::{GeneralizedTime, UtcTime};
#[derive(Debug, Clone, PartialEq)]
pub enum Element<'a> {
Boolean(Boolean),
Integer(Integer),
BitString(crate::types::string::BitStringRef<'a>),
OctetString(crate::types::string::OctetStringRef<'a>),
Null(Null),
Real(Real),
ObjectIdentifier(ObjectIdentifier),
Utf8String(crate::types::string::Utf8StringRef<'a>),
PrintableString(crate::types::string::PrintableStringRef<'a>),
IA5String(crate::types::string::IA5StringRef<'a>),
UtcTime(UtcTime),
GeneralizedTime(GeneralizedTime),
Sequence(Sequence<'a>),
Set(Set<'a>),
Tagged(crate::Tag, Box<Element<'a>>),
NumericString(NumericString),
TeletexString(TeletexString),
VisibleString(VisibleString),
GeneralString(GeneralString),
UniversalString(UniversalString),
BmpString(BmpString),
Raw(crate::Tag, &'a [u8]),
}
enum SeqRepr<'a> {
Borrowed {
raw: &'a [u8],
encoding: crate::Encoding,
},
OwnedBytes {
raw: Vec<u8>,
encoding: crate::Encoding,
},
Owned(Vec<Element<'a>>),
}
impl<'a> Clone for SeqRepr<'a> {
fn clone(&self) -> Self {
match self {
SeqRepr::Borrowed { raw, encoding } => SeqRepr::Borrowed {
raw,
encoding: *encoding,
},
SeqRepr::OwnedBytes { raw, encoding } => SeqRepr::OwnedBytes {
raw: raw.clone(),
encoding: *encoding,
},
SeqRepr::Owned(v) => SeqRepr::Owned(v.clone()),
}
}
}
impl<'a> SeqRepr<'a> {
fn raw_bytes(&self) -> Option<&[u8]> {
match self {
SeqRepr::Borrowed { raw, .. } => Some(raw),
SeqRepr::OwnedBytes { raw, .. } => Some(raw.as_slice()),
SeqRepr::Owned(_) => None,
}
}
}
impl<'a> PartialEq for SeqRepr<'a> {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(SeqRepr::Borrowed { raw: r1, .. }, SeqRepr::Borrowed { raw: r2, .. }) => r1 == r2,
(SeqRepr::OwnedBytes { raw: r1, .. }, SeqRepr::OwnedBytes { raw: r2, .. }) => r1 == r2,
(SeqRepr::Owned(a), SeqRepr::Owned(b)) => a == b,
_ => false, }
}
}
#[inline]
fn decode_one_from_slice<'a>(
remaining: &mut &'a [u8],
encoding: crate::Encoding,
) -> Option<crate::Result<Element<'a>>> {
if remaining.is_empty() {
return None;
}
let mut decoder = crate::der::decoder::Decoder::new(remaining, encoding);
use crate::traits::Decode;
let result = Element::decode(&mut decoder);
match result {
Ok(el) => {
let consumed = decoder.position();
*remaining = &remaining[consumed..];
Some(Ok(el))
}
Err(e) => {
*remaining = &[];
Some(Err(e))
}
}
}
pub enum SeqIter<'data, 'seq> {
Raw(Decoder<'data>),
Owned(core::slice::Iter<'seq, Element<'data>>),
}
impl<'data, 'seq> Iterator for SeqIter<'data, 'seq> {
type Item = crate::Result<Element<'data>>;
fn next(&mut self) -> Option<Self::Item> {
match self {
SeqIter::Raw(decoder) => {
if decoder.is_empty() {
None
} else {
use crate::traits::Decode;
let result = Element::decode(decoder);
if result.is_err() {
decoder.exhaust();
}
Some(result)
}
}
SeqIter::Owned(iter) => iter.next().map(|el| Ok(el.clone())),
}
}
}
pub enum SeqIntoIter<'a> {
Raw(Decoder<'a>),
OwnedBytes {
raw: Vec<u8>,
pos: usize,
encoding: crate::Encoding,
},
Owned(std::vec::IntoIter<Element<'a>>),
}
impl<'a> Iterator for SeqIntoIter<'a> {
type Item = crate::Result<Element<'a>>;
fn next(&mut self) -> Option<Self::Item> {
match self {
SeqIntoIter::Raw(decoder) => {
if decoder.is_empty() {
None
} else {
use crate::traits::Decode;
let result = Element::decode(decoder);
if result.is_err() {
decoder.exhaust();
}
Some(result)
}
}
SeqIntoIter::OwnedBytes { raw, pos, encoding } => {
if *pos >= raw.len() {
return None;
}
let mut remaining: &'a [u8] = unsafe {
core::slice::from_raw_parts(raw.as_ptr().add(*pos), raw.len() - *pos)
};
let result = decode_one_from_slice(&mut remaining, *encoding);
*pos = raw.len() - remaining.len();
result
}
SeqIntoIter::Owned(iter) => iter.next().map(Ok),
}
}
}
pub struct Sequence<'a> {
repr: SeqRepr<'a>,
}
impl<'a> Sequence<'a> {
pub fn new() -> Self {
Self {
repr: SeqRepr::Owned(Vec::new()),
}
}
pub fn from_vec(v: Vec<Element<'a>>) -> Self {
Self {
repr: SeqRepr::Owned(v),
}
}
pub(crate) fn from_raw(raw: &'a [u8], encoding: crate::Encoding) -> Self {
Self {
repr: SeqRepr::Borrowed { raw, encoding },
}
}
pub(crate) fn from_owned_bytes(raw: Vec<u8>, encoding: crate::Encoding) -> Self {
Self {
repr: SeqRepr::OwnedBytes { raw, encoding },
}
}
pub fn push(&mut self, el: Element<'a>) {
match &mut self.repr {
SeqRepr::Owned(v) => v.push(el),
SeqRepr::Borrowed { .. } | SeqRepr::OwnedBytes { .. } => {
panic!("cannot push to a borrowed Sequence")
}
}
}
pub fn is_empty(&self) -> bool {
match &self.repr {
SeqRepr::Borrowed { raw, .. } => raw.is_empty(),
SeqRepr::OwnedBytes { raw, .. } => raw.is_empty(),
SeqRepr::Owned(v) => v.is_empty(),
}
}
pub fn iter(&self) -> SeqIter<'a, '_> {
match &self.repr {
SeqRepr::Borrowed { raw, encoding } => SeqIter::Raw(Decoder::new(raw, *encoding)),
SeqRepr::OwnedBytes { raw, encoding } => {
let slice: &'a [u8] =
unsafe { core::slice::from_raw_parts(raw.as_ptr(), raw.len()) };
SeqIter::Raw(Decoder::new(slice, *encoding))
}
SeqRepr::Owned(v) => SeqIter::Owned(v.iter()),
}
}
pub fn into_elements(self) -> crate::Result<Vec<Element<'a>>> {
match self.repr {
SeqRepr::Owned(v) => Ok(v),
SeqRepr::Borrowed { raw, encoding } => {
let mut decoder = crate::der::decoder::Decoder::new(raw, encoding);
let mut out = Vec::new();
while !decoder.is_empty() {
use crate::traits::Decode;
out.push(Element::decode(&mut decoder)?);
}
Ok(out)
}
SeqRepr::OwnedBytes { raw, encoding } => {
let slice: &'a [u8] =
unsafe { core::slice::from_raw_parts(raw.as_ptr(), raw.len()) };
let mut decoder = crate::der::decoder::Decoder::new(slice, encoding);
let mut out = Vec::new();
while !decoder.is_empty() {
use crate::traits::Decode;
out.push(Element::decode(&mut decoder)?);
}
Ok(out)
}
}
}
}
impl<'a> Default for Sequence<'a> {
fn default() -> Self {
Self::new()
}
}
impl<'a> Clone for Sequence<'a> {
fn clone(&self) -> Self {
Sequence {
repr: self.repr.clone(),
}
}
}
impl<'a> fmt::Debug for Sequence<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.repr {
SeqRepr::Borrowed { raw, .. } => {
write!(f, "Sequence::Borrowed({} bytes)", raw.len())
}
SeqRepr::OwnedBytes { raw, .. } => {
write!(f, "Sequence::OwnedBytes({} bytes)", raw.len())
}
SeqRepr::Owned(v) => f.debug_list().entries(v.iter()).finish(),
}
}
}
impl<'a> PartialEq for Sequence<'a> {
fn eq(&self, other: &Self) -> bool {
match (self.repr.raw_bytes(), other.repr.raw_bytes()) {
(Some(a), Some(b)) => a == b,
_ => match (&self.repr, &other.repr) {
(SeqRepr::Owned(a), SeqRepr::Owned(b)) => a == b,
_ => {
let a: crate::Result<Vec<_>> = self.iter().collect();
let b: crate::Result<Vec<_>> = other.iter().collect();
a.ok() == b.ok()
}
},
}
}
}
impl<'a> IntoIterator for Sequence<'a> {
type Item = crate::Result<Element<'a>>;
type IntoIter = SeqIntoIter<'a>;
fn into_iter(self) -> Self::IntoIter {
match self.repr {
SeqRepr::Borrowed { raw, encoding } => SeqIntoIter::Raw(Decoder::new(raw, encoding)),
SeqRepr::OwnedBytes { raw, encoding } => SeqIntoIter::OwnedBytes {
raw,
pos: 0,
encoding,
},
SeqRepr::Owned(v) => SeqIntoIter::Owned(v.into_iter()),
}
}
}
impl<'a> crate::traits::Decode<'a> for Sequence<'a> {
fn decode(decoder: &mut crate::der::decoder::Decoder<'a>) -> crate::Result<Self> {
use crate::tag::TAG_SEQUENCE;
let tag = crate::Tag::universal_constructed(TAG_SEQUENCE);
let read_tag = decoder.read_tag()?;
if read_tag != tag {
return Err(crate::Error::UnexpectedTag {
position: decoder.position(),
expected: tag,
actual: read_tag,
});
}
decode_seq_content(decoder)
}
}
impl<'a> crate::traits::Encode for Sequence<'a> {
fn encode(&self, encoder: &mut crate::der::encoder::Encoder) -> crate::Result<()> {
use crate::tag::TAG_SEQUENCE;
let tag = crate::Tag::universal_constructed(TAG_SEQUENCE);
if let Some(raw) = self.repr.raw_bytes() {
encoder.write_tag(tag)?;
encoder.write_length(raw.len())?;
encoder.write_bytes(raw);
return Ok(());
}
let SeqRepr::Owned(elements) = &self.repr else {
unreachable!()
};
let mut constructed = encoder.start_constructed(tag)?;
for el in elements {
constructed.encode(el)?;
}
Ok(())
}
fn encoded_len(&self) -> crate::Result<usize> {
use crate::tag::TAG_SEQUENCE;
let tag_len = crate::Tag::universal_constructed(TAG_SEQUENCE).encoded_len();
if let Some(raw) = self.repr.raw_bytes() {
let length_len = crate::Length::Definite(raw.len()).encoded_len()?;
return Ok(tag_len + length_len + raw.len());
}
let SeqRepr::Owned(elements) = &self.repr else {
unreachable!()
};
let mut content_len = 0;
for el in elements {
content_len += el.encoded_len()?;
}
let length_len = crate::Length::Definite(content_len).encoded_len()?;
Ok(tag_len + length_len + content_len)
}
}
impl<'a> crate::traits::Tagged for Sequence<'a> {
fn tag() -> crate::Tag {
crate::Tag::universal_constructed(crate::tag::TAG_SEQUENCE)
}
}
pub struct Set<'a> {
repr: SeqRepr<'a>,
}
impl<'a> Set<'a> {
pub fn new() -> Self {
Self {
repr: SeqRepr::Owned(Vec::new()),
}
}
pub fn from_vec(v: Vec<Element<'a>>) -> Self {
Self {
repr: SeqRepr::Owned(v),
}
}
pub(crate) fn from_raw(raw: &'a [u8], encoding: crate::Encoding) -> Self {
Self {
repr: SeqRepr::Borrowed { raw, encoding },
}
}
pub(crate) fn from_owned_bytes(raw: Vec<u8>, encoding: crate::Encoding) -> Self {
Self {
repr: SeqRepr::OwnedBytes { raw, encoding },
}
}
pub fn push(&mut self, el: Element<'a>) {
match &mut self.repr {
SeqRepr::Owned(v) => v.push(el),
SeqRepr::Borrowed { .. } | SeqRepr::OwnedBytes { .. } => {
panic!("cannot push to a borrowed Set")
}
}
}
pub fn is_empty(&self) -> bool {
match &self.repr {
SeqRepr::Borrowed { raw, .. } => raw.is_empty(),
SeqRepr::OwnedBytes { raw, .. } => raw.is_empty(),
SeqRepr::Owned(v) => v.is_empty(),
}
}
pub fn iter(&self) -> SeqIter<'a, '_> {
match &self.repr {
SeqRepr::Borrowed { raw, encoding } => SeqIter::Raw(Decoder::new(raw, *encoding)),
SeqRepr::OwnedBytes { raw, encoding } => {
let slice: &'a [u8] =
unsafe { core::slice::from_raw_parts(raw.as_ptr(), raw.len()) };
SeqIter::Raw(Decoder::new(slice, *encoding))
}
SeqRepr::Owned(v) => SeqIter::Owned(v.iter()),
}
}
pub fn into_elements(self) -> crate::Result<Vec<Element<'a>>> {
match self.repr {
SeqRepr::Owned(v) => Ok(v),
SeqRepr::Borrowed { raw, encoding } => {
let mut decoder = crate::der::decoder::Decoder::new(raw, encoding);
let mut out = Vec::new();
while !decoder.is_empty() {
use crate::traits::Decode;
out.push(Element::decode(&mut decoder)?);
}
Ok(out)
}
SeqRepr::OwnedBytes { raw, encoding } => {
let slice: &'a [u8] =
unsafe { core::slice::from_raw_parts(raw.as_ptr(), raw.len()) };
let mut decoder = crate::der::decoder::Decoder::new(slice, encoding);
let mut out = Vec::new();
while !decoder.is_empty() {
use crate::traits::Decode;
out.push(Element::decode(&mut decoder)?);
}
Ok(out)
}
}
}
}
impl<'a> Default for Set<'a> {
fn default() -> Self {
Self::new()
}
}
impl<'a> Clone for Set<'a> {
fn clone(&self) -> Self {
Set {
repr: self.repr.clone(),
}
}
}
impl<'a> fmt::Debug for Set<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.repr {
SeqRepr::Borrowed { raw, .. } => {
write!(f, "Set::Borrowed({} bytes)", raw.len())
}
SeqRepr::OwnedBytes { raw, .. } => {
write!(f, "Set::OwnedBytes({} bytes)", raw.len())
}
SeqRepr::Owned(v) => f.debug_list().entries(v.iter()).finish(),
}
}
}
impl<'a> PartialEq for Set<'a> {
fn eq(&self, other: &Self) -> bool {
match (self.repr.raw_bytes(), other.repr.raw_bytes()) {
(Some(a), Some(b)) => a == b,
_ => match (&self.repr, &other.repr) {
(SeqRepr::Owned(a), SeqRepr::Owned(b)) => a == b,
_ => {
let a: crate::Result<Vec<_>> = self.iter().collect();
let b: crate::Result<Vec<_>> = other.iter().collect();
a.ok() == b.ok()
}
},
}
}
}
impl<'a> IntoIterator for Set<'a> {
type Item = crate::Result<Element<'a>>;
type IntoIter = SeqIntoIter<'a>;
fn into_iter(self) -> Self::IntoIter {
match self.repr {
SeqRepr::Borrowed { raw, encoding } => SeqIntoIter::Raw(Decoder::new(raw, encoding)),
SeqRepr::OwnedBytes { raw, encoding } => SeqIntoIter::OwnedBytes {
raw,
pos: 0,
encoding,
},
SeqRepr::Owned(v) => SeqIntoIter::Owned(v.into_iter()),
}
}
}
impl<'a> crate::traits::Decode<'a> for Set<'a> {
fn decode(decoder: &mut crate::der::decoder::Decoder<'a>) -> crate::Result<Self> {
use crate::tag::TAG_SET;
let tag = crate::Tag::universal_constructed(TAG_SET);
let read_tag = decoder.read_tag()?;
if read_tag != tag {
return Err(crate::Error::UnexpectedTag {
position: decoder.position(),
expected: tag,
actual: read_tag,
});
}
decode_set_content(decoder)
}
}
impl<'a> crate::traits::Encode for Set<'a> {
fn encode(&self, encoder: &mut crate::der::encoder::Encoder) -> crate::Result<()> {
use crate::tag::TAG_SET;
let tag = crate::Tag::universal_constructed(TAG_SET);
if let Some(raw) = self.repr.raw_bytes() {
encoder.write_tag(tag)?;
encoder.write_length(raw.len())?;
encoder.write_bytes(raw);
return Ok(());
}
let SeqRepr::Owned(elements) = &self.repr else {
unreachable!()
};
let encoding = encoder.encoding();
let mut constructed = encoder.start_constructed(tag)?;
if encoding == crate::Encoding::Der {
let mut encoded: Vec<Vec<u8>> = Vec::new();
for el in elements {
let mut enc = crate::der::encoder::Encoder::new(encoding);
el.encode(&mut enc)?;
encoded.push(enc.finish()?);
}
encoded.sort();
for bytes in encoded {
constructed.write_bytes(&bytes)?;
}
} else {
for el in elements {
constructed.encode(el)?;
}
}
Ok(())
}
fn encoded_len(&self) -> crate::Result<usize> {
use crate::tag::TAG_SET;
let tag_len = crate::Tag::universal_constructed(TAG_SET).encoded_len();
if let Some(raw) = self.repr.raw_bytes() {
let length_len = crate::Length::Definite(raw.len()).encoded_len()?;
return Ok(tag_len + length_len + raw.len());
}
let SeqRepr::Owned(elements) = &self.repr else {
unreachable!()
};
let mut content_len = 0;
for el in elements {
content_len += el.encoded_len()?;
}
let length_len = crate::Length::Definite(content_len).encoded_len()?;
Ok(tag_len + length_len + content_len)
}
}
impl<'a> crate::traits::Tagged for Set<'a> {
fn tag() -> crate::Tag {
crate::Tag::universal_constructed(crate::tag::TAG_SET)
}
}
#[inline(always)]
fn decode_constructed_content<'a, T>(
decoder: &mut crate::der::decoder::Decoder<'a>,
from_raw: fn(&'a [u8], crate::Encoding) -> T,
from_owned: fn(Vec<u8>, crate::Encoding) -> T,
) -> crate::Result<T> {
let encoding = decoder.encoding();
match decoder.read_length()? {
crate::Length::Definite(len) => {
if encoding == crate::Encoding::Cer && len > 1000 {
#[cfg(feature = "std")]
return Err(crate::Error::CerViolation {
position: decoder.position(),
reason: "CER requires indefinite length for constructed types >1000 bytes"
.into(),
});
#[cfg(not(feature = "std"))]
return Err(crate::Error::CerViolation {
position: decoder.position(),
reason: "CER requires indefinite length for constructed types >1000 bytes",
});
}
let raw = decoder.read_bytes(len)?;
Ok(from_raw(raw, encoding))
}
crate::Length::Indefinite => {
if encoding == crate::Encoding::Der {
return Err(crate::Error::IndefiniteLengthInDer {
position: decoder.position(),
});
}
let raw = decoder.read_indefinite_content()?.to_vec();
Ok(from_owned(raw, encoding))
}
}
}
#[inline(always)]
fn decode_seq_content<'a>(
decoder: &mut crate::der::decoder::Decoder<'a>,
) -> crate::Result<Sequence<'a>> {
decode_constructed_content(decoder, Sequence::from_raw, Sequence::from_owned_bytes)
}
#[inline(always)]
fn decode_set_content<'a>(
decoder: &mut crate::der::decoder::Decoder<'a>,
) -> crate::Result<Set<'a>> {
decode_constructed_content(decoder, Set::from_raw, Set::from_owned_bytes)
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SequenceOf<T> {
elements: Vec<T>,
}
impl<T> SequenceOf<T> {
pub fn new() -> Self {
Self {
elements: Vec::new(),
}
}
pub fn from_vec(elements: Vec<T>) -> Self {
Self { elements }
}
pub fn push(&mut self, element: T) {
self.elements.push(element);
}
pub fn elements(&self) -> &[T] {
&self.elements
}
pub fn into_vec(self) -> Vec<T> {
self.elements
}
pub fn len(&self) -> usize {
self.elements.len()
}
pub fn is_empty(&self) -> bool {
self.elements.is_empty()
}
}
impl<T> Default for SequenceOf<T> {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SetOf<T> {
elements: Vec<T>,
}
impl<T> SetOf<T> {
pub fn new() -> Self {
Self {
elements: Vec::new(),
}
}
pub fn from_vec(elements: Vec<T>) -> Self {
Self { elements }
}
pub fn push(&mut self, element: T) {
self.elements.push(element);
}
pub fn elements(&self) -> &[T] {
&self.elements
}
pub fn into_vec(self) -> Vec<T> {
self.elements
}
pub fn len(&self) -> usize {
self.elements.len()
}
pub fn is_empty(&self) -> bool {
self.elements.is_empty()
}
}
impl<T> Default for SetOf<T> {
fn default() -> Self {
Self::new()
}
}
impl<'a> crate::traits::Decode<'a> for Element<'a> {
#[inline]
fn decode(decoder: &mut crate::der::decoder::Decoder<'a>) -> crate::Result<Self> {
use crate::tag::*;
let tag = decoder.read_tag()?;
if tag.class() == crate::TagClass::Universal {
let constructed = tag.is_constructed();
let number = tag.number();
return if constructed {
match number {
TAG_SEQUENCE => Ok(Element::Sequence(decode_seq_content(decoder)?)),
TAG_SET => Ok(Element::Set(decode_set_content(decoder)?)),
_ => {
let pos = decoder.position();
Err(crate::Error::InvalidEncoding {
position: pos,
tag,
#[cfg(feature = "std")]
reason: format!("Unsupported constructed tag: {:?}", tag),
#[cfg(not(feature = "std"))]
reason: "Unsupported constructed tag",
})
}
}
} else {
match number {
TAG_OBJECT_IDENTIFIER => {
Ok(Element::ObjectIdentifier(decode_oid_content(decoder)?))
}
TAG_PRINTABLE_STRING => Ok(Element::PrintableString(
decode_printable_string_content(decoder)?,
)),
TAG_INTEGER => Ok(Element::Integer(decode_integer_content(decoder)?)),
TAG_OCTET_STRING => {
Ok(Element::OctetString(decode_octet_string_content(decoder)?))
}
TAG_BIT_STRING => Ok(Element::BitString(decode_bit_string_content(decoder)?)),
TAG_UTF8_STRING => {
Ok(Element::Utf8String(decode_utf8_string_content(decoder)?))
}
TAG_IA5_STRING => Ok(Element::IA5String(decode_ia5_string_content(decoder)?)),
TAG_UTC_TIME => Ok(Element::UtcTime(decode_utc_time_content(decoder)?)),
TAG_GENERALIZED_TIME => Ok(Element::GeneralizedTime(
decode_generalized_time_content(decoder)?,
)),
TAG_BOOLEAN => Ok(Element::Boolean(decode_boolean_content(decoder)?)),
TAG_NULL => Ok(Element::Null(decode_null_content(decoder)?)),
TAG_REAL => Ok(Element::Real(decode_real_content(decoder)?)),
TAG_NUMERIC_STRING => Ok(Element::NumericString(
decode_numeric_string_content(decoder)?,
)),
TAG_TELETEX_STRING => Ok(Element::TeletexString(
decode_teletex_string_content(decoder)?,
)),
TAG_VISIBLE_STRING => Ok(Element::VisibleString(
decode_visible_string_content(decoder)?,
)),
TAG_GENERAL_STRING => Ok(Element::GeneralString(
decode_general_string_content(decoder)?,
)),
TAG_UNIVERSAL_STRING => Ok(Element::UniversalString(
decode_universal_string_content(decoder)?,
)),
TAG_BMP_STRING => Ok(Element::BmpString(decode_bmp_string_content(decoder)?)),
0 => Err(crate::Error::InvalidEncoding {
position: decoder.position(),
tag,
#[cfg(feature = "std")]
reason: "End-of-Contents (EOC) is not a valid standalone element"
.to_string(),
#[cfg(not(feature = "std"))]
reason: "End-of-Contents (EOC) is not a valid standalone element",
}),
TAG_SEQUENCE | TAG_SET => Err(crate::Error::InvalidEncoding {
position: decoder.position(),
tag,
#[cfg(feature = "std")]
reason: format!("tag {:?} must be constructed, not primitive", tag),
#[cfg(not(feature = "std"))]
reason: "SEQUENCE/SET must be constructed",
}),
_ => {
let length = decoder.read_length()?;
let len = length.definite()?;
let bytes = decoder.read_bytes(len)?;
Ok(Element::Raw(tag, bytes))
}
}
};
}
let length = decoder.read_length()?;
let len = length.definite()?;
let content = decoder.read_bytes(len)?;
let mut inner_decoder = crate::der::decoder::Decoder::new(content, decoder.encoding());
let inner = Element::decode(&mut inner_decoder)?;
Ok(Element::Tagged(tag, Box::new(inner)))
}
}
#[inline(always)]
fn decode_integer_content(
decoder: &mut crate::der::decoder::Decoder,
) -> crate::Result<crate::types::primitive::Integer> {
let length = decoder.read_length()?;
let len = length.definite()?;
let bytes = decoder.read_bytes(len)?;
if bytes.len() > 1 {
let b0 = bytes[0];
let b1 = bytes[1];
let redundant_zero = b0 == 0x00 && (b1 & 0x80) == 0;
let redundant_ff = b0 == 0xFF && (b1 & 0x80) != 0;
if redundant_zero || redundant_ff {
return Err(crate::Error::InvalidEncoding {
position: decoder.position(),
tag: crate::Tag::universal(crate::tag::TAG_INTEGER),
#[cfg(feature = "std")]
reason: "INTEGER has non-minimal encoding (redundant leading byte)".to_string(),
#[cfg(not(feature = "std"))]
reason: "INTEGER has non-minimal encoding",
});
}
}
Ok(crate::types::primitive::Integer::from_bytes(bytes))
}
#[inline(always)]
fn decode_oid_content(
decoder: &mut crate::der::decoder::Decoder,
) -> crate::Result<crate::types::oid::ObjectIdentifier> {
let length = decoder.read_length()?;
let len = length.definite()?;
if len == 0 {
return Err(crate::Error::InvalidOid {
position: decoder.position(),
});
}
let bytes = decoder.read_bytes(len)?;
let mut components: smallvec::SmallVec<[u32; 10]> = smallvec::SmallVec::new();
let mut i = 0;
let mut combined: u32 = 0;
loop {
if i >= bytes.len() {
return Err(crate::Error::InvalidOid {
position: decoder.position(),
});
}
let byte = bytes[i];
i += 1;
if combined > (u32::MAX >> 7) {
return Err(crate::Error::InvalidOid {
position: decoder.position(),
});
}
combined = (combined << 7) | ((byte & 0x7F) as u32);
if (byte & 0x80) == 0 {
break;
}
}
if combined < 40 {
components.push(0);
components.push(combined);
} else if combined < 80 {
components.push(1);
components.push(combined - 40);
} else {
components.push(2);
components.push(combined - 80);
}
while i < bytes.len() {
let mut value: u32 = 0;
loop {
if i >= bytes.len() {
return Err(crate::Error::InvalidOid {
position: decoder.position(),
});
}
let byte = bytes[i];
i += 1;
if value > (u32::MAX >> 7) {
return Err(crate::Error::InvalidOid {
position: decoder.position(),
});
}
value = (value << 7) | ((byte & 0x7F) as u32);
if (byte & 0x80) == 0 {
break;
}
}
components.push(value);
}
Ok(crate::types::oid::ObjectIdentifier::from_components_unchecked(components))
}
#[inline(always)]
fn decode_printable_string_content<'a>(
decoder: &mut crate::der::decoder::Decoder<'a>,
) -> crate::Result<crate::types::string::PrintableStringRef<'a>> {
let length = decoder.read_length()?;
let len = length.definite()?;
let bytes = decoder.read_bytes(len)?;
let s = core::str::from_utf8(bytes).map_err(|_| crate::Error::InvalidString {
position: decoder.position(),
string_type: "PrintableString",
#[cfg(feature = "std")]
reason: "Invalid UTF-8/ASCII encoding".to_string(),
#[cfg(not(feature = "std"))]
reason: "Invalid UTF-8/ASCII encoding",
})?;
crate::types::string::PrintableStringRef::new(s)
}
#[inline(always)]
fn decode_octet_string_content<'a>(
decoder: &mut crate::der::decoder::Decoder<'a>,
) -> crate::Result<crate::types::string::OctetStringRef<'a>> {
let length = decoder.read_length()?;
let len = length.definite()?;
let bytes = decoder.read_bytes(len)?;
Ok(crate::types::string::OctetStringRef::new(bytes))
}
#[inline(always)]
fn decode_bit_string_content<'a>(
decoder: &mut crate::der::decoder::Decoder<'a>,
) -> crate::Result<crate::types::string::BitStringRef<'a>> {
let length = decoder.read_length()?;
let len = length.definite()?;
let bytes = decoder.read_bytes(len)?;
if bytes.is_empty() {
return Err(crate::Error::InvalidEncoding {
position: decoder.position(),
tag: crate::Tag::universal(crate::tag::TAG_BIT_STRING),
#[cfg(feature = "std")]
reason: "BIT STRING must have at least 1 byte".to_string(),
#[cfg(not(feature = "std"))]
reason: "BIT STRING too short",
});
}
let unused_bits = bytes[0];
if unused_bits > 7 {
return Err(crate::Error::InvalidEncoding {
position: decoder.position(),
tag: crate::Tag::universal(crate::tag::TAG_BIT_STRING),
#[cfg(feature = "std")]
reason: format!("Invalid unused bits: {}", unused_bits),
#[cfg(not(feature = "std"))]
reason: "Invalid unused bits",
});
}
crate::types::string::BitStringRef::new(&bytes[1..], unused_bits)
}
#[inline(always)]
fn decode_utf8_string_content<'a>(
decoder: &mut crate::der::decoder::Decoder<'a>,
) -> crate::Result<crate::types::string::Utf8StringRef<'a>> {
let length = decoder.read_length()?;
let len = length.definite()?;
let bytes = decoder.read_bytes(len)?;
let s = core::str::from_utf8(bytes).map_err(|_| crate::Error::InvalidString {
position: decoder.position(),
string_type: "UTF8String",
#[cfg(feature = "std")]
reason: "Invalid UTF-8 encoding".to_string(),
#[cfg(not(feature = "std"))]
reason: "Invalid UTF-8 encoding",
})?;
Ok(crate::types::string::Utf8StringRef::new(s))
}
#[inline(always)]
fn decode_ia5_string_content<'a>(
decoder: &mut crate::der::decoder::Decoder<'a>,
) -> crate::Result<crate::types::string::IA5StringRef<'a>> {
let length = decoder.read_length()?;
let len = length.definite()?;
let bytes = decoder.read_bytes(len)?;
let s = core::str::from_utf8(bytes).map_err(|_| crate::Error::InvalidString {
position: decoder.position(),
string_type: "IA5String",
#[cfg(feature = "std")]
reason: "Invalid UTF-8/ASCII encoding".to_string(),
#[cfg(not(feature = "std"))]
reason: "Invalid UTF-8/ASCII encoding",
})?;
if !s.is_ascii() {
return Err(crate::Error::InvalidString {
position: decoder.position(),
string_type: "IA5String",
#[cfg(feature = "std")]
reason: "String contains non-ASCII characters".to_string(),
#[cfg(not(feature = "std"))]
reason: "Non-ASCII characters",
});
}
Ok(crate::types::string::IA5StringRef::new(s).unwrap())
}
#[inline(always)]
fn decode_utc_time_content(
decoder: &mut crate::der::decoder::Decoder,
) -> crate::Result<crate::types::time::UtcTime> {
let length = decoder.read_length()?;
let len = length.definite()?;
let content = decoder.read_bytes(len)?;
let s = core::str::from_utf8(content).map_err(|_| crate::Error::InvalidTime {
position: decoder.position(),
})?;
crate::types::time::UtcTime::from_str(s)
}
#[inline(always)]
fn decode_generalized_time_content(
decoder: &mut crate::der::decoder::Decoder,
) -> crate::Result<crate::types::time::GeneralizedTime> {
let length = decoder.read_length()?;
let len = length.definite()?;
let content = decoder.read_bytes(len)?;
let s = core::str::from_utf8(content).map_err(|_| crate::Error::InvalidTime {
position: decoder.position(),
})?;
crate::types::time::GeneralizedTime::from_str(s)
}
#[inline(always)]
fn decode_boolean_content(
decoder: &mut crate::der::decoder::Decoder,
) -> crate::Result<crate::types::primitive::Boolean> {
let length = decoder.read_length()?;
let len = length.definite()?;
if len != 1 {
return Err(crate::Error::InvalidEncoding {
position: decoder.position(),
tag: crate::Tag::universal(crate::tag::TAG_BOOLEAN),
#[cfg(feature = "std")]
reason: format!("BOOLEAN must be exactly 1 byte, got {}", len),
#[cfg(not(feature = "std"))]
reason: "Invalid BOOLEAN length",
});
}
let bytes = decoder.read_bytes(1)?;
let value = bytes[0];
if decoder.encoding() == crate::Encoding::Der && value != 0x00 && value != 0xFF {
return Err(crate::Error::DerViolation {
position: decoder.position(),
#[cfg(feature = "std")]
reason: format!("BOOLEAN TRUE must be 0xFF in DER, got 0x{:02X}", value),
#[cfg(not(feature = "std"))]
reason: "BOOLEAN TRUE must be 0xFF in DER",
});
}
Ok(crate::types::primitive::Boolean::new(value != 0))
}
#[inline(always)]
fn decode_null_content(
decoder: &mut crate::der::decoder::Decoder,
) -> crate::Result<crate::types::primitive::Null> {
let length = decoder.read_length()?;
let len = length.definite()?;
if len != 0 {
return Err(crate::Error::InvalidEncoding {
position: decoder.position(),
tag: crate::Tag::universal(crate::tag::TAG_NULL),
#[cfg(feature = "std")]
reason: "NULL must have zero length".to_string(),
#[cfg(not(feature = "std"))]
reason: "Invalid NULL length",
});
}
Ok(crate::types::primitive::Null)
}
#[inline(always)]
fn decode_real_content(
decoder: &mut crate::der::decoder::Decoder,
) -> crate::Result<crate::types::primitive::Real> {
let length = decoder.read_length()?;
let len = length.definite()?;
let content = decoder.read_bytes(len)?;
match len {
0 => Ok(crate::types::primitive::Real::new(0.0)),
1 => match content[0] {
0x40 => Ok(crate::types::primitive::Real::new(f64::INFINITY)),
0x41 => Ok(crate::types::primitive::Real::new(f64::NEG_INFINITY)),
0x42 => Ok(crate::types::primitive::Real::new(f64::NAN)),
_ => Err(crate::Error::InvalidEncoding {
position: decoder.position(),
tag: crate::Tag::universal(crate::tag::TAG_REAL),
#[cfg(feature = "std")]
reason: format!("Invalid REAL special value byte: 0x{:02x}", content[0]),
#[cfg(not(feature = "std"))]
reason: "Invalid REAL special value",
}),
},
9 => {
let info = content[0];
if (info & 0x80) == 0 {
return Err(crate::Error::InvalidEncoding {
position: decoder.position(),
tag: crate::Tag::universal(crate::tag::TAG_REAL),
#[cfg(feature = "std")]
reason: "Decimal REAL encoding not supported".to_string(),
#[cfg(not(feature = "std"))]
reason: "Decimal REAL not supported",
});
}
let bytes: [u8; 8] = content[1..9].try_into().unwrap();
Ok(crate::types::primitive::Real::new(f64::from_be_bytes(
bytes,
)))
}
_ => Err(crate::Error::InvalidEncoding {
position: decoder.position(),
tag: crate::Tag::universal(crate::tag::TAG_REAL),
#[cfg(feature = "std")]
reason: format!("Unsupported REAL encoding length: {}", len),
#[cfg(not(feature = "std"))]
reason: "Unsupported REAL encoding length",
}),
}
}
impl<'a> crate::traits::Encode for Element<'a> {
fn encode(&self, encoder: &mut crate::der::encoder::Encoder) -> crate::Result<()> {
match self {
Element::Boolean(v) => encoder.encode(v),
Element::Integer(v) => encoder.encode(v),
Element::BitString(v) => encoder.encode(v),
Element::OctetString(v) => encoder.encode(v),
Element::Null(v) => encoder.encode(v),
Element::Real(v) => encoder.encode(v),
Element::ObjectIdentifier(v) => encoder.encode(v),
Element::Utf8String(v) => encoder.encode(v),
Element::PrintableString(v) => encoder.encode(v),
Element::IA5String(v) => encoder.encode(v),
Element::UtcTime(v) => encoder.encode(v),
Element::GeneralizedTime(v) => encoder.encode(v),
Element::Sequence(v) => encoder.encode(v),
Element::Set(v) => encoder.encode(v),
Element::Tagged(tag, inner) => {
encoder.write_tag(*tag)?;
let mut inner_encoder = crate::der::encoder::Encoder::new(encoder.encoding());
inner.encode(&mut inner_encoder)?;
let inner_bytes = inner_encoder.finish()?;
encoder.write_length(inner_bytes.len())?;
encoder.write_bytes(&inner_bytes);
Ok(())
}
Element::NumericString(v) => encoder.encode(v),
Element::TeletexString(v) => encoder.encode(v),
Element::VisibleString(v) => encoder.encode(v),
Element::GeneralString(v) => encoder.encode(v),
Element::UniversalString(v) => encoder.encode(v),
Element::BmpString(v) => encoder.encode(v),
Element::Raw(tag, bytes) => {
encoder.write_tag(*tag)?;
encoder.write_length(bytes.len())?;
encoder.write_bytes(bytes);
Ok(())
}
}
}
fn encoded_len(&self) -> crate::Result<usize> {
match self {
Element::Boolean(v) => v.encoded_len(),
Element::Integer(v) => v.encoded_len(),
Element::BitString(v) => v.encoded_len(),
Element::OctetString(v) => v.encoded_len(),
Element::Null(v) => v.encoded_len(),
Element::Real(v) => v.encoded_len(),
Element::ObjectIdentifier(v) => v.encoded_len(),
Element::Utf8String(v) => v.encoded_len(),
Element::PrintableString(v) => v.encoded_len(),
Element::IA5String(v) => v.encoded_len(),
Element::UtcTime(v) => v.encoded_len(),
Element::GeneralizedTime(v) => v.encoded_len(),
Element::Sequence(v) => v.encoded_len(),
Element::Set(v) => v.encoded_len(),
Element::Tagged(_tag, inner) => {
let tag_len = 1; let inner_len = inner.encoded_len()?;
let length_len = crate::Length::Definite(inner_len).encoded_len()?;
Ok(tag_len + length_len + inner_len)
}
Element::NumericString(v) => v.encoded_len(),
Element::TeletexString(v) => v.encoded_len(),
Element::VisibleString(v) => v.encoded_len(),
Element::GeneralString(v) => v.encoded_len(),
Element::UniversalString(v) => v.encoded_len(),
Element::BmpString(v) => v.encoded_len(),
Element::Raw(tag, bytes) => {
let tag_len = tag.encoded_len();
let length_len = crate::Length::Definite(bytes.len()).encoded_len()?;
Ok(tag_len + length_len + bytes.len())
}
}
}
}
impl<'a> crate::traits::TagForOptional for Element<'a> {
fn optional_tag() -> Option<crate::Tag> {
None
}
}
impl<'a, T> crate::traits::Decode<'a> for SequenceOf<T>
where
T: for<'b> crate::traits::Decode<'b>,
{
fn decode(decoder: &mut crate::der::decoder::Decoder<'a>) -> crate::Result<Self> {
use crate::tag::TAG_SEQUENCE;
let tag = crate::Tag::universal_constructed(TAG_SEQUENCE);
let mut seq_decoder = decoder.enter_constructed(tag)?;
let mut sequence = SequenceOf::new();
while !seq_decoder.is_empty() {
let element = T::decode(&mut seq_decoder)?;
sequence.push(element);
}
Ok(sequence)
}
}
impl<T: crate::traits::Encode> crate::traits::Encode for SequenceOf<T> {
fn encode(&self, encoder: &mut crate::der::encoder::Encoder) -> crate::Result<()> {
use crate::tag::TAG_SEQUENCE;
let tag = crate::Tag::universal_constructed(TAG_SEQUENCE);
let mut constructed = encoder.start_constructed(tag)?;
for element in &self.elements {
constructed.encode(element)?;
}
Ok(())
}
fn encoded_len(&self) -> crate::Result<usize> {
let tag_len = 1;
let mut content_len = 0;
for element in &self.elements {
content_len += element.encoded_len()?;
}
let length_len = crate::Length::Definite(content_len).encoded_len()?;
Ok(tag_len + length_len + content_len)
}
}
impl<T> crate::traits::Tagged for SequenceOf<T> {
fn tag() -> crate::Tag {
crate::Tag::universal_constructed(crate::tag::TAG_SEQUENCE)
}
}
impl<'a, T> crate::traits::Decode<'a> for SetOf<T>
where
T: crate::traits::Decode<'a>,
{
fn decode(decoder: &mut crate::der::decoder::Decoder<'a>) -> crate::Result<Self> {
use crate::tag::TAG_SET;
let tag = crate::Tag::universal_constructed(TAG_SET);
let mut set_decoder = decoder.enter_constructed(tag)?;
let mut set = SetOf::new();
while !set_decoder.is_empty() {
let element = T::decode(&mut set_decoder)?;
set.push(element);
}
Ok(set)
}
}
impl<T: crate::traits::Encode> crate::traits::Encode for SetOf<T> {
fn encode(&self, encoder: &mut crate::der::encoder::Encoder) -> crate::Result<()> {
use crate::tag::TAG_SET;
let tag = crate::Tag::universal_constructed(TAG_SET);
let encoding = encoder.encoding();
let mut constructed = encoder.start_constructed(tag)?;
if encoding == crate::Encoding::Der {
let mut encoded_elements: Vec<Vec<u8>> = Vec::new();
for element in &self.elements {
let mut elem_encoder = crate::der::encoder::Encoder::new(encoding);
element.encode(&mut elem_encoder)?;
encoded_elements.push(elem_encoder.finish()?);
}
encoded_elements.sort();
for bytes in encoded_elements {
constructed.write_bytes(&bytes)?;
}
} else {
for element in &self.elements {
constructed.encode(element)?;
}
}
Ok(())
}
fn encoded_len(&self) -> crate::Result<usize> {
let tag_len = 1;
let mut content_len = 0;
for element in &self.elements {
content_len += element.encoded_len()?;
}
let length_len = crate::Length::Definite(content_len).encoded_len()?;
Ok(tag_len + length_len + content_len)
}
}
impl<T> crate::traits::Tagged for SetOf<T> {
fn tag() -> crate::Tag {
crate::Tag::universal_constructed(crate::tag::TAG_SET)
}
}
impl<T: crate::traits::Encode> crate::traits::Encode for Vec<T> {
fn encode(&self, encoder: &mut crate::der::encoder::Encoder) -> crate::Result<()> {
use crate::tag::TAG_SEQUENCE;
let tag = crate::Tag::universal_constructed(TAG_SEQUENCE);
let mut constructed = encoder.start_constructed(tag)?;
for element in self {
constructed.encode(element)?;
}
Ok(())
}
fn encoded_len(&self) -> crate::Result<usize> {
let tag_len = 1;
let mut content_len = 0;
for element in self {
content_len += element.encoded_len()?;
}
let length_len = crate::Length::Definite(content_len).encoded_len()?;
Ok(tag_len + length_len + content_len)
}
}
impl<'a, T> crate::traits::Decode<'a> for Vec<T>
where
T: crate::traits::Decode<'a>,
{
fn decode(decoder: &mut crate::der::decoder::Decoder<'a>) -> crate::Result<Self> {
use crate::tag::TAG_SEQUENCE;
let tag = crate::Tag::universal_constructed(TAG_SEQUENCE);
let mut seq_decoder = decoder.enter_constructed(tag)?;
let mut elements = Vec::new();
while !seq_decoder.is_empty() {
elements.push(T::decode(&mut seq_decoder)?);
}
Ok(elements)
}
}
impl<T> crate::traits::Tagged for Vec<T> {
fn tag() -> crate::Tag {
crate::Tag::universal_constructed(crate::tag::TAG_SEQUENCE)
}
}
#[cfg(feature = "serde")]
impl<'a> serde::Serialize for Element<'a> {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
use serde::ser::SerializeMap;
match self {
Element::Boolean(v) => {
let mut m = serializer.serialize_map(Some(2))?;
m.serialize_entry("type", "Boolean")?;
m.serialize_entry("value", v)?;
m.end()
}
Element::Integer(v) => {
let mut m = serializer.serialize_map(Some(2))?;
m.serialize_entry("type", "Integer")?;
m.serialize_entry("value", v)?;
m.end()
}
Element::BitString(v) => {
let mut m = serializer.serialize_map(Some(2))?;
m.serialize_entry("type", "BitString")?;
m.serialize_entry("value", v)?;
m.end()
}
Element::OctetString(v) => {
let mut m = serializer.serialize_map(Some(2))?;
m.serialize_entry("type", "OctetString")?;
m.serialize_entry("value", v)?;
m.end()
}
Element::Null(v) => {
let mut m = serializer.serialize_map(Some(2))?;
m.serialize_entry("type", "Null")?;
m.serialize_entry("value", v)?;
m.end()
}
Element::Real(v) => {
let mut m = serializer.serialize_map(Some(2))?;
m.serialize_entry("type", "Real")?;
m.serialize_entry("value", v)?;
m.end()
}
Element::ObjectIdentifier(v) => {
let mut m = serializer.serialize_map(Some(2))?;
m.serialize_entry("type", "ObjectIdentifier")?;
m.serialize_entry("value", v)?;
m.end()
}
Element::Utf8String(v) => {
let mut m = serializer.serialize_map(Some(2))?;
m.serialize_entry("type", "Utf8String")?;
m.serialize_entry("value", v)?;
m.end()
}
Element::PrintableString(v) => {
let mut m = serializer.serialize_map(Some(2))?;
m.serialize_entry("type", "PrintableString")?;
m.serialize_entry("value", v)?;
m.end()
}
Element::IA5String(v) => {
let mut m = serializer.serialize_map(Some(2))?;
m.serialize_entry("type", "IA5String")?;
m.serialize_entry("value", v)?;
m.end()
}
Element::UtcTime(v) => {
let mut m = serializer.serialize_map(Some(2))?;
m.serialize_entry("type", "UtcTime")?;
m.serialize_entry("value", v)?;
m.end()
}
Element::GeneralizedTime(v) => {
let mut m = serializer.serialize_map(Some(2))?;
m.serialize_entry("type", "GeneralizedTime")?;
m.serialize_entry("value", v)?;
m.end()
}
Element::Sequence(v) => {
let mut m = serializer.serialize_map(Some(2))?;
m.serialize_entry("type", "Sequence")?;
m.serialize_entry("value", v)?;
m.end()
}
Element::Set(v) => {
let mut m = serializer.serialize_map(Some(2))?;
m.serialize_entry("type", "Set")?;
m.serialize_entry("value", v)?;
m.end()
}
Element::Tagged(tag, inner) => {
let mut m = serializer.serialize_map(Some(3))?;
m.serialize_entry("type", "Tagged")?;
m.serialize_entry("tag", tag)?;
m.serialize_entry("value", inner.as_ref())?;
m.end()
}
Element::NumericString(v) => {
let mut m = serializer.serialize_map(Some(2))?;
m.serialize_entry("type", "NumericString")?;
m.serialize_entry("value", v)?;
m.end()
}
Element::TeletexString(v) => {
let mut m = serializer.serialize_map(Some(2))?;
m.serialize_entry("type", "TeletexString")?;
m.serialize_entry("value", v)?;
m.end()
}
Element::VisibleString(v) => {
let mut m = serializer.serialize_map(Some(2))?;
m.serialize_entry("type", "VisibleString")?;
m.serialize_entry("value", v)?;
m.end()
}
Element::GeneralString(v) => {
let mut m = serializer.serialize_map(Some(2))?;
m.serialize_entry("type", "GeneralString")?;
m.serialize_entry("value", v)?;
m.end()
}
Element::UniversalString(v) => {
let mut m = serializer.serialize_map(Some(2))?;
m.serialize_entry("type", "UniversalString")?;
m.serialize_entry("value", v)?;
m.end()
}
Element::BmpString(v) => {
let mut m = serializer.serialize_map(Some(2))?;
m.serialize_entry("type", "BmpString")?;
m.serialize_entry("value", v)?;
m.end()
}
Element::Raw(tag, bytes) => {
let mut m = serializer.serialize_map(Some(3))?;
m.serialize_entry("type", "Raw")?;
m.serialize_entry("tag", tag)?;
m.serialize_entry("value", &crate::serde_impl::bytes_to_hex(bytes))?;
m.end()
}
}
}
}
#[cfg(feature = "serde")]
impl<'a> serde::Serialize for Sequence<'a> {
fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
use serde::ser::SerializeSeq;
match &self.repr {
SeqRepr::Owned(elements) => {
let mut seq = s.serialize_seq(Some(elements.len()))?;
for element in elements {
seq.serialize_element(element)?;
}
seq.end()
}
SeqRepr::Borrowed { raw, encoding } => {
let mut seq = s.serialize_seq(None)?;
let mut decoder = crate::der::decoder::Decoder::new(raw, *encoding);
while !decoder.is_empty() {
use crate::traits::Decode;
let element =
Element::decode(&mut decoder).map_err(serde::ser::Error::custom)?;
seq.serialize_element(&element)?;
}
seq.end()
}
SeqRepr::OwnedBytes { raw, encoding } => {
let mut seq = s.serialize_seq(None)?;
let mut decoder = crate::der::decoder::Decoder::new(raw.as_slice(), *encoding);
while !decoder.is_empty() {
use crate::traits::Decode;
let element =
Element::decode(&mut decoder).map_err(serde::ser::Error::custom)?;
seq.serialize_element(&element)?;
}
seq.end()
}
}
}
}
#[cfg(feature = "serde")]
impl<'a> serde::Serialize for Set<'a> {
fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
use serde::ser::SerializeSeq;
match &self.repr {
SeqRepr::Owned(elements) => {
let mut seq = s.serialize_seq(Some(elements.len()))?;
for element in elements {
seq.serialize_element(element)?;
}
seq.end()
}
SeqRepr::Borrowed { raw, encoding } => {
let mut seq = s.serialize_seq(None)?;
let mut decoder = crate::der::decoder::Decoder::new(raw, *encoding);
while !decoder.is_empty() {
use crate::traits::Decode;
let element =
Element::decode(&mut decoder).map_err(serde::ser::Error::custom)?;
seq.serialize_element(&element)?;
}
seq.end()
}
SeqRepr::OwnedBytes { raw, encoding } => {
let mut seq = s.serialize_seq(None)?;
let mut decoder = crate::der::decoder::Decoder::new(raw.as_slice(), *encoding);
while !decoder.is_empty() {
use crate::traits::Decode;
let element =
Element::decode(&mut decoder).map_err(serde::ser::Error::custom)?;
seq.serialize_element(&element)?;
}
seq.end()
}
}
}
}
#[cfg(feature = "serde")]
impl<T: serde::Serialize> serde::Serialize for SequenceOf<T> {
fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
use serde::ser::SerializeSeq;
let mut seq = s.serialize_seq(Some(self.elements.len()))?;
for element in self.elements() {
seq.serialize_element(element)?;
}
seq.end()
}
}
#[cfg(feature = "serde")]
impl<'de, T: serde::Deserialize<'de>> serde::Deserialize<'de> for SequenceOf<T> {
fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
struct SeqVisitor<T>(core::marker::PhantomData<T>);
impl<'de, T: serde::Deserialize<'de>> serde::de::Visitor<'de> for SeqVisitor<T> {
type Value = SequenceOf<T>;
fn expecting(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
write!(f, "a sequence")
}
fn visit_seq<A: serde::de::SeqAccess<'de>>(
self,
mut seq: A,
) -> Result<SequenceOf<T>, A::Error> {
let mut elements = Vec::new();
while let Some(element) = seq.next_element()? {
elements.push(element);
}
Ok(SequenceOf::from_vec(elements))
}
}
d.deserialize_seq(SeqVisitor(core::marker::PhantomData))
}
}
#[cfg(feature = "serde")]
impl<T: serde::Serialize> serde::Serialize for SetOf<T> {
fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
use serde::ser::SerializeSeq;
let mut seq = s.serialize_seq(Some(self.elements.len()))?;
for element in self.elements() {
seq.serialize_element(element)?;
}
seq.end()
}
}
#[cfg(feature = "serde")]
impl<'de, T: serde::Deserialize<'de>> serde::Deserialize<'de> for SetOf<T> {
fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
struct SetVisitor<T>(core::marker::PhantomData<T>);
impl<'de, T: serde::Deserialize<'de>> serde::de::Visitor<'de> for SetVisitor<T> {
type Value = SetOf<T>;
fn expecting(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
write!(f, "a set")
}
fn visit_seq<A: serde::de::SeqAccess<'de>>(
self,
mut seq: A,
) -> Result<SetOf<T>, A::Error> {
let mut elements = Vec::new();
while let Some(element) = seq.next_element()? {
elements.push(element);
}
Ok(SetOf::from_vec(elements))
}
}
d.deserialize_seq(SetVisitor(core::marker::PhantomData))
}
}
#[inline(always)]
fn decode_numeric_string_content(
decoder: &mut crate::der::decoder::Decoder,
) -> crate::Result<NumericString> {
let length = decoder.read_length()?;
let len = length.definite()?;
let bytes = decoder.read_bytes(len)?;
let s = core::str::from_utf8(bytes).map_err(|_| crate::Error::InvalidString {
position: decoder.position(),
string_type: "NumericString",
#[cfg(feature = "std")]
reason: "Invalid ASCII encoding".to_string(),
#[cfg(not(feature = "std"))]
reason: "Invalid ASCII encoding",
})?;
NumericString::new(s.to_string())
}
#[inline(always)]
fn decode_teletex_string_content(
decoder: &mut crate::der::decoder::Decoder,
) -> crate::Result<TeletexString> {
let length = decoder.read_length()?;
let len = length.definite()?;
let bytes = decoder.read_bytes(len)?;
Ok(TeletexString::new(bytes.to_vec()))
}
#[inline(always)]
fn decode_visible_string_content(
decoder: &mut crate::der::decoder::Decoder,
) -> crate::Result<VisibleString> {
let length = decoder.read_length()?;
let len = length.definite()?;
let bytes = decoder.read_bytes(len)?;
let s = core::str::from_utf8(bytes).map_err(|_| crate::Error::InvalidString {
position: decoder.position(),
string_type: "VisibleString",
#[cfg(feature = "std")]
reason: "Invalid ASCII encoding".to_string(),
#[cfg(not(feature = "std"))]
reason: "Invalid ASCII encoding",
})?;
VisibleString::new(s.to_string())
}
#[inline(always)]
fn decode_general_string_content(
decoder: &mut crate::der::decoder::Decoder,
) -> crate::Result<GeneralString> {
let length = decoder.read_length()?;
let len = length.definite()?;
let bytes = decoder.read_bytes(len)?;
Ok(GeneralString::new(bytes.to_vec()))
}
#[inline(always)]
fn decode_universal_string_content(
decoder: &mut crate::der::decoder::Decoder,
) -> crate::Result<UniversalString> {
let length = decoder.read_length()?;
let len = length.definite()?;
let bytes = decoder.read_bytes(len)?;
UniversalString::from_ucs4_be(bytes)
}
#[inline(always)]
fn decode_bmp_string_content(
decoder: &mut crate::der::decoder::Decoder,
) -> crate::Result<BmpString> {
let length = decoder.read_length()?;
let len = length.definite()?;
let bytes = decoder.read_bytes(len)?;
BmpString::from_ucs2_be(bytes)
}