openpgp-card: rename Openpgp and OpenpgpTransaction, restructure modules
This commit is contained in:
parent
01ef1ec4d1
commit
2d1bf919d4
13 changed files with 1537 additions and 1520 deletions
|
@ -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()?;
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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".
|
||||
//
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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]> {
|
||||
|
|
|
@ -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
259
openpgp-card/src/tags.rs
Normal 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],
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in a new issue