use enum_display_derive::Display;
use serde_derive::Serialize;
use std::fmt::Display;
use super::common::{
ApplicationData, ApplicationNamespace, AttributeIndex, AttributeName, AttributeValue, CompromiseOccurrenceDate,
CryptographicAlgorithm, CryptographicLength, CryptographicParameters, CryptographicUsageMask, Data, DataLength,
KeyCompressionType, KeyFormatType, KeyMaterial, LinkType, LinkedObjectIdentifier, NameType, NameValue, ObjectType,
Operation, RevocationMessage, RevocationReasonCode, UniqueBatchItemID, UniqueIdentifier,
};
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
#[serde(rename = "0x420008")]
pub struct Attribute(
pub AttributeName,
#[serde(skip_serializing_if = "Option::is_none")] pub Option<AttributeIndex>,
pub AttributeValue,
);
impl Attribute {
#[allow(non_snake_case)]
pub fn UniqueIdentifier(value: String) -> Self {
Attribute(
AttributeName("Unique Identifier".into()),
Option::<AttributeIndex>::None,
AttributeValue::TextString(value),
)
}
#[allow(non_snake_case)]
pub fn Name(value: String) -> Self {
Attribute(
AttributeName("Name".into()),
Option::<AttributeIndex>::None,
AttributeValue::Name(NameValue(value), NameType::UninterpretedTextString),
)
}
#[allow(non_snake_case)]
pub fn URI(value: String) -> Self {
Attribute(
AttributeName("Name".into()),
Option::<AttributeIndex>::None,
AttributeValue::Name(NameValue(value), NameType::URI),
)
}
#[allow(non_snake_case)]
pub fn ObjectType(value: ObjectType) -> Self {
Attribute(
AttributeName("Object Type".into()),
Option::<AttributeIndex>::None,
AttributeValue::ObjectType(value),
)
}
#[allow(non_snake_case)]
pub fn CryptographicAlgorithm(value: CryptographicAlgorithm) -> Self {
Attribute(
AttributeName("Cryptographic Algorithm".into()),
Option::<AttributeIndex>::None,
AttributeValue::CryptographicAlgorithm(value),
)
}
#[allow(non_snake_case)]
pub fn CryptographicLength(value: i32) -> Self {
Attribute(
AttributeName("Cryptographic Length".into()),
Option::<AttributeIndex>::None,
AttributeValue::Integer(value),
)
}
#[allow(non_snake_case)]
pub fn CryptographicParameters(cryptographic_parameters: CryptographicParameters) -> Self {
Attribute(
AttributeName("Cryptographic Parameters".into()),
Option::<AttributeIndex>::None,
cryptographic_parameters.into(),
)
}
#[allow(non_snake_case)]
pub fn OperationPolicyName(value: String) -> Self {
Attribute(
AttributeName("Operation Policy Name".into()),
Option::<AttributeIndex>::None,
AttributeValue::TextString(value),
)
}
#[allow(non_snake_case)]
pub fn CryptographicUsageMask(value: CryptographicUsageMask) -> Self {
Attribute(
AttributeName("Cryptographic Usage Mask".into()),
Option::<AttributeIndex>::None,
AttributeValue::Integer(value as i32),
)
}
#[allow(non_snake_case)]
pub fn ActivationDate(value: u64) -> Self {
Attribute(
AttributeName("Activation Date".into()),
Option::<AttributeIndex>::None,
AttributeValue::DateTime(value),
)
}
#[allow(non_snake_case)]
pub fn ObjectGroup(value: String) -> Self {
Attribute(
AttributeName("Object Group".into()),
Option::<AttributeIndex>::None,
AttributeValue::TextString(value),
)
}
#[allow(non_snake_case)]
pub fn Link(link_type: LinkType, linked_object_identifier: LinkedObjectIdentifier) -> Self {
Attribute(
AttributeName("Link".into()),
Option::<AttributeIndex>::None,
AttributeValue::Link(link_type, linked_object_identifier),
)
}
#[allow(non_snake_case)]
pub fn ApplicationSpecificInformation(
application_namespace: ApplicationNamespace,
application_data: ApplicationData,
) -> Self {
Attribute(
AttributeName("Application Specific Information".into()),
Option::<AttributeIndex>::None,
AttributeValue::ApplicationSpecificInformation(application_namespace, application_data),
)
}
#[allow(non_snake_case)]
pub fn ContactInformation(value: String) -> Self {
Attribute(
AttributeName("Contact Information".into()),
Option::<AttributeIndex>::None,
AttributeValue::ContactInformation(value),
)
}
}
macro_rules! impl_template_attribute_flavour {
($RustType:ident, $TtlvTag:literal) => {
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
#[serde(rename = $TtlvTag)]
pub struct $RustType(
#[serde(skip_serializing_if = "Option::is_none")] pub Option<Vec<Name>>,
#[serde(skip_serializing_if = "Option::is_none")] pub Option<Vec<Attribute>>,
);
impl $RustType {
pub fn unnamed(attributes: Vec<Attribute>) -> Self {
Self(Option::<Vec<Name>>::None, Some(attributes))
}
pub fn named(name: String, attributes: Vec<Attribute>) -> Self {
Self(
Some(vec![Name(NameValue(name), NameType::UninterpretedTextString)]),
Some(attributes),
)
}
}
};
}
impl_template_attribute_flavour!(TemplateAttribute, "0x420091");
impl_template_attribute_flavour!(CommonTemplateAttribute, "0x42001F");
impl_template_attribute_flavour!(PrivateKeyTemplateAttribute, "0x420065");
impl_template_attribute_flavour!(PublicKeyTemplateAttribute, "0x42006E");
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
#[serde(rename = "0x420023")]
pub struct Credential(pub CredentialType, pub CredentialValue);
#[derive(Clone, Copy, Debug, Serialize, Display, PartialEq, Eq)]
#[serde(rename = "0x420024")]
#[non_exhaustive]
pub enum CredentialType {
#[serde(rename = "0x00000001")]
UsernameAndPassword,
}
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
#[serde(rename = "0x420025")]
#[non_exhaustive]
pub enum CredentialValue {
UsernameAndPassword(
Username,
#[serde(skip_serializing_if = "Option::is_none")] Option<Password>,
),
}
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
#[serde(rename = "Transparent:0x420099")]
pub struct Username(pub String);
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
#[serde(rename = "Transparent:0x4200A1")]
pub struct Password(pub String);
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
#[serde(rename = "0x420040")]
pub struct KeyBlock(
pub KeyFormatType,
#[serde(skip_serializing_if = "Option::is_none")] pub Option<KeyCompressionType>,
#[serde(skip_serializing_if = "Option::is_none")] pub Option<KeyValue>,
#[serde(skip_serializing_if = "Option::is_none")] pub Option<CryptographicAlgorithm>,
#[serde(skip_serializing_if = "Option::is_none")] pub Option<CryptographicLength>,
#[serde(skip_serializing_if = "Option::is_none")] pub Option<KeyWrappingData>,
);
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
#[serde(rename = "0x420045")]
pub struct KeyValue(
pub KeyMaterial,
#[serde(skip_serializing_if = "Option::is_none")] pub Option<Vec<Attribute>>,
);
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
#[serde(rename = "0x420046")]
pub struct KeyWrappingData(
pub WrappingMethod,
#[serde(skip_serializing_if = "Option::is_none")] pub Option<EncryptionKeyInformation>,
#[serde(skip_serializing_if = "Option::is_none")] pub Option<MACOrSignatureKeyInformation>,
#[serde(skip_serializing_if = "Option::is_none")] pub Option<MACOrSignature>,
#[serde(skip_serializing_if = "Option::is_none")] pub Option<IVOrCounterOrNonce>,
#[serde(skip_serializing_if = "Option::is_none")] pub Option<Vec<Attribute>>,
);
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
#[serde(rename = "Transparent:0x42004D")]
pub struct MACOrSignature(#[serde(with = "serde_bytes")] Vec<u8>);
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
#[serde(rename = "Transparent:0x42003D")]
pub struct IVOrCounterOrNonce(#[serde(with = "serde_bytes")] Vec<u8>);
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
#[serde(rename = "0x420036")]
pub struct EncryptionKeyInformation(
pub UniqueIdentifier,
#[serde(skip_serializing_if = "Option::is_none")] pub Option<CryptographicParameters>,
);
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
#[serde(rename = "0x42004E")]
pub struct MACOrSignatureKeyInformation(
pub UniqueIdentifier,
#[serde(skip_serializing_if = "Option::is_none")] pub Option<CryptographicParameters>,
);
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
#[serde(rename = "Transparent:0x420047")]
pub struct KeyWrappingSpecification(
pub WrappingMethod,
#[serde(skip_serializing_if = "Option::is_none")] pub Option<EncryptionKeyInformation>,
#[serde(skip_serializing_if = "Option::is_none")] pub Option<MACOrSignatureKeyInformation>,
#[serde(skip_serializing_if = "Option::is_none")] pub Option<Vec<Attribute>>,
);
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
#[serde(untagged)]
#[non_exhaustive]
pub enum ManagedObject {
SymmetricKey(SymmetricKey),
PublicKey(PublicKey),
PrivateKey(PrivateKey),
Template(Template),
}
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
#[serde(rename = "0x42008F")]
pub struct SymmetricKey(pub KeyBlock);
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
#[serde(rename = "0x42006D")]
pub struct PublicKey(pub KeyBlock);
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
#[serde(rename = "0x420064")]
pub struct PrivateKey(pub KeyBlock);
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
#[serde(rename = "0x420090")]
pub struct Template(pub Vec<Attribute>);
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
#[serde(rename = "0x420053")]
pub struct Name(pub NameValue, pub NameType);
impl std::fmt::Display for Name {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_fmt(format_args!("{}", self.0))
}
}
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
#[serde(rename = "0x420081")]
pub struct RevocationReason(
pub RevocationReasonCode,
#[serde(skip_serializing_if = "Option::is_none")] pub Option<RevocationMessage>,
);
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
#[serde(rename = "0x420069")]
pub struct ProtocolVersion(pub ProtocolVersionMajor, pub ProtocolVersionMinor);
#[derive(Clone, Copy, Debug, Serialize, PartialEq, Eq)]
#[serde(rename = "Transparent:0x42006A")]
pub struct ProtocolVersionMajor(pub i32);
#[derive(Clone, Copy, Debug, Serialize, PartialEq, Eq)]
#[serde(rename = "Transparent:0x42006B")]
pub struct ProtocolVersionMinor(pub i32);
#[derive(Clone, Copy, Debug, Serialize, PartialEq, Eq)]
#[serde(rename = "Transparent:0x420050")]
pub struct MaximumResponseSize(pub i32);
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
#[serde(rename = "0x42000C")]
pub struct Authentication(pub Credential);
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
#[serde(rename = "Transparent:0x42000D")]
pub struct BatchCount(pub i32);
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
#[serde(rename = "0x42000F")]
pub struct BatchItem(
pub Operation, )
#[serde(skip_serializing_if = "Option::is_none")] pub Option<UniqueBatchItemID>,
pub RequestPayload,
);
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
#[serde(rename = "0x420078")]
pub struct RequestMessage(pub RequestHeader, pub Vec<BatchItem>);
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
#[serde(rename = "0x420077")]
pub struct RequestHeader(
pub ProtocolVersion,
#[serde(skip_serializing_if = "Option::is_none")] pub Option<MaximumResponseSize>,
#[serde(skip_serializing_if = "Option::is_none")] pub Option<Authentication>,
pub BatchCount,
);
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
#[serde(rename = "0x420079")]
#[non_exhaustive]
#[allow(clippy::large_enum_variant)]
pub enum RequestPayload {
Create(ObjectType, TemplateAttribute),
CreateKeyPair(
#[serde(skip_serializing_if = "Option::is_none")] Option<CommonTemplateAttribute>,
#[serde(skip_serializing_if = "Option::is_none")] Option<PrivateKeyTemplateAttribute>,
#[serde(skip_serializing_if = "Option::is_none")] Option<PublicKeyTemplateAttribute>,
),
Register(
ObjectType,
TemplateAttribute,
#[serde(skip_serializing_if = "Option::is_none")] Option<ManagedObject>,
),
Locate(Vec<Attribute>),
Get(
#[serde(skip_serializing_if = "Option::is_none")] Option<UniqueIdentifier>,
#[serde(skip_serializing_if = "Option::is_none")] Option<KeyFormatType>,
#[serde(skip_serializing_if = "Option::is_none")] Option<KeyCompressionType>,
#[serde(skip_serializing_if = "Option::is_none")] Option<KeyWrappingSpecification>,
),
GetAttributes(
#[serde(skip_serializing_if = "Option::is_none")] Option<UniqueIdentifier>,
#[serde(skip_serializing_if = "Option::is_none")] Option<Vec<AttributeName>>,
),
GetAttributeList(#[serde(skip_serializing_if = "Option::is_none")] Option<UniqueIdentifier>),
AddAttribute(
#[serde(skip_serializing_if = "Option::is_none")] Option<UniqueIdentifier>,
Attribute,
),
ModifyAttribute(
#[serde(skip_serializing_if = "Option::is_none")] Option<UniqueIdentifier>,
Attribute,
),
DeleteAttribute(
#[serde(skip_serializing_if = "Option::is_none")] Option<UniqueIdentifier>,
AttributeName,
#[serde(skip_serializing_if = "Option::is_none")] Option<AttributeIndex>,
),
Activate(#[serde(skip_serializing_if = "Option::is_none")] Option<UniqueIdentifier>),
Revoke(
#[serde(skip_serializing_if = "Option::is_none")] Option<UniqueIdentifier>,
RevocationReason,
#[serde(skip_serializing_if = "Option::is_none")] Option<CompromiseOccurrenceDate>,
),
Destroy(#[serde(skip_serializing_if = "Option::is_none")] Option<UniqueIdentifier>),
Query(Vec<QueryFunction>),
DiscoverVersions(Vec<ProtocolVersion>),
Sign(
#[serde(skip_serializing_if = "Option::is_none")] Option<UniqueIdentifier>,
#[serde(skip_serializing_if = "Option::is_none")] Option<CryptographicParameters>,
Data,
),
RNGRetrieve(DataLength),
}
impl RequestPayload {
pub fn operation(&self) -> Operation {
match self {
RequestPayload::Create(..) => Operation::Create,
RequestPayload::CreateKeyPair(..) => Operation::CreateKeyPair,
RequestPayload::Register(..) => Operation::Register,
RequestPayload::Locate(..) => Operation::Locate,
RequestPayload::Get(..) => Operation::Get,
RequestPayload::GetAttributes(..) => Operation::GetAttributes,
RequestPayload::GetAttributeList(..) => Operation::GetAttributeList,
RequestPayload::AddAttribute(..) => Operation::AddAttribute,
RequestPayload::ModifyAttribute(..) => Operation::ModifyAttribute,
RequestPayload::DeleteAttribute(..) => Operation::DeleteAttribute,
RequestPayload::Activate(..) => Operation::Activate,
RequestPayload::Revoke(..) => Operation::Revoke,
RequestPayload::Destroy(..) => Operation::Destroy,
RequestPayload::Query(..) => Operation::Query,
RequestPayload::DiscoverVersions(..) => Operation::DiscoverVersions,
RequestPayload::Sign(..) => Operation::Sign,
RequestPayload::RNGRetrieve(..) => Operation::RNGRetrieve,
}
}
pub fn protocol_version(&self) -> ProtocolVersion {
match self {
RequestPayload::Create(..)
| RequestPayload::CreateKeyPair(..)
| RequestPayload::Register(..)
| RequestPayload::Locate(..)
| RequestPayload::Get(..)
| RequestPayload::GetAttributes(..)
| RequestPayload::GetAttributeList(..)
| RequestPayload::AddAttribute(..)
| RequestPayload::ModifyAttribute(..)
| RequestPayload::DeleteAttribute(..)
| RequestPayload::Activate(..)
| RequestPayload::Revoke(..)
| RequestPayload::Destroy(..) => {
ProtocolVersion(ProtocolVersionMajor(1), ProtocolVersionMinor(0))
}
RequestPayload::DiscoverVersions(..) => {
ProtocolVersion(ProtocolVersionMajor(1), ProtocolVersionMinor(1))
}
RequestPayload::Sign(..) | RequestPayload::RNGRetrieve(..) => {
ProtocolVersion(ProtocolVersionMajor(1), ProtocolVersionMinor(2))
}
RequestPayload::Query(..) => {
ProtocolVersion(ProtocolVersionMajor(1), ProtocolVersionMinor(2))
}
}
}
}
#[derive(Clone, Copy, Debug, Serialize, Display, PartialEq, Eq)]
#[serde(rename = "0x42009E")]
#[non_exhaustive]
pub enum WrappingMethod {
#[serde(rename = "0x00000001")]
Encrypt,
#[serde(rename = "0x00000002")]
MACSign,
#[serde(rename = "0x00000003")]
EncryptThenMACSign,
#[serde(rename = "0x00000004")]
MACSignThenEncrypt,
#[serde(rename = "0x00000005")]
TR31,
}
#[derive(Clone, Copy, Debug, Serialize, Display, PartialEq, Eq)]
#[serde(rename = "0x420074")]
#[non_exhaustive]
pub enum QueryFunction {
#[serde(rename = "0x00000001")]
QueryOperations,
#[serde(rename = "0x00000002")]
QueryObjects,
#[serde(rename = "0x00000003")]
QueryServerInformation,
}