Replace hard coded tag value for Rsa and Ecc params with Tags.

This commit is contained in:
Heiko Schaefer 2022-05-04 12:13:16 +02:00
parent 861a051ff5
commit e49d0bd19b
No known key found for this signature in database
GPG key ID: 4A849A1904CCBD7D
2 changed files with 81 additions and 29 deletions

View file

@ -16,7 +16,7 @@ use crate::crypto_data::{
}; };
use crate::openpgp::OpenPgpTransaction; use crate::openpgp::OpenPgpTransaction;
use crate::tlv::{length::tlv_encode_length, value::Value, Tlv}; use crate::tlv::{length::tlv_encode_length, value::Value, Tlv};
use crate::{apdu, Error, KeyType, Tag, Tags}; use crate::{apdu, Error, KeyType, Tags};
/// Generate asymmetric key pair on the card. /// Generate asymmetric key pair on the card.
/// ///
@ -92,10 +92,10 @@ pub(crate) fn gen_key_with_metadata(
/// Transform a public key Tlv from the card into PublicKeyMaterial /// Transform a public key Tlv from the card into PublicKeyMaterial
fn tlv_to_pubkey(tlv: &Tlv, algo: &Algo) -> Result<PublicKeyMaterial, crate::Error> { fn tlv_to_pubkey(tlv: &Tlv, algo: &Algo) -> Result<PublicKeyMaterial, crate::Error> {
let n = tlv.find(Tag::from([0x81])); let n = tlv.find(Tags::PublicKeyDataRsaModulus);
let v = tlv.find(Tag::from([0x82])); let v = tlv.find(Tags::PublicKeyDataRsaExponent);
let ec = tlv.find(Tag::from([0x86])); let ec = tlv.find(Tags::PublicKeyDataEccPoint);
match (n, v, ec) { match (n, v, ec) {
(Some(n), Some(v), None) => { (Some(n), Some(v), None) => {
@ -379,7 +379,7 @@ fn rsa_key_import_cmd(
// Collect data for "Cardholder private key template" DO (7F48) // Collect data for "Cardholder private key template" DO (7F48)
// //
// (Describes the content of the Cardholder private key DO) // (Describes the content of the Cardholder private key DO)
let mut cpkt_data = vec![]; let mut cpkt_data: Vec<u8> = vec![];
// "Cardholder private key" (5F48) // "Cardholder private key" (5F48)
// //
@ -388,10 +388,9 @@ fn rsa_key_import_cmd(
let mut key_data = Vec::new(); let mut key_data = Vec::new();
// -- Public exponent: e -- // -- Public exponent: e --
cpkt_data.extend(Vec::from(Tags::PrivateKeyDataRsaPublicExponent));
// Expected length of e in bytes, rounding up from the bit value in algo. // Expected length of e in bytes, rounding up from the bit value in algo.
let len_e_bytes = ((rsa_attrs.len_e() + 7) / 8) as u8; let len_e_bytes = ((rsa_attrs.len_e() + 7) / 8) as u8;
cpkt_data.push(0x91);
// len_e in bytes has a value of 3-4, it doesn't need TLV encoding // len_e in bytes has a value of 3-4, it doesn't need TLV encoding
cpkt_data.push(len_e_bytes); cpkt_data.push(len_e_bytes);
@ -411,11 +410,11 @@ fn rsa_key_import_cmd(
let len_p_bytes: u16 = rsa_attrs.len_n() / 2 / 8; let len_p_bytes: u16 = rsa_attrs.len_n() / 2 / 8;
let len_q_bytes: u16 = rsa_attrs.len_n() / 2 / 8; let len_q_bytes: u16 = rsa_attrs.len_n() / 2 / 8;
cpkt_data.push(0x92); cpkt_data.extend(Vec::from(Tags::PrivateKeyDataRsaPrime1));
// len p in bytes, TLV-encoded // len p in bytes, TLV-encoded
cpkt_data.extend_from_slice(&tlv_encode_length(len_p_bytes)); cpkt_data.extend_from_slice(&tlv_encode_length(len_p_bytes));
cpkt_data.push(0x93); cpkt_data.extend(Vec::from(Tags::PrivateKeyDataRsaPrime2));
// len q in bytes, TLV-encoded // len q in bytes, TLV-encoded
cpkt_data.extend_from_slice(&tlv_encode_length(len_q_bytes)); cpkt_data.extend_from_slice(&tlv_encode_length(len_q_bytes));
@ -428,19 +427,19 @@ fn rsa_key_import_cmd(
if rsa_attrs.import_format() == 2 || rsa_attrs.import_format() == 3 { if rsa_attrs.import_format() == 2 || rsa_attrs.import_format() == 3 {
// PQ: 1/q mod p // PQ: 1/q mod p
let pq = rsa_key.pq(); let pq = rsa_key.pq();
cpkt_data.push(0x94); cpkt_data.extend(Vec::from(Tags::PrivateKeyDataRsaPq));
cpkt_data.extend(&tlv_encode_length(pq.len() as u16)); cpkt_data.extend(&tlv_encode_length(pq.len() as u16));
key_data.extend(pq.iter()); key_data.extend(pq.iter());
// DP1: d mod (p - 1) // DP1: d mod (p - 1)
let dp1 = rsa_key.dp1(); let dp1 = rsa_key.dp1();
cpkt_data.push(0x95); cpkt_data.extend(Vec::from(Tags::PrivateKeyDataRsaDp1));
cpkt_data.extend(&tlv_encode_length(dp1.len() as u16)); cpkt_data.extend(&tlv_encode_length(dp1.len() as u16));
key_data.extend(dp1.iter()); key_data.extend(dp1.iter());
// DQ1: d mod (q - 1) // DQ1: d mod (q - 1)
let dq1 = rsa_key.dq1(); let dq1 = rsa_key.dq1();
cpkt_data.push(0x96); cpkt_data.extend(Vec::from(Tags::PrivateKeyDataRsaDq1));
cpkt_data.extend(&tlv_encode_length(dq1.len() as u16)); cpkt_data.extend(&tlv_encode_length(dq1.len() as u16));
key_data.extend(dq1.iter()); key_data.extend(dq1.iter());
} }
@ -448,7 +447,7 @@ fn rsa_key_import_cmd(
// import format requires modulus n field // import format requires modulus n field
if rsa_attrs.import_format() == 1 || rsa_attrs.import_format() == 3 { if rsa_attrs.import_format() == 1 || rsa_attrs.import_format() == 3 {
let n = rsa_key.n(); let n = rsa_key.n();
cpkt_data.push(0x97); cpkt_data.extend(Vec::from(Tags::PrivateKeyDataRsaModulus));
cpkt_data.extend(&tlv_encode_length(n.len() as u16)); cpkt_data.extend(&tlv_encode_length(n.len() as u16));
key_data.extend(n.iter()); key_data.extend(n.iter());
} }
@ -487,7 +486,7 @@ fn ecc_key_import_cmd(
let mut key_data = Vec::new(); let mut key_data = Vec::new();
// Process "scalar" // Process "scalar"
cpkt_data.push(0x92); cpkt_data.extend(Vec::from(Tags::PrivateKeyDataEccPrivateKey));
cpkt_data.extend_from_slice(&tlv_encode_length(private.len() as u16)); cpkt_data.extend_from_slice(&tlv_encode_length(private.len() as u16));
key_data.extend(private); key_data.extend(private);
@ -496,7 +495,7 @@ fn ecc_key_import_cmd(
if ecc_attrs.import_format() == Some(0xff) { if ecc_attrs.import_format() == Some(0xff) {
let p = ecc_key.public(); let p = ecc_key.public();
cpkt_data.push(0x99); cpkt_data.extend(Vec::from(Tags::PrivateKeyDataEccPublicKey));
cpkt_data.extend_from_slice(&tlv_encode_length(p.len() as u16)); cpkt_data.extend_from_slice(&tlv_encode_length(p.len() as u16));
key_data.extend(p); key_data.extend(p);

View file

@ -257,6 +257,7 @@ pub(crate) enum Tags {
Null, Null,
ObjectIdentifier, ObjectIdentifier,
Sequence, Sequence,
// GET DATA // GET DATA
PrivateUse1, PrivateUse1,
PrivateUse2, PrivateUse2,
@ -298,6 +299,7 @@ pub(crate) enum Tags {
AlgorithmInformation, AlgorithmInformation,
CertificateSecureMessaging, CertificateSecureMessaging,
AttestationCertificate, AttestationCertificate,
// PUT DATA (additional Tags that don't get used for GET DATA) // PUT DATA (additional Tags that don't get used for GET DATA)
FingerprintSignature, FingerprintSignature,
FingerprintDecryption, FingerprintDecryption,
@ -310,23 +312,44 @@ pub(crate) enum Tags {
GenerationTimeAuthentication, GenerationTimeAuthentication,
// FIXME: +D1, D2 // FIXME: +D1, D2
ResettingCode, ResettingCode,
// OTHER // OTHER
// 4.4.3.12 Private Key Template // 4.4.3.12 Private Key Template
ExtendedHeaderList, ExtendedHeaderList,
CardholderPrivateKeyTemplate, CardholderPrivateKeyTemplate,
ConcatenatedKeyData, ConcatenatedKeyData,
// 7.2.14 GENERATE ASYMMETRIC KEY PAIR
PublicKey,
// 7.2.11 PSO: DECIPHER
Cipher,
ExternalPublicKey,
// 7.2.5 SELECT DATA
GeneralReference,
TagList,
// 4.4.3.12 Private Key Template
CrtKeySignature, CrtKeySignature,
CrtKeyConfidentiality, CrtKeyConfidentiality,
CrtKeyAuthentication, 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 { impl From<Tags> for Tag {
@ -343,6 +366,7 @@ impl From<Tags> for ShortTag {
Tags::Null => [0x05].into(), Tags::Null => [0x05].into(),
Tags::ObjectIdentifier => [0x06].into(), Tags::ObjectIdentifier => [0x06].into(),
Tags::Sequence => [0x30].into(), Tags::Sequence => [0x30].into(),
// GET DATA // GET DATA
Tags::PrivateUse1 => [0x01, 0x01].into(), Tags::PrivateUse1 => [0x01, 0x01].into(),
Tags::PrivateUse2 => [0x01, 0x02].into(), Tags::PrivateUse2 => [0x01, 0x02].into(),
@ -384,6 +408,7 @@ impl From<Tags> for ShortTag {
Tags::AlgorithmInformation => [0xfa].into(), Tags::AlgorithmInformation => [0xfa].into(),
Tags::CertificateSecureMessaging => [0xfb].into(), Tags::CertificateSecureMessaging => [0xfb].into(),
Tags::AttestationCertificate => [0xfc].into(), Tags::AttestationCertificate => [0xfc].into(),
// PUT DATA // PUT DATA
Tags::FingerprintSignature => [0xc7].into(), Tags::FingerprintSignature => [0xc7].into(),
Tags::FingerprintDecryption => [0xc8].into(), Tags::FingerprintDecryption => [0xc8].into(),
@ -395,18 +420,38 @@ impl From<Tags> for ShortTag {
Tags::GenerationTimeDecryption => [0xcf].into(), Tags::GenerationTimeDecryption => [0xcf].into(),
Tags::GenerationTimeAuthentication => [0xd0].into(), Tags::GenerationTimeAuthentication => [0xd0].into(),
Tags::ResettingCode => [0xd3].into(), Tags::ResettingCode => [0xd3].into(),
// OTHER // OTHER
// 4.4.3.12 Private Key Template
Tags::ExtendedHeaderList => [0x4d].into(), Tags::ExtendedHeaderList => [0x4d].into(),
Tags::CardholderPrivateKeyTemplate => [0x7f, 0x48].into(), Tags::CardholderPrivateKeyTemplate => [0x7f, 0x48].into(),
Tags::ConcatenatedKeyData => [0x5f, 0x48].into(), Tags::ConcatenatedKeyData => [0x5f, 0x48].into(),
Tags::PublicKey => [0x7f, 0x49].into(),
Tags::Cipher => [0xa6].into(),
Tags::ExternalPublicKey => [0x86].into(),
Tags::GeneralReference => [0x60].into(),
Tags::TagList => [0x5c].into(),
Tags::CrtKeySignature => [0xb6].into(), Tags::CrtKeySignature => [0xb6].into(),
Tags::CrtKeyConfidentiality => [0xb8].into(), Tags::CrtKeyConfidentiality => [0xb8].into(),
Tags::CrtKeyAuthentication => [0xa4].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(),
} }
} }
} }
@ -443,6 +488,14 @@ impl From<[u8; 2]> for ShortTag {
ShortTag::Two(v[0], v[1]) 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],
}
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq)] #[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum PinType { pub enum PinType {