openpgp-card: rename Openpgp and OpenpgpTransaction, restructure modules

This commit is contained in:
Heiko Schaefer 2023-08-29 13:18:53 +02:00
parent 01ef1ec4d1
commit 2d1bf919d4
No known key found for this signature in database
GPG key ID: 4A849A1904CCBD7D
13 changed files with 1537 additions and 1520 deletions

View file

@ -8,7 +8,7 @@ use std::string::FromUtf8Error;
use anyhow::Result;
use openpgp_card::algorithm::AlgoSimple;
use openpgp_card::card_do::{KeyGenerationTime, Sex};
use openpgp_card::{Error, KeyType, OpenPgp, StatusBytes};
use openpgp_card::{Error, KeyType, StatusBytes};
use openpgp_card_sequoia::sq_util;
use openpgp_card_sequoia::state::{Admin, Open, Transaction};
use openpgp_card_sequoia::util::{
@ -136,7 +136,10 @@ fn check_key_upload_algo_attrs() -> Result<()> {
Ok(())
}
pub fn test_print_caps(pgp: &mut OpenPgp, _param: &[&str]) -> Result<TestOutput, TestError> {
pub fn test_print_caps(
pgp: &mut openpgp_card::Card,
_param: &[&str],
) -> Result<TestOutput, TestError> {
let mut pgpt = pgp.transaction()?;
let ard = pgpt.application_related_data()?;
@ -156,7 +159,10 @@ pub fn test_print_caps(pgp: &mut OpenPgp, _param: &[&str]) -> Result<TestOutput,
Ok(vec![])
}
pub fn test_print_algo_info(pgp: &mut OpenPgp, _param: &[&str]) -> Result<TestOutput, TestError> {
pub fn test_print_algo_info(
pgp: &mut openpgp_card::Card,
_param: &[&str],
) -> Result<TestOutput, TestError> {
let mut pgpt = pgp.transaction()?;
let ard = pgpt.application_related_data()?;

View file

@ -3,7 +3,7 @@
use anyhow::anyhow;
use openpgp_card::crypto_data::Cryptogram;
use openpgp_card::OpenPgpTransaction;
use openpgp_card::Transaction;
use sequoia_openpgp::crypto::mpi;
use sequoia_openpgp::crypto::SessionKey;
use sequoia_openpgp::packet;
@ -15,7 +15,7 @@ use crate::PublicKey;
pub struct CardDecryptor<'a, 'app> {
/// The OpenPGP card (authenticated to allow decryption operations)
ca: &'a mut OpenPgpTransaction<'app>,
ca: &'a mut Transaction<'app>,
/// The matching public key for the card's decryption key
public: PublicKey,
@ -26,7 +26,7 @@ pub struct CardDecryptor<'a, 'app> {
impl<'a, 'app> CardDecryptor<'a, 'app> {
pub(crate) fn with_pubkey(
ca: &'a mut OpenPgpTransaction<'app>,
ca: &'a mut Transaction<'app>,
public: PublicKey,
touch_prompt: &'a (dyn Fn() + Send + Sync),
) -> CardDecryptor<'a, 'app> {

View file

@ -143,11 +143,11 @@ use card_backend::{CardBackend, SmartcardError};
use openpgp_card::algorithm::{AlgoInfo, AlgoSimple, AlgorithmAttributes};
use openpgp_card::card_do::{
ApplicationIdentifier, CardholderRelatedData, ExtendedCapabilities, ExtendedLengthInfo,
Fingerprint, HistoricalBytes, KeyGenerationTime, KeyInformation, Lang, PWStatusBytes,
Fingerprint, HistoricalBytes, KeyGenerationTime, KeyInformation, KeySet, Lang, PWStatusBytes,
SecuritySupportTemplate, Sex, TouchPolicy, UIF,
};
use openpgp_card::crypto_data::PublicKeyMaterial;
use openpgp_card::{Error, KeySet, KeyType, OpenPgp, OpenPgpTransaction};
use openpgp_card::{Error, KeyType};
use sequoia_openpgp::cert::prelude::ValidErasedKeyAmalgamation;
use sequoia_openpgp::packet::key::SecretParts;
use sequoia_openpgp::packet::{key, Key};
@ -241,7 +241,7 @@ impl Card<Open> {
where
B: Into<Box<dyn CardBackend + Send + Sync>>,
{
let pgp = OpenPgp::new(backend)?;
let pgp = openpgp_card::Card::new(backend)?;
Ok(Card::<Open> {
state: Open { pgp },
@ -265,7 +265,7 @@ impl Card<Open> {
impl<'a> Card<Transaction<'a>> {
// Internal constructor
fn new(mut opt: OpenPgpTransaction<'a>) -> Result<Self, Error> {
fn new(mut opt: openpgp_card::Transaction<'a>) -> Result<Self, Error> {
let ard = opt.application_related_data()?;
Ok(Self {
@ -715,7 +715,7 @@ impl<'a> Card<Transaction<'a>> {
impl<'app, 'open> Card<User<'app, 'open>> {
/// Helper fn to easily access underlying openpgp_card object
fn card(&mut self) -> &mut OpenPgpTransaction<'app> {
fn card(&mut self) -> &mut openpgp_card::Transaction<'app> {
&mut self.state.tx.state.opt
}
@ -767,7 +767,7 @@ impl<'app, 'open> Card<User<'app, 'open>> {
impl<'app, 'open> Card<Sign<'app, 'open>> {
/// Helper fn to easily access underlying openpgp_card object
fn card(&mut self) -> &mut OpenPgpTransaction<'app> {
fn card(&mut self) -> &mut openpgp_card::Transaction<'app> {
&mut self.state.tx.state.opt
}
@ -823,7 +823,7 @@ impl<'app, 'open> Card<Admin<'app, 'open>> {
}
/// Helper fn to easily access underlying openpgp_card object
fn card(&mut self) -> &mut OpenPgpTransaction<'app> {
fn card(&mut self) -> &mut openpgp_card::Transaction<'app> {
&mut self.state.tx.state.opt
}
}

View file

@ -5,7 +5,7 @@ use std::convert::TryInto;
use anyhow::anyhow;
use openpgp_card::crypto_data::Hash;
use openpgp_card::OpenPgpTransaction;
use openpgp_card::Transaction;
use sequoia_openpgp::crypto;
use sequoia_openpgp::crypto::mpi;
use sequoia_openpgp::types::{Curve, PublicKeyAlgorithm};
@ -14,7 +14,7 @@ use crate::PublicKey;
pub struct CardSigner<'a, 'app> {
/// The OpenPGP card (authenticated to allow signing operations)
ca: &'a mut OpenPgpTransaction<'app>,
ca: &'a mut Transaction<'app>,
/// The matching public key for the card's signing key
public: PublicKey,
@ -28,7 +28,7 @@ pub struct CardSigner<'a, 'app> {
impl<'a, 'app> CardSigner<'a, 'app> {
pub(crate) fn with_pubkey(
ca: &'a mut OpenPgpTransaction<'app>,
ca: &'a mut Transaction<'app>,
public: PublicKey,
touch_prompt: &'a (dyn Fn() + Send + Sync),
) -> CardSigner<'a, 'app> {
@ -41,7 +41,7 @@ impl<'a, 'app> CardSigner<'a, 'app> {
}
pub(crate) fn with_pubkey_for_auth(
ca: &'a mut OpenPgpTransaction<'app>,
ca: &'a mut Transaction<'app>,
public: PublicKey,
touch_prompt: &'a (dyn Fn() + Send + Sync),
) -> CardSigner<'a, 'app> {
@ -84,9 +84,9 @@ impl<'a, 'app> crypto::Signer for CardSigner<'a, 'app> {
};
let sig_fn = if !self.auth {
OpenPgpTransaction::signature_for_hash
Transaction::signature_for_hash
} else {
OpenPgpTransaction::authenticate_for_hash
Transaction::authenticate_for_hash
};
// Delegate a signing (or auth) operation to the OpenPGP card.

View file

@ -4,7 +4,6 @@
//! States of a card are modeled by the types `Open`, `Transaction`, `User`, `Sign`, `Admin`.
use openpgp_card::card_do::ApplicationRelatedData;
use openpgp_card::{OpenPgp, OpenPgpTransaction};
use crate::Card;
@ -23,7 +22,7 @@ impl State for Admin<'_, '_> {}
///
/// A transaction can be started on the card, in this state.
pub struct Open {
pub(crate) pgp: OpenPgp,
pub(crate) pgp: openpgp_card::Card,
}
/// State of an OpenPGP card once a transaction has been started.
@ -34,7 +33,7 @@ pub struct Open {
///
/// (Note that a factory-reset can be performed in this base state.)
pub struct Transaction<'a> {
pub(crate) opt: OpenPgpTransaction<'a>,
pub(crate) opt: openpgp_card::Transaction<'a>,
// Cache of "application related data".
//

View file

@ -1,15 +1,16 @@
// SPDX-FileCopyrightText: 2021-2022 Heiko Schaefer <heiko@schaefer.name>
// SPDX-FileCopyrightText: 2021-2023 Heiko Schaefer <heiko@schaefer.name>
// SPDX-License-Identifier: MIT OR Apache-2.0
//! Pre-defined `Command` values for the OpenPGP card application
use crate::apdu::command::Command;
use crate::{KeyType, ShortTag, Tags, OP_APP};
use crate::tags::{ShortTag, Tags};
use crate::{KeyType, OPENPGP_APPLICATION};
/// 7.2.1 SELECT
/// (select the OpenPGP application on the card)
pub(crate) fn select_openpgp() -> Command {
Command::new(0x00, 0xA4, 0x04, 0x00, OP_APP.to_vec())
Command::new(0x00, 0xA4, 0x04, 0x00, OPENPGP_APPLICATION.to_vec())
}
/// 7.2.6 GET DATA

View file

@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2021-2022 Heiko Schaefer <heiko@schaefer.name>
// SPDX-FileCopyrightText: 2021-2023 Heiko Schaefer <heiko@schaefer.name>
// SPDX-License-Identifier: MIT OR Apache-2.0
//! OpenPGP card data objects (DO)
@ -9,7 +9,8 @@ use std::time::{Duration, UNIX_EPOCH};
use chrono::{DateTime, Utc};
use crate::{algorithm::AlgorithmAttributes, tlv::Tlv, Error, KeySet, KeyType, Tags};
use crate::tags::Tags;
use crate::{algorithm::AlgorithmAttributes, tlv::Tlv, Error, KeyType};
mod algo_attrs;
mod algo_info;
@ -22,7 +23,7 @@ mod historical;
mod key_generation_times;
mod pw_status;
/// 4.4.3.1 Application Related Data
/// Application Related Data [Spec section 4.4.3.1]
///
/// The "application related data" DO contains a set of DOs.
/// This struct offers read access to these DOs.
@ -274,7 +275,7 @@ impl ApplicationRelatedData {
}
}
/// Security support template (see spec pg. 24)
/// Security support template [Spec page 24]
#[derive(Debug)]
pub struct SecuritySupportTemplate {
// Digital signature counter [3 bytes]
@ -288,7 +289,7 @@ impl SecuritySupportTemplate {
}
}
/// An OpenPGP key generation Time (see spec pg. 24)
/// An OpenPGP key generation Time [Spec page 24]
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
pub struct KeyGenerationTime(u32);
@ -309,7 +310,7 @@ impl Display for KeyGenerationTime {
}
}
/// User Interaction Flag (UIF) (see spec pg. 24)
/// User Interaction Flag (UIF) [Spec page 24]
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
pub struct UIF([u8; 2]);
@ -422,7 +423,7 @@ impl From<u8> for TouchPolicy {
}
}
/// "additional hardware for user interaction" (see spec 4.1.3.2)
/// "additional hardware for user interaction" [Spec section 4.1.3.2]
pub struct Features(u8);
impl From<u8> for Features {
@ -464,7 +465,7 @@ impl Display for Features {
}
}
/// 4.4.3.8 Key Information
/// Key Information [Spec section 4.4.3.8]
pub struct KeyInformation(Vec<u8>);
impl From<Vec<u8>> for KeyInformation {
@ -583,7 +584,7 @@ impl Display for KeyStatus {
}
}
/// 4.2.1 Application Identifier (AID)
/// Application Identifier (AID) [Spec section 4.2.1]
#[derive(Debug, Eq, PartialEq)]
pub struct ApplicationIdentifier {
application: u8,
@ -602,7 +603,7 @@ impl Display for ApplicationIdentifier {
}
}
/// 6 Historical Bytes
/// Historical Bytes [Spec chapter 6]
#[derive(Debug, PartialEq, Eq)]
pub struct HistoricalBytes {
/// category indicator byte
@ -618,7 +619,7 @@ pub struct HistoricalBytes {
sib: u8,
}
/// Card Capabilities (see 6 Historical Bytes)
/// Card Capabilities [Spec chapter 6 (Historical Bytes)]
#[derive(Debug, PartialEq, Eq)]
pub struct CardCapabilities {
command_chaining: bool,
@ -642,7 +643,7 @@ impl Display for CardCapabilities {
}
}
/// Card service data (see 6 Historical Bytes)
/// Card service data [Spec chapter 6 (Historical Bytes)]
#[derive(Debug, PartialEq, Eq)]
pub struct CardServiceData {
select_by_full_df_name: bool, // Application Selection by full DF name (AID)
@ -689,7 +690,7 @@ impl Display for CardServiceData {
}
}
/// 4.4.3.7 Extended Capabilities
/// Extended Capabilities [Spec section 4.4.3.7]
#[derive(Debug, Eq, PartialEq)]
pub struct ExtendedCapabilities {
secure_messaging: bool,
@ -779,7 +780,7 @@ impl Display for ExtendedCapabilities {
}
}
/// 4.1.3.1 Extended length information
/// Extended length information [Spec section 4.1.3.1]
#[derive(Debug, Eq, PartialEq)]
pub struct ExtendedLengthInfo {
max_command_bytes: u16,
@ -794,7 +795,7 @@ impl Display for ExtendedLengthInfo {
}
}
/// Cardholder Related Data (see spec pg. 22)
/// Cardholder Related Data [Spec page 22]
#[derive(Debug, PartialEq, Eq)]
pub struct CardholderRelatedData {
name: Option<Vec<u8>>,
@ -819,7 +820,7 @@ impl Display for CardholderRelatedData {
}
}
/// 4.4.3.5 Sex
/// Sex [Spec section 4.4.3.5]
///
/// Encoded in accordance with <https://en.wikipedia.org/wiki/ISO/IEC_5218>
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
@ -867,7 +868,9 @@ impl From<u8> for Sex {
}
}
/// Individual language for Language Preferences (4.4.3.4), accessible via `CardholderRelatedData`.
/// Individual language for Language Preferences [Spec section 4.4.3.4]
///
/// This field is accessible via `CardholderRelatedData`.
///
/// Encoded according to <https://en.wikipedia.org/wiki/ISO_639-1>
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
@ -922,7 +925,7 @@ impl From<&[u8; 2]> for Lang {
}
}
/// PW status Bytes (see spec page 23)
/// PW status Bytes [Spec page 23]
#[derive(Debug, PartialEq, Eq)]
pub struct PWStatusBytes {
pub(crate) pw1_cds_valid_once: bool,
@ -992,7 +995,7 @@ impl PWStatusBytes {
}
}
/// Fingerprint (see spec pg. 23)
/// Fingerprint [Spec page 23]
#[derive(Clone, Eq, PartialEq)]
pub struct Fingerprint([u8; 20]);
@ -1026,3 +1029,35 @@ pub(crate) fn complete<O>(result: nom::IResult<&[u8], O>) -> Result<O, Error> {
)))
}
}
/// A KeySet binds together a triple of information about each Key slot on a card
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct KeySet<T> {
signature: Option<T>,
decryption: Option<T>,
authentication: Option<T>,
}
impl<T> From<(Option<T>, Option<T>, Option<T>)> for KeySet<T> {
fn from(tuple: (Option<T>, Option<T>, Option<T>)) -> Self {
Self {
signature: tuple.0,
decryption: tuple.1,
authentication: tuple.2,
}
}
}
impl<T> KeySet<T> {
pub fn signature(&self) -> Option<&T> {
self.signature.as_ref()
}
pub fn decryption(&self) -> Option<&T> {
self.decryption.as_ref()
}
pub fn authentication(&self) -> Option<&T> {
self.authentication.as_ref()
}
}

View file

@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2021-2022 Heiko Schaefer <heiko@schaefer.name>
// SPDX-FileCopyrightText: 2021-2023 Heiko Schaefer <heiko@schaefer.name>
// SPDX-License-Identifier: MIT OR Apache-2.0
//! Cardholder Related Data (see spec pg. 22)
@ -6,8 +6,8 @@
use std::convert::TryFrom;
use crate::card_do::{CardholderRelatedData, Lang, Sex};
use crate::tags::Tags;
use crate::tlv::{value::Value, Tlv};
use crate::Tags;
impl CardholderRelatedData {
pub fn name(&self) -> Option<&[u8]> {

View file

@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2021-2022 Heiko Schaefer <heiko@schaefer.name>
// SPDX-FileCopyrightText: 2021-2023 Heiko Schaefer <heiko@schaefer.name>
// SPDX-License-Identifier: MIT OR Apache-2.0
//! Generate and import keys
@ -14,9 +14,9 @@ use crate::crypto_data::{
CardUploadableKey, EccKey, EccPub, EccType, PrivateKeyMaterial, PublicKeyMaterial, RSAKey,
RSAPub,
};
use crate::openpgp::OpenPgpTransaction;
use crate::tags::Tags;
use crate::tlv::{length::tlv_encode_length, value::Value, Tlv};
use crate::{Error, KeyType, Tag, Tags};
use crate::{Error, KeyType, Tag, Transaction};
/// Generate asymmetric key pair on the card.
///
@ -29,7 +29,7 @@ use crate::{Error, KeyType, Tag, Tags};
/// `fp_from_pub` calculates the fingerprint for a public key data object and
/// creation timestamp
pub(crate) fn gen_key_with_metadata(
card_tx: &mut OpenPgpTransaction,
card_tx: &mut Transaction,
fp_from_pub: fn(&PublicKeyMaterial, KeyGenerationTime, KeyType) -> Result<Fingerprint, Error>,
key_type: KeyType,
algo: Option<&AlgorithmAttributes>,
@ -121,7 +121,7 @@ fn tlv_to_pubkey(tlv: &Tlv, algo: &AlgorithmAttributes) -> Result<PublicKeyMater
/// This runs the low level key generation primitive on the card.
/// (This does not set algorithm attributes, creation time or fingerprint)
pub(crate) fn generate_asymmetric_key_pair(
card_tx: &mut OpenPgpTransaction,
card_tx: &mut Transaction,
key_type: KeyType,
) -> Result<Tlv, Error> {
log::info!("OpenPgpTransaction: generate_asymmetric_key_pair");
@ -145,7 +145,7 @@ pub(crate) fn generate_asymmetric_key_pair(
///
/// (See 7.2.14 GENERATE ASYMMETRIC KEY PAIR)
pub(crate) fn public_key(
card_tx: &mut OpenPgpTransaction,
card_tx: &mut Transaction,
key_type: KeyType,
) -> Result<PublicKeyMaterial, Error> {
log::info!("OpenPgpTransaction: public_key");
@ -173,7 +173,7 @@ pub(crate) fn public_key(
/// caused by checks before attempting to upload the key to the card, or by
/// an error that the card reports during an attempt to upload the key).
pub(crate) fn key_import(
card_tx: &mut OpenPgpTransaction,
card_tx: &mut Transaction,
key: Box<dyn CardUploadableKey>,
key_type: KeyType,
algo_info: Option<AlgoInfo>,

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

259
openpgp-card/src/tags.rs Normal file
View file

@ -0,0 +1,259 @@
// SPDX-FileCopyrightText: 2021-2023 Heiko Schaefer <heiko@schaefer.name>
// SPDX-License-Identifier: MIT OR Apache-2.0
use crate::tlv::tag::Tag;
/// Tags, as specified and used in the OpenPGP card 3.4.1 spec.
/// All tags in OpenPGP card are either 1 or 2 bytes long.
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
#[non_exhaustive]
#[allow(dead_code)]
pub(crate) enum Tags {
// BER identifiers
OctetString,
Null,
ObjectIdentifier,
Sequence,
// GET DATA
PrivateUse1,
PrivateUse2,
PrivateUse3,
PrivateUse4,
ApplicationIdentifier,
LoginData,
Url,
HistoricalBytes,
CardholderRelatedData,
Name,
LanguagePref,
Sex,
ApplicationRelatedData,
ExtendedLengthInformation,
GeneralFeatureManagement,
DiscretionaryDataObjects,
ExtendedCapabilities,
AlgorithmAttributesSignature,
AlgorithmAttributesDecryption,
AlgorithmAttributesAuthentication,
PWStatusBytes,
Fingerprints,
CaFingerprints,
GenerationTimes,
KeyInformation,
UifSig,
UifDec,
UifAuth,
UifAttestation,
SecuritySupportTemplate,
DigitalSignatureCounter,
CardholderCertificate,
AlgorithmAttributesAttestation,
FingerprintAttestation,
CaFingerprintAttestation,
GenerationTimeAttestation,
KdfDo,
AlgorithmInformation,
CertificateSecureMessaging,
AttestationCertificate,
// PUT DATA (additional Tags that don't get used for GET DATA)
FingerprintSignature,
FingerprintDecryption,
FingerprintAuthentication,
CaFingerprint1,
CaFingerprint2,
CaFingerprint3,
GenerationTimeSignature,
GenerationTimeDecryption,
GenerationTimeAuthentication,
// FIXME: +D1, D2
ResettingCode,
PsoEncDecKey,
// OTHER
// 4.4.3.12 Private Key Template
ExtendedHeaderList,
CardholderPrivateKeyTemplate,
ConcatenatedKeyData,
CrtKeySignature,
CrtKeyConfidentiality,
CrtKeyAuthentication,
PrivateKeyDataRsaPublicExponent,
PrivateKeyDataRsaPrime1,
PrivateKeyDataRsaPrime2,
PrivateKeyDataRsaPq,
PrivateKeyDataRsaDp1,
PrivateKeyDataRsaDq1,
PrivateKeyDataRsaModulus,
PrivateKeyDataEccPrivateKey,
PrivateKeyDataEccPublicKey,
// 7.2.14 GENERATE ASYMMETRIC KEY PAIR
PublicKey,
PublicKeyDataRsaModulus,
PublicKeyDataRsaExponent,
PublicKeyDataEccPoint,
// 7.2.11 PSO: DECIPHER
Cipher,
ExternalPublicKey,
// 7.2.5 SELECT DATA
GeneralReference,
TagList,
}
impl From<Tags> for Vec<u8> {
fn from(t: Tags) -> Self {
ShortTag::from(t).into()
}
}
impl From<Tags> for Tag {
fn from(t: Tags) -> Self {
ShortTag::from(t).into()
}
}
impl From<Tags> for ShortTag {
fn from(t: Tags) -> Self {
match t {
// BER identifiers https://en.wikipedia.org/wiki/X.690#BER_encoding
Tags::OctetString => [0x04].into(),
Tags::Null => [0x05].into(),
Tags::ObjectIdentifier => [0x06].into(),
Tags::Sequence => [0x30].into(),
// GET DATA
Tags::PrivateUse1 => [0x01, 0x01].into(),
Tags::PrivateUse2 => [0x01, 0x02].into(),
Tags::PrivateUse3 => [0x01, 0x03].into(),
Tags::PrivateUse4 => [0x01, 0x04].into(),
Tags::ApplicationIdentifier => [0x4f].into(),
Tags::LoginData => [0x5e].into(),
Tags::Url => [0x5f, 0x50].into(),
Tags::HistoricalBytes => [0x5f, 0x52].into(),
Tags::CardholderRelatedData => [0x65].into(),
Tags::Name => [0x5b].into(),
Tags::LanguagePref => [0x5f, 0x2d].into(),
Tags::Sex => [0x5f, 0x35].into(),
Tags::ApplicationRelatedData => [0x6e].into(),
Tags::ExtendedLengthInformation => [0x7f, 0x66].into(),
Tags::GeneralFeatureManagement => [0x7f, 0x74].into(),
Tags::DiscretionaryDataObjects => [0x73].into(),
Tags::ExtendedCapabilities => [0xc0].into(),
Tags::AlgorithmAttributesSignature => [0xc1].into(),
Tags::AlgorithmAttributesDecryption => [0xc2].into(),
Tags::AlgorithmAttributesAuthentication => [0xc3].into(),
Tags::PWStatusBytes => [0xc4].into(),
Tags::Fingerprints => [0xc5].into(),
Tags::CaFingerprints => [0xc6].into(),
Tags::GenerationTimes => [0xcd].into(),
Tags::KeyInformation => [0xde].into(),
Tags::UifSig => [0xd6].into(),
Tags::UifDec => [0xd7].into(),
Tags::UifAuth => [0xd8].into(),
Tags::UifAttestation => [0xd9].into(),
Tags::SecuritySupportTemplate => [0x7a].into(),
Tags::DigitalSignatureCounter => [0x93].into(),
Tags::CardholderCertificate => [0x7f, 0x21].into(),
Tags::AlgorithmAttributesAttestation => [0xda].into(),
Tags::FingerprintAttestation => [0xdb].into(),
Tags::CaFingerprintAttestation => [0xdc].into(),
Tags::GenerationTimeAttestation => [0xdd].into(),
Tags::KdfDo => [0xf9].into(),
Tags::AlgorithmInformation => [0xfa].into(),
Tags::CertificateSecureMessaging => [0xfb].into(),
Tags::AttestationCertificate => [0xfc].into(),
// PUT DATA
Tags::FingerprintSignature => [0xc7].into(),
Tags::FingerprintDecryption => [0xc8].into(),
Tags::FingerprintAuthentication => [0xc9].into(),
Tags::CaFingerprint1 => [0xca].into(),
Tags::CaFingerprint2 => [0xcb].into(),
Tags::CaFingerprint3 => [0xcc].into(),
Tags::GenerationTimeSignature => [0xce].into(),
Tags::GenerationTimeDecryption => [0xcf].into(),
Tags::GenerationTimeAuthentication => [0xd0].into(),
Tags::ResettingCode => [0xd3].into(),
Tags::PsoEncDecKey => [0xd5].into(),
// OTHER
// 4.4.3.12 Private Key Template
Tags::ExtendedHeaderList => [0x4d].into(),
Tags::CardholderPrivateKeyTemplate => [0x7f, 0x48].into(),
Tags::ConcatenatedKeyData => [0x5f, 0x48].into(),
Tags::CrtKeySignature => [0xb6].into(),
Tags::CrtKeyConfidentiality => [0xb8].into(),
Tags::CrtKeyAuthentication => [0xa4].into(),
Tags::PrivateKeyDataRsaPublicExponent => [0x91].into(),
Tags::PrivateKeyDataRsaPrime1 => [0x92].into(), // Note: value reused!
Tags::PrivateKeyDataRsaPrime2 => [0x93].into(),
Tags::PrivateKeyDataRsaPq => [0x94].into(),
Tags::PrivateKeyDataRsaDp1 => [0x95].into(),
Tags::PrivateKeyDataRsaDq1 => [0x96].into(),
Tags::PrivateKeyDataRsaModulus => [0x97].into(),
Tags::PrivateKeyDataEccPrivateKey => [0x92].into(), // Note: value reused!
Tags::PrivateKeyDataEccPublicKey => [0x99].into(),
// 7.2.14 GENERATE ASYMMETRIC KEY PAIR
Tags::PublicKey => [0x7f, 0x49].into(),
Tags::PublicKeyDataRsaModulus => [0x81].into(),
Tags::PublicKeyDataRsaExponent => [0x82].into(),
Tags::PublicKeyDataEccPoint => [0x86].into(),
// 7.2.11 PSO: DECIPHER
Tags::Cipher => [0xa6].into(),
Tags::ExternalPublicKey => [0x86].into(),
// 7.2.5 SELECT DATA
Tags::GeneralReference => [0x60].into(),
Tags::TagList => [0x5c].into(),
}
}
}
/// A ShortTag is a Tlv tag that is guaranteed to be either 1 or 2 bytes long.
///
/// This covers any tag that can be used in the OpenPGP card context (the spec doesn't describe how
/// longer tags might be used.)
///
/// (The type tlv::Tag will usually/always contain 1 or 2 byte long tags, in this library.
/// But its length is not guaranteed by the type system)
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum ShortTag {
One(u8),
Two(u8, u8),
}
impl From<ShortTag> for Tag {
fn from(n: ShortTag) -> Self {
match n {
ShortTag::One(t0) => [t0].into(),
ShortTag::Two(t0, t1) => [t0, t1].into(),
}
}
}
impl From<[u8; 1]> for ShortTag {
fn from(v: [u8; 1]) -> Self {
ShortTag::One(v[0])
}
}
impl From<[u8; 2]> for ShortTag {
fn from(v: [u8; 2]) -> Self {
ShortTag::Two(v[0], v[1])
}
}
impl From<ShortTag> for Vec<u8> {
fn from(t: ShortTag) -> Self {
match t {
ShortTag::One(t0) => vec![t0],
ShortTag::Two(t0, t1) => vec![t0, t1],
}
}
}

View file

@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2021-2022 Heiko Schaefer <heiko@schaefer.name>
// SPDX-FileCopyrightText: 2021-2023 Heiko Schaefer <heiko@schaefer.name>
// SPDX-License-Identifier: MIT OR Apache-2.0
pub(crate) mod length;
@ -87,7 +87,8 @@ mod test {
use hex_literal::hex;
use super::{Tlv, Value};
use crate::{Error, Tags};
use crate::tags::Tags;
use crate::Error;
#[test]
fn test_tlv0() {