use alloc::boxed::Box;
use der::asn1::{BitString, Null, OctetString, Utf8StringRef};
use der::{Choice, Enumerated, Sequence};
use spki::{AlgorithmIdentifierOwned, SubjectPublicKeyInfoOwned};
use x509_cert::attr::Attributes;
use x509_cert::ext::pkix::name::GeneralName;
use cms::enveloped_data::EnvelopedData;
#[derive(Clone, Debug, PartialEq, Eq, Choice)]
#[allow(missing_docs)]
pub enum ProofOfPossession {
#[asn1(context_specific = "0", tag_mode = "IMPLICIT", constructed = "false")]
RaVerified(Null),
#[asn1(context_specific = "1", tag_mode = "IMPLICIT", constructed = "true")]
Signature(Box<PopoSigningKey>),
#[asn1(context_specific = "2", tag_mode = "EXPLICIT", constructed = "true")]
KeyEncipherment(POPOPrivKey),
#[asn1(context_specific = "3", tag_mode = "EXPLICIT", constructed = "true")]
KeyAgreement(POPOPrivKey),
}
#[derive(Clone, Debug, Eq, PartialEq, Sequence)]
#[allow(missing_docs)]
pub struct PopoSigningKey {
#[asn1(
context_specific = "0",
tag_mode = "IMPLICIT",
constructed = "true",
optional = "true"
)]
pub poposk_input: Option<PopoSigningKeyInput>,
pub alg_id: AlgorithmIdentifierOwned,
pub signature: BitString,
}
#[derive(Clone, Debug, Eq, PartialEq, Sequence)]
#[allow(missing_docs)]
pub struct PopoSigningKeyInput {
pub auth_info: PopoSigningKeyInputChoice,
pub public_key: SubjectPublicKeyInfoOwned,
}
#[derive(Clone, Debug, Eq, PartialEq, Choice)]
#[allow(missing_docs)]
pub enum PopoSigningKeyInputChoice {
#[asn1(context_specific = "0", tag_mode = "EXPLICIT", constructed = "true")]
Sender(GeneralName),
PublicKeyMAC(PkMacValue),
}
#[derive(Clone, Debug, Eq, PartialEq, Sequence)]
#[allow(missing_docs)]
pub struct PkMacValue {
pub alg_id: AlgorithmIdentifierOwned,
pub value: BitString,
}
#[derive(Clone, Debug, Eq, PartialEq, Sequence)]
#[allow(missing_docs)]
pub struct PbmParameter {
pub salt: OctetString,
pub owf: AlgorithmIdentifierOwned,
pub iteration_count: u64,
pub mac: AlgorithmIdentifierOwned,
}
#[derive(Clone, Debug, PartialEq, Eq, Choice)]
#[allow(missing_docs)]
pub enum POPOPrivKey {
#[asn1(context_specific = "0", tag_mode = "EXPLICIT", constructed = "false")]
ThisMessage(BitString),
#[asn1(context_specific = "1", tag_mode = "EXPLICIT", constructed = "true")]
SubsequentMessage(SubsequentMessage),
#[asn1(context_specific = "2", tag_mode = "EXPLICIT", constructed = "false")]
DhMac(BitString),
#[asn1(context_specific = "3", tag_mode = "EXPLICIT", constructed = "true")]
AgreeMac(PkMacValue),
#[asn1(context_specific = "4", tag_mode = "EXPLICIT", constructed = "true")]
EncryptedKey(EnvelopedData),
}
#[derive(Clone, Debug, Copy, PartialEq, Eq, Enumerated)]
#[asn1(type = "INTEGER")]
#[repr(u8)]
#[allow(missing_docs)]
pub enum SubsequentMessage {
EncrCert = 0,
ChallengeResp = 1,
}
#[derive(Clone, Debug, Eq, PartialEq, Sequence)]
#[allow(missing_docs)]
pub struct EncKeyWithID<'a> {
pub priv_key: PrivateKeyInfo,
pub identifier: Option<EncKeyWithIdChoice<'a>>,
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[allow(missing_docs)]
pub enum EncKeyWithIdChoice<'a> {
String(Utf8StringRef<'a>),
GeneralName(GeneralName),
}
impl<'a> ::der::Choice<'a> for EncKeyWithIdChoice<'a> {
fn can_decode(tag: ::der::Tag) -> bool {
<Utf8StringRef<'a> as ::der::FixedTag>::TAG == tag || tag.is_context_specific()
}
}
impl<'a> ::der::Decode<'a> for EncKeyWithIdChoice<'a> {
fn decode<R: ::der::Reader<'a>>(reader: &mut R) -> ::der::Result<Self> {
let t = reader.peek_tag()?;
if t == <Utf8StringRef<'a> as ::der::FixedTag>::TAG {
Ok(Self::String(reader.decode()?))
} else if t.is_context_specific() {
Ok(Self::GeneralName(reader.decode()?))
} else {
Err(der::ErrorKind::TagUnexpected {
expected: None,
actual: t,
}
.into())
}
}
}
impl<'a> ::der::EncodeValue for EncKeyWithIdChoice<'a> {
fn encode_value(&self, encoder: &mut impl ::der::Writer) -> ::der::Result<()> {
match self {
Self::String(variant) => variant.encode_value(encoder),
Self::GeneralName(variant) => variant.encode_value(encoder),
}
}
fn value_len(&self) -> ::der::Result<::der::Length> {
match self {
Self::String(variant) => variant.value_len(),
Self::GeneralName(variant) => variant.value_len(),
}
}
}
impl<'a> ::der::Tagged for EncKeyWithIdChoice<'a> {
fn tag(&self) -> ::der::Tag {
match self {
Self::String(_) => <Utf8StringRef<'a> as ::der::FixedTag>::TAG,
Self::GeneralName(_) => self.tag(),
}
}
}
#[derive(Clone, Debug, Eq, PartialEq, Sequence)]
#[allow(missing_docs)]
pub struct PrivateKeyInfo {
pub version: u64,
pub priv_key_alg: AlgorithmIdentifierOwned,
pub priv_key: OctetString,
#[asn1(
context_specific = "0",
tag_mode = "IMPLICIT",
constructed = "true",
optional = "true"
)]
pub attrs: Option<Attributes>,
}