diff --git a/openpgp-card/src/keys.rs b/openpgp-card/src/keys.rs index 9f73a95..8344120 100644 --- a/openpgp-card/src/keys.rs +++ b/openpgp-card/src/keys.rs @@ -16,7 +16,7 @@ use crate::crypto_data::{ }; use crate::openpgp::OpenPgpTransaction; 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. /// @@ -92,10 +92,10 @@ pub(crate) fn gen_key_with_metadata( /// Transform a public key Tlv from the card into PublicKeyMaterial fn tlv_to_pubkey(tlv: &Tlv, algo: &Algo) -> Result { - let n = tlv.find(Tag::from([0x81])); - let v = tlv.find(Tag::from([0x82])); + let n = tlv.find(Tags::PublicKeyDataRsaModulus); + let v = tlv.find(Tags::PublicKeyDataRsaExponent); - let ec = tlv.find(Tag::from([0x86])); + let ec = tlv.find(Tags::PublicKeyDataEccPoint); match (n, v, ec) { (Some(n), Some(v), None) => { @@ -379,7 +379,7 @@ fn rsa_key_import_cmd( // Collect data for "Cardholder private key template" DO (7F48) // // (Describes the content of the Cardholder private key DO) - let mut cpkt_data = vec![]; + let mut cpkt_data: Vec = vec![]; // "Cardholder private key" (5F48) // @@ -388,10 +388,9 @@ fn rsa_key_import_cmd( let mut key_data = Vec::new(); // -- Public exponent: e -- - + cpkt_data.extend(Vec::from(Tags::PrivateKeyDataRsaPublicExponent)); // 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; - cpkt_data.push(0x91); // len_e in bytes has a value of 3-4, it doesn't need TLV encoding 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_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 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 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 { // PQ: 1/q mod p 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)); key_data.extend(pq.iter()); // DP1: d mod (p - 1) 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)); key_data.extend(dp1.iter()); // DQ1: d mod (q - 1) 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)); key_data.extend(dq1.iter()); } @@ -448,7 +447,7 @@ fn rsa_key_import_cmd( // import format requires modulus n field if rsa_attrs.import_format() == 1 || rsa_attrs.import_format() == 3 { 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)); key_data.extend(n.iter()); } @@ -487,7 +486,7 @@ fn ecc_key_import_cmd( let mut key_data = Vec::new(); // 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)); key_data.extend(private); @@ -496,7 +495,7 @@ fn ecc_key_import_cmd( if ecc_attrs.import_format() == Some(0xff) { 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)); key_data.extend(p); diff --git a/openpgp-card/src/lib.rs b/openpgp-card/src/lib.rs index 4165e8a..6dc574e 100644 --- a/openpgp-card/src/lib.rs +++ b/openpgp-card/src/lib.rs @@ -257,6 +257,7 @@ pub(crate) enum Tags { Null, ObjectIdentifier, Sequence, + // GET DATA PrivateUse1, PrivateUse2, @@ -298,6 +299,7 @@ pub(crate) enum Tags { AlgorithmInformation, CertificateSecureMessaging, AttestationCertificate, + // PUT DATA (additional Tags that don't get used for GET DATA) FingerprintSignature, FingerprintDecryption, @@ -310,23 +312,44 @@ pub(crate) enum Tags { GenerationTimeAuthentication, // FIXME: +D1, D2 ResettingCode, + // OTHER // 4.4.3.12 Private Key Template ExtendedHeaderList, CardholderPrivateKeyTemplate, 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, 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 for Vec { + fn from(t: Tags) -> Self { + ShortTag::from(t).into() + } } impl From for Tag { @@ -343,6 +366,7 @@ impl From for ShortTag { Tags::Null => [0x05].into(), Tags::ObjectIdentifier => [0x06].into(), Tags::Sequence => [0x30].into(), + // GET DATA Tags::PrivateUse1 => [0x01, 0x01].into(), Tags::PrivateUse2 => [0x01, 0x02].into(), @@ -384,6 +408,7 @@ impl From for ShortTag { Tags::AlgorithmInformation => [0xfa].into(), Tags::CertificateSecureMessaging => [0xfb].into(), Tags::AttestationCertificate => [0xfc].into(), + // PUT DATA Tags::FingerprintSignature => [0xc7].into(), Tags::FingerprintDecryption => [0xc8].into(), @@ -395,18 +420,38 @@ impl From for ShortTag { Tags::GenerationTimeDecryption => [0xcf].into(), Tags::GenerationTimeAuthentication => [0xd0].into(), Tags::ResettingCode => [0xd3].into(), + // OTHER + // 4.4.3.12 Private Key Template Tags::ExtendedHeaderList => [0x4d].into(), Tags::CardholderPrivateKeyTemplate => [0x7f, 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::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(), } } } @@ -443,6 +488,14 @@ impl From<[u8; 2]> for ShortTag { ShortTag::Two(v[0], v[1]) } } +impl From for Vec { + 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)] pub enum PinType {