Replace hard coded tag value for Rsa and Ecc params with Tags.
This commit is contained in:
parent
861a051ff5
commit
e49d0bd19b
2 changed files with 81 additions and 29 deletions
|
@ -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);
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue