use asn1::{Asn1DefinedByWritable, SimpleAsn1Writable};
#[derive(
asn1::Asn1Read, asn1::Asn1Write, PartialEq, Hash, Clone, Eq, Debug,
)]
pub struct AlgorithmIdentifier<'a> {
pub oid: asn1::DefinedByMarker<asn1::ObjectIdentifier>,
#[defined_by(oid)]
pub params: AlgorithmParameters<'a>,
}
impl AlgorithmIdentifier<'_> {
pub fn oid(&self) -> &asn1::ObjectIdentifier {
self.params.item()
}
}
#[derive(
asn1::Asn1DefinedByRead,
asn1::Asn1DefinedByWrite,
PartialEq,
Eq,
Hash,
Clone,
Debug,
)]
pub enum AlgorithmParameters<'a> {
#[defined_by(oid::SHA1_OID)]
Sha1(Option<asn1::Null>),
#[defined_by(oid::SHA224_OID)]
Sha224(Option<asn1::Null>),
#[defined_by(oid::SHA256_OID)]
Sha256(Option<asn1::Null>),
#[defined_by(oid::SHA384_OID)]
Sha384(Option<asn1::Null>),
#[defined_by(oid::SHA512_OID)]
Sha512(Option<asn1::Null>),
#[defined_by(oid::SHA3_224_OID)]
Sha3_224(Option<asn1::Null>),
#[defined_by(oid::SHA3_256_OID)]
Sha3_256(Option<asn1::Null>),
#[defined_by(oid::SHA3_384_OID)]
Sha3_384(Option<asn1::Null>),
#[defined_by(oid::SHA3_512_OID)]
Sha3_512(Option<asn1::Null>),
#[defined_by(oid::SHA3_224_NIST_OID)]
Sha3_224Nist(Option<asn1::Null>),
#[defined_by(oid::SHA3_256_NIST_OID)]
Sha3_256Nist(Option<asn1::Null>),
#[defined_by(oid::SHA3_384_NIST_OID)]
Sha3_384Nist(Option<asn1::Null>),
#[defined_by(oid::SHA3_512_NIST_OID)]
Sha3_512Nist(Option<asn1::Null>),
#[defined_by(oid::ED25519_OID)]
Ed25519,
#[defined_by(oid::ED448_OID)]
Ed448,
#[defined_by(oid::X25519_OID)]
X25519,
#[defined_by(oid::X448_OID)]
X448,
#[defined_by(oid::EC_OID)]
Ec(EcParameters<'a>),
#[defined_by(oid::RSA_OID)]
Rsa(Option<asn1::Null>),
#[defined_by(oid::ECDSA_WITH_SHA224_OID)]
EcDsaWithSha224(Option<asn1::Null>),
#[defined_by(oid::ECDSA_WITH_SHA256_OID)]
EcDsaWithSha256(Option<asn1::Null>),
#[defined_by(oid::ECDSA_WITH_SHA384_OID)]
EcDsaWithSha384(Option<asn1::Null>),
#[defined_by(oid::ECDSA_WITH_SHA512_OID)]
EcDsaWithSha512(Option<asn1::Null>),
#[defined_by(oid::ECDSA_WITH_SHA3_224_OID)]
EcDsaWithSha3_224,
#[defined_by(oid::ECDSA_WITH_SHA3_256_OID)]
EcDsaWithSha3_256,
#[defined_by(oid::ECDSA_WITH_SHA3_384_OID)]
EcDsaWithSha3_384,
#[defined_by(oid::ECDSA_WITH_SHA3_512_OID)]
EcDsaWithSha3_512,
#[defined_by(oid::RSA_WITH_SHA1_OID)]
RsaWithSha1(Option<asn1::Null>),
#[defined_by(oid::RSA_WITH_SHA1_ALT_OID)]
RsaWithSha1Alt(Option<asn1::Null>),
#[defined_by(oid::RSA_WITH_SHA224_OID)]
RsaWithSha224(Option<asn1::Null>),
#[defined_by(oid::RSA_WITH_SHA256_OID)]
RsaWithSha256(Option<asn1::Null>),
#[defined_by(oid::RSA_WITH_SHA384_OID)]
RsaWithSha384(Option<asn1::Null>),
#[defined_by(oid::RSA_WITH_SHA512_OID)]
RsaWithSha512(Option<asn1::Null>),
#[defined_by(oid::RSA_WITH_SHA3_224_OID)]
RsaWithSha3_224(Option<asn1::Null>),
#[defined_by(oid::RSA_WITH_SHA3_256_OID)]
RsaWithSha3_256(Option<asn1::Null>),
#[defined_by(oid::RSA_WITH_SHA3_384_OID)]
RsaWithSha3_384(Option<asn1::Null>),
#[defined_by(oid::RSA_WITH_SHA3_512_OID)]
RsaWithSha3_512(Option<asn1::Null>),
#[defined_by(oid::RSASSA_PSS_OID)]
RsaPss(Option<Box<RsaPssParameters<'a>>>),
#[defined_by(oid::DSA_OID)]
Dsa(DssParams<'a>),
#[defined_by(oid::DSA_WITH_SHA224_OID)]
DsaWithSha224(Option<asn1::Null>),
#[defined_by(oid::DSA_WITH_SHA256_OID)]
DsaWithSha256(Option<asn1::Null>),
#[defined_by(oid::DSA_WITH_SHA384_OID)]
DsaWithSha384(Option<asn1::Null>),
#[defined_by(oid::DSA_WITH_SHA512_OID)]
DsaWithSha512(Option<asn1::Null>),
#[defined_by(oid::DH_OID)]
Dh(DHXParams<'a>),
#[defined_by(oid::DH_KEY_AGREEMENT_OID)]
DhKeyAgreement(BasicDHParams<'a>),
#[defined_by(oid::PBES2_OID)]
Pbes2(PBES2Params<'a>),
#[defined_by(oid::PBKDF2_OID)]
Pbkdf2(PBKDF2Params<'a>),
#[defined_by(oid::SCRYPT_OID)]
Scrypt(ScryptParams<'a>),
#[defined_by(oid::HMAC_WITH_SHA1_OID)]
HmacWithSha1(Option<asn1::Null>),
#[defined_by(oid::HMAC_WITH_SHA224_OID)]
HmacWithSha224(Option<asn1::Null>),
#[defined_by(oid::HMAC_WITH_SHA256_OID)]
HmacWithSha256(Option<asn1::Null>),
#[defined_by(oid::HMAC_WITH_SHA384_OID)]
HmacWithSha384(Option<asn1::Null>),
#[defined_by(oid::HMAC_WITH_SHA512_OID)]
HmacWithSha512(Option<asn1::Null>),
#[defined_by(oid::AES_128_CBC_OID)]
Aes128Cbc([u8; 16]),
#[defined_by(oid::AES_192_CBC_OID)]
Aes192Cbc([u8; 16]),
#[defined_by(oid::AES_256_CBC_OID)]
Aes256Cbc([u8; 16]),
#[defined_by(oid::DES_EDE3_CBC_OID)]
DesEde3Cbc([u8; 8]),
#[defined_by(oid::RC2_CBC)]
Rc2Cbc(Rc2CbcParams),
#[defined_by(oid::PBE_WITH_MD5_AND_DES_CBC)]
PbeWithMd5AndDesCbc(PbeParams),
#[defined_by(oid::PBE_WITH_SHA_AND_128_BIT_RC4)]
PbeWithShaAnd128BitRc4(Pkcs12PbeParams<'a>),
#[defined_by(oid::PBE_WITH_SHA_AND_3KEY_TRIPLEDES_CBC)]
PbeWithShaAnd3KeyTripleDesCbc(Pkcs12PbeParams<'a>),
#[defined_by(oid::PBE_WITH_SHA_AND_40_BIT_RC2_CBC)]
PbeWithShaAnd40BitRc2Cbc(Pkcs12PbeParams<'a>),
#[defined_by(oid::MLDSA44_OID)]
Mldsa44,
#[defined_by(oid::MLDSA65_OID)]
Mldsa65,
#[defined_by(oid::MLDSA87_OID)]
Mldsa87,
#[defined_by(oid::MLKEM512_OID)]
MlKem512,
#[defined_by(oid::MLKEM768_OID)]
MlKem768,
#[defined_by(oid::MLKEM1024_OID)]
MlKem1024,
#[defined_by(oid::SLHDSA_SHA2_128S_OID)]
SlhdsaSha2128s,
#[defined_by(oid::SLHDSA_SHA2_128F_OID)]
SlhdsaSha2128f,
#[defined_by(oid::SLHDSA_SHA2_192S_OID)]
SlhdsaSha2192s,
#[defined_by(oid::SLHDSA_SHA2_192F_OID)]
SlhdsaSha2192f,
#[defined_by(oid::SLHDSA_SHA2_256S_OID)]
SlhdsaSha2256s,
#[defined_by(oid::SLHDSA_SHA2_256F_OID)]
SlhdsaSha2256f,
#[defined_by(oid::SLHDSA_SHAKE_128S_OID)]
SlhdsaShake128s,
#[defined_by(oid::SLHDSA_SHAKE_128F_OID)]
SlhdsaShake128f,
#[defined_by(oid::SLHDSA_SHAKE_192S_OID)]
SlhdsaShake192s,
#[defined_by(oid::SLHDSA_SHAKE_192F_OID)]
SlhdsaShake192f,
#[defined_by(oid::SLHDSA_SHAKE_256S_OID)]
SlhdsaShake256s,
#[defined_by(oid::SLHDSA_SHAKE_256F_OID)]
SlhdsaShake256f,
#[default]
Other(asn1::ObjectIdentifier, Option<asn1::Tlv<'a>>),
}
#[derive(asn1::Asn1Read, asn1::Asn1Write, Hash, PartialEq, Eq, Clone)]
pub struct SubjectPublicKeyInfo<'a> {
pub algorithm: AlgorithmIdentifier<'a>,
pub subject_public_key: asn1::BitString<'a>,
}
#[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Eq, Hash, Clone)]
pub struct AttributeTypeValue<'a> {
pub type_id: asn1::ObjectIdentifier,
pub value: AttributeValue<'a>,
}
#[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Eq, Hash, Clone)]
pub enum AttributeValue<'a> {
UniversalString(asn1::UniversalString<'a>),
BmpString(asn1::BMPString<'a>),
PrintableString(asn1::PrintableString<'a>),
AnyString(RawTlv<'a>),
}
impl AttributeValue<'_> {
pub fn tag(&self) -> asn1::Tag {
match self {
AttributeValue::AnyString(tlv) => tlv.tag(),
AttributeValue::PrintableString(_) => asn1::PrintableString::TAG,
AttributeValue::UniversalString(_) => asn1::UniversalString::TAG,
AttributeValue::BmpString(_) => asn1::BMPString::TAG,
}
}
}
#[derive(Hash, PartialEq, Eq, Clone)]
pub struct RawTlv<'a> {
tag: asn1::Tag,
value: &'a [u8],
}
impl<'a> RawTlv<'a> {
pub fn new(tag: asn1::Tag, value: &'a [u8]) -> Self {
RawTlv { tag, value }
}
pub fn tag(&self) -> asn1::Tag {
self.tag
}
pub fn data(&self) -> &'a [u8] {
self.value
}
}
impl<'a> asn1::Asn1Readable<'a> for RawTlv<'a> {
fn parse(parser: &mut asn1::Parser<'a>) -> asn1::ParseResult<Self> {
let tlv = parser.read_element::<asn1::Tlv<'a>>()?;
Ok(RawTlv::new(tlv.tag(), tlv.data()))
}
fn can_parse(_tag: asn1::Tag) -> bool {
true
}
}
impl asn1::Asn1Writable for RawTlv<'_> {
fn write(&self, w: &mut asn1::Writer<'_>) -> asn1::WriteResult {
w.write_tlv(self.tag, Some(self.value.len()), move |dest| {
dest.push_slice(self.value)
})
}
fn encoded_length(&self) -> Option<usize> {
None
}
}
#[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Eq, Hash, Clone)]
pub enum Time {
UtcTime(asn1::UtcTime),
GeneralizedTime(asn1::X509GeneralizedTime),
}
impl Time {
pub fn as_datetime(&self) -> &asn1::DateTime {
match self {
Time::UtcTime(data) => data.as_datetime(),
Time::GeneralizedTime(data) => data.as_datetime(),
}
}
}
#[derive(Hash, PartialEq, Eq, Clone)]
pub enum Asn1ReadableOrWritable<T, U> {
Read(T),
Write(U),
}
impl<T, U> Asn1ReadableOrWritable<T, U> {
pub fn new_read(v: T) -> Self {
Asn1ReadableOrWritable::Read(v)
}
pub fn new_write(v: U) -> Self {
Asn1ReadableOrWritable::Write(v)
}
pub fn unwrap_read(&self) -> &T {
match self {
Asn1ReadableOrWritable::Read(v) => v,
Asn1ReadableOrWritable::Write(_) => {
panic!("unwrap_read called on a Write value")
}
}
}
}
impl<'a, T: asn1::SimpleAsn1Readable<'a>, U> asn1::SimpleAsn1Readable<'a>
for Asn1ReadableOrWritable<T, U>
{
const TAG: asn1::Tag = T::TAG;
fn parse_data(data: &'a [u8]) -> asn1::ParseResult<Self> {
Ok(Self::new_read(T::parse_data(data)?))
}
}
impl<T: asn1::SimpleAsn1Writable, U: asn1::SimpleAsn1Writable>
asn1::SimpleAsn1Writable for Asn1ReadableOrWritable<T, U>
{
const TAG: asn1::Tag = U::TAG;
fn write_data(&self, w: &mut asn1::WriteBuf) -> asn1::WriteResult {
match self {
Asn1ReadableOrWritable::Read(v) => T::write_data(v, w),
Asn1ReadableOrWritable::Write(v) => U::write_data(v, w),
}
}
fn data_length(&self) -> Option<usize> {
match self {
Asn1ReadableOrWritable::Read(v) => T::data_length(v),
Asn1ReadableOrWritable::Write(v) => U::data_length(v),
}
}
}
pub trait Asn1Operation {
type SequenceOfVec<'a, T>
where
T: 'a;
type SetOfVec<'a, T>
where
T: 'a;
type OwnedBitString<'a>;
}
pub struct Asn1Read;
pub struct Asn1Write;
impl Asn1Operation for Asn1Read {
type SequenceOfVec<'a, T>
= asn1::SequenceOf<'a, T>
where
T: 'a;
type SetOfVec<'a, T>
= asn1::SetOf<'a, T>
where
T: 'a;
type OwnedBitString<'a> = asn1::BitString<'a>;
}
impl Asn1Operation for Asn1Write {
type SequenceOfVec<'a, T>
= asn1::SequenceOfWriter<'a, T, Vec<T>>
where
T: 'a;
type SetOfVec<'a, T>
= asn1::SetOfWriter<'a, T, Vec<T>>
where
T: 'a;
type OwnedBitString<'a> = asn1::OwnedBitString;
}
#[derive(asn1::Asn1Read, asn1::Asn1Write)]
pub struct DssSignature<'a> {
pub r: asn1::BigUint<'a>,
pub s: asn1::BigUint<'a>,
}
#[derive(asn1::Asn1Read, asn1::Asn1Write)]
pub struct DHParams<'a> {
pub p: asn1::BigUint<'a>,
pub g: asn1::BigUint<'a>,
pub q: Option<asn1::BigUint<'a>>,
}
#[derive(
asn1::Asn1Read, asn1::Asn1Write, Clone, PartialEq, Eq, Debug, Hash,
)]
pub struct BasicDHParams<'a> {
pub p: asn1::BigUint<'a>,
pub g: asn1::BigUint<'a>,
pub private_value_length: Option<u32>,
}
#[derive(
asn1::Asn1Read, asn1::Asn1Write, Clone, PartialEq, Eq, Debug, Hash,
)]
pub struct DHXParams<'a> {
pub p: asn1::BigUint<'a>,
pub g: asn1::BigUint<'a>,
pub q: asn1::BigUint<'a>,
pub j: Option<asn1::BigUint<'a>>,
pub validation_params: Option<asn1::Sequence<'a>>,
}
pub const PSS_SHA1_HASH_ALG: AlgorithmIdentifier<'_> = AlgorithmIdentifier {
oid: asn1::DefinedByMarker::marker(),
params: AlgorithmParameters::Sha1(Some(())),
};
pub const PSS_SHA256_HASH_ALG: AlgorithmIdentifier<'_> = AlgorithmIdentifier {
oid: asn1::DefinedByMarker::marker(),
params: AlgorithmParameters::Sha256(Some(())),
};
pub const PSS_SHA384_HASH_ALG: AlgorithmIdentifier<'_> = AlgorithmIdentifier {
oid: asn1::DefinedByMarker::marker(),
params: AlgorithmParameters::Sha384(Some(())),
};
pub const PSS_SHA512_HASH_ALG: AlgorithmIdentifier<'_> = AlgorithmIdentifier {
oid: asn1::DefinedByMarker::marker(),
params: AlgorithmParameters::Sha512(Some(())),
};
#[derive(
asn1::Asn1Read, asn1::Asn1Write, Hash, Clone, PartialEq, Eq, Debug,
)]
pub struct MaskGenAlgorithm<'a> {
pub oid: asn1::ObjectIdentifier,
pub params: AlgorithmIdentifier<'a>,
}
pub const PSS_SHA1_MASK_GEN_ALG: MaskGenAlgorithm<'_> = MaskGenAlgorithm {
oid: oid::MGF1_OID,
params: PSS_SHA1_HASH_ALG,
};
pub const PSS_SHA256_MASK_GEN_ALG: MaskGenAlgorithm<'_> = MaskGenAlgorithm {
oid: oid::MGF1_OID,
params: PSS_SHA256_HASH_ALG,
};
pub const PSS_SHA384_MASK_GEN_ALG: MaskGenAlgorithm<'_> = MaskGenAlgorithm {
oid: oid::MGF1_OID,
params: PSS_SHA384_HASH_ALG,
};
pub const PSS_SHA512_MASK_GEN_ALG: MaskGenAlgorithm<'_> = MaskGenAlgorithm {
oid: oid::MGF1_OID,
params: PSS_SHA512_HASH_ALG,
};
#[derive(
asn1::Asn1Read, asn1::Asn1Write, Hash, Clone, PartialEq, Eq, Debug,
)]
pub enum EcParameters<'a> {
NamedCurve(asn1::ObjectIdentifier),
ImplicitCurve(asn1::Null),
SpecifiedCurve(asn1::Sequence<'a>),
}
#[derive(
asn1::Asn1Read, asn1::Asn1Write, Hash, Clone, PartialEq, Eq, Debug,
)]
pub struct RsaPssParameters<'a> {
#[explicit(0)]
#[default(PSS_SHA1_HASH_ALG)]
pub hash_algorithm: AlgorithmIdentifier<'a>,
#[explicit(1)]
#[default(PSS_SHA1_MASK_GEN_ALG)]
pub mask_gen_algorithm: MaskGenAlgorithm<'a>,
#[explicit(2)]
#[default(20u16)]
pub salt_length: u16,
#[explicit(3)]
pub _trailer_field: Option<u8>,
}
#[derive(
asn1::Asn1Read, asn1::Asn1Write, Hash, Clone, PartialEq, Eq, Debug,
)]
pub struct DssParams<'a> {
pub p: asn1::BigUint<'a>,
pub q: asn1::BigUint<'a>,
pub g: asn1::BigUint<'a>,
}
#[derive(
asn1::Asn1Read, asn1::Asn1Write, PartialEq, Eq, Hash, Clone, Debug,
)]
pub struct PBES2Params<'a> {
pub key_derivation_func: Box<AlgorithmIdentifier<'a>>,
pub encryption_scheme: Box<AlgorithmIdentifier<'a>>,
}
const HMAC_SHA1_ALG: AlgorithmIdentifier<'static> = AlgorithmIdentifier {
oid: asn1::DefinedByMarker::marker(),
params: AlgorithmParameters::HmacWithSha1(Some(())),
};
#[derive(
asn1::Asn1Read, asn1::Asn1Write, PartialEq, Eq, Hash, Clone, Debug,
)]
pub struct PBKDF2Params<'a> {
pub salt: &'a [u8],
pub iteration_count: u64,
pub key_length: Option<u64>,
#[default(HMAC_SHA1_ALG)]
pub prf: Box<AlgorithmIdentifier<'a>>,
}
#[derive(
asn1::Asn1Read, asn1::Asn1Write, PartialEq, Eq, Hash, Clone, Debug,
)]
pub struct ScryptParams<'a> {
pub salt: &'a [u8],
pub cost_parameter: u64,
pub block_size: u64,
pub parallelization_parameter: u64,
pub key_length: Option<u32>,
}
#[derive(
asn1::Asn1Read, asn1::Asn1Write, PartialEq, Eq, Hash, Clone, Debug,
)]
pub struct PbeParams {
pub salt: [u8; 8],
pub iterations: u64,
}
#[derive(
asn1::Asn1Read, asn1::Asn1Write, PartialEq, Eq, Hash, Clone, Debug,
)]
pub struct Pkcs12PbeParams<'a> {
pub salt: &'a [u8],
pub iterations: u64,
}
#[derive(
asn1::Asn1Read, asn1::Asn1Write, PartialEq, Eq, Hash, Clone, Debug,
)]
pub struct Rc2CbcParams {
pub version: Option<u32>,
pub iv: [u8; 8],
}
pub struct UnvalidatedVisibleString<'a>(pub &'a str);
impl<'a> UnvalidatedVisibleString<'a> {
pub fn as_str(&self) -> &'a str {
self.0
}
}
impl<'a> asn1::SimpleAsn1Readable<'a> for UnvalidatedVisibleString<'a> {
const TAG: asn1::Tag =
<asn1::VisibleString<'_> as asn1::SimpleAsn1Readable>::TAG;
fn parse_data(data: &'a [u8]) -> asn1::ParseResult<Self> {
Ok(UnvalidatedVisibleString(
std::str::from_utf8(data).map_err(|_| {
asn1::ParseError::new(asn1::ParseErrorKind::InvalidValue)
})?,
))
}
}
impl asn1::SimpleAsn1Writable for UnvalidatedVisibleString<'_> {
const TAG: asn1::Tag = asn1::VisibleString::TAG;
fn write_data(&self, _: &mut asn1::WriteBuf) -> asn1::WriteResult {
unimplemented!();
}
fn data_length(&self) -> Option<usize> {
None
}
}
pub struct Utf8StoredBMPString<'a>(pub &'a str);
impl<'a> Utf8StoredBMPString<'a> {
pub fn new(s: &'a str) -> Self {
Utf8StoredBMPString(s)
}
}
impl asn1::SimpleAsn1Writable for Utf8StoredBMPString<'_> {
const TAG: asn1::Tag = asn1::BMPString::TAG;
fn write_data(&self, writer: &mut asn1::WriteBuf) -> asn1::WriteResult {
for ch in self.0.encode_utf16() {
writer.push_slice(&ch.to_be_bytes())?;
}
Ok(())
}
fn data_length(&self) -> Option<usize> {
Some(self.0.encode_utf16().count() * 2)
}
}
#[derive(Clone)]
pub struct WithTlv<'a, T> {
tlv: asn1::Tlv<'a>,
value: T,
}
impl<'a, T> WithTlv<'a, T> {
pub fn tlv(&self) -> &asn1::Tlv<'a> {
&self.tlv
}
}
impl<T> std::ops::Deref for WithTlv<'_, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.value
}
}
impl<'a, T: asn1::Asn1Readable<'a>> asn1::Asn1Readable<'a> for WithTlv<'a, T> {
fn parse(p: &mut asn1::Parser<'a>) -> asn1::ParseResult<Self> {
let tlv = p.read_element::<asn1::Tlv<'a>>()?;
Ok(Self {
tlv,
value: tlv.parse()?,
})
}
fn can_parse(t: asn1::Tag) -> bool {
T::can_parse(t)
}
}
impl<T: asn1::Asn1Writable> asn1::Asn1Writable for WithTlv<'_, T> {
fn write(&self, w: &mut asn1::Writer<'_>) -> asn1::WriteResult<()> {
self.value.write(w)
}
fn encoded_length(&self) -> Option<usize> {
self.value.encoded_length()
}
}
impl<T: PartialEq> PartialEq for WithTlv<'_, T> {
fn eq(&self, other: &Self) -> bool {
self.value == other.value
}
}
impl<T: Eq> Eq for WithTlv<'_, T> {}
impl<T: std::hash::Hash> std::hash::Hash for WithTlv<'_, T> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.value.hash(state)
}
}
#[cfg(test)]
mod tests {
use asn1::Asn1Readable;
use super::{
Asn1ReadableOrWritable, RawTlv, UnvalidatedVisibleString, WithTlv,
};
#[test]
#[should_panic]
fn test_unvalidated_visible_string_write() {
let v = UnvalidatedVisibleString("foo");
asn1::write_single(&v).unwrap();
}
#[test]
#[should_panic]
fn test_asn1_readable_or_writable_unwrap_read() {
Asn1ReadableOrWritable::<u32, u32>::new_write(17).unwrap_read();
}
#[test]
fn test_asn1_readable_or_writable_write_read_data() {
let v = Asn1ReadableOrWritable::<u32, u32>::new_read(17);
assert_eq!(&asn1::write_single(&v).unwrap(), b"\x02\x01\x11");
}
#[test]
fn test_raw_tlv_can_parse() {
let t = asn1::Tag::from_bytes(&[0]).unwrap().0;
assert!(RawTlv::can_parse(t));
}
#[test]
fn test_with_raw_tlv_can_parse() {
let t = asn1::Tag::from_bytes(&[0x30]).unwrap().0;
assert!(WithTlv::<asn1::Sequence<'_>>::can_parse(t));
assert!(!WithTlv::<bool>::can_parse(t));
}
}