Move the code that creates a DO for setting algorithm attributes into Algo.
This commit is contained in:
parent
5fcb454b9c
commit
bc7dede0ac
2 changed files with 63 additions and 61 deletions
|
@ -10,7 +10,7 @@
|
|||
//! specifically for key generation on the card.
|
||||
|
||||
use crate::crypto_data::EccType;
|
||||
use crate::KeyType;
|
||||
use crate::{Error, KeyType};
|
||||
|
||||
use anyhow::anyhow;
|
||||
use std::convert::TryFrom;
|
||||
|
@ -173,6 +173,62 @@ impl fmt::Display for Algo {
|
|||
}
|
||||
}
|
||||
|
||||
impl Algo {
|
||||
/// Get a DO representation of the Algo, for setting algorithm
|
||||
/// attributes on the card.
|
||||
pub(crate) fn get_data(&self) -> Result<Vec<u8>, Error> {
|
||||
match self {
|
||||
Algo::Rsa(rsa) => Self::rsa_algo_attrs(rsa),
|
||||
Algo::Ecc(ecc) => Self::ecc_algo_attrs(ecc.oid(), ecc.ecc_type()),
|
||||
_ => Err(anyhow!("Unexpected Algo {:?}", self).into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper: generate `data` for algorithm attributes with RSA
|
||||
fn rsa_algo_attrs(algo_attrs: &RsaAttrs) -> Result<Vec<u8>, Error> {
|
||||
// Algorithm ID (01 = RSA (Encrypt or Sign))
|
||||
let mut algo_attributes = vec![0x01];
|
||||
|
||||
// Length of modulus n in bit
|
||||
algo_attributes.extend(&algo_attrs.len_n().to_be_bytes());
|
||||
|
||||
// Length of public exponent e in bit
|
||||
algo_attributes.push(0x00);
|
||||
algo_attributes.push(algo_attrs.len_e() as u8);
|
||||
|
||||
// Import-Format of private key
|
||||
// (This fn currently assumes import_format "00 = standard (e, p, q)")
|
||||
if algo_attrs.import_format() != 0 {
|
||||
return Err(anyhow!(
|
||||
"Unexpected RSA input format (only 0 is supported)"
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
||||
algo_attributes.push(algo_attrs.import_format());
|
||||
|
||||
Ok(algo_attributes)
|
||||
}
|
||||
|
||||
/// Helper: generate `data` for algorithm attributes with ECC
|
||||
fn ecc_algo_attrs(
|
||||
oid: &[u8],
|
||||
ecc_type: EccType,
|
||||
) -> Result<Vec<u8>, Error> {
|
||||
let algo_id = match ecc_type {
|
||||
EccType::EdDSA => 0x16,
|
||||
EccType::ECDH => 0x12,
|
||||
EccType::ECDSA => 0x13,
|
||||
};
|
||||
|
||||
let mut algo_attributes = vec![algo_id];
|
||||
algo_attributes.extend(oid);
|
||||
// Leave Import-Format unset, for default (pg. 35)
|
||||
|
||||
Ok(algo_attributes)
|
||||
}
|
||||
}
|
||||
|
||||
/// RSA specific attributes of [`Algo`] ("Algorithm Attributes")
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct RsaAttrs {
|
||||
|
|
|
@ -9,14 +9,14 @@ use std::convert::TryInto;
|
|||
|
||||
use anyhow::{anyhow, Result};
|
||||
|
||||
use crate::algorithm::{Algo, AlgoInfo, AlgoSimple, RsaAttrs};
|
||||
use crate::algorithm::{Algo, AlgoInfo, AlgoSimple};
|
||||
use crate::apdu::{commands, response::Response};
|
||||
use crate::card_do::{
|
||||
ApplicationRelatedData, CardholderRelatedData, Fingerprint,
|
||||
KeyGenerationTime, PWStatusBytes, SecuritySupportTemplate, Sex,
|
||||
};
|
||||
use crate::crypto_data::{
|
||||
CardUploadableKey, Cryptogram, EccType, Hash, PublicKeyMaterial,
|
||||
CardUploadableKey, Cryptogram, Hash, PublicKeyMaterial,
|
||||
};
|
||||
use crate::tlv::{tag::Tag, value::Value, Tlv};
|
||||
use crate::Error;
|
||||
|
@ -572,69 +572,15 @@ impl CardApp {
|
|||
key_type: KeyType,
|
||||
algo: &Algo,
|
||||
) -> Result<Response, Error> {
|
||||
// FIXME: caching?
|
||||
let ard = self.get_application_related_data()?;
|
||||
|
||||
// FIXME: Only write algo attributes to the card if "extended
|
||||
// capabilities" show that they are changeable!
|
||||
|
||||
// FIXME: reuse "e" from card, if no algo list is available
|
||||
let _cur_algo = ard.get_algorithm_attributes(key_type)?;
|
||||
|
||||
let data = match algo {
|
||||
Algo::Rsa(rsa) => Self::rsa_algo_attrs(rsa)?,
|
||||
Algo::Ecc(ecc) => Self::ecc_algo_attrs(ecc.oid(), ecc.ecc_type()),
|
||||
_ => {
|
||||
return Err(anyhow!("Unexpected Algo {:?}", algo).into());
|
||||
}
|
||||
};
|
||||
|
||||
// Command to PUT the algorithm attributes
|
||||
let cmd = commands::put_data(&[key_type.get_algorithm_tag()], data);
|
||||
let cmd = commands::put_data(
|
||||
&[key_type.get_algorithm_tag()],
|
||||
algo.get_data()?,
|
||||
);
|
||||
|
||||
apdu::send_command(&mut self.card_client, cmd, false)?.try_into()
|
||||
}
|
||||
|
||||
/// Helper: generate `data` for algorithm attributes with RSA
|
||||
fn rsa_algo_attrs(algo_attrs: &RsaAttrs) -> Result<Vec<u8>> {
|
||||
// Algorithm ID (01 = RSA (Encrypt or Sign))
|
||||
let mut algo_attributes = vec![0x01];
|
||||
|
||||
// Length of modulus n in bit
|
||||
algo_attributes.extend(&algo_attrs.len_n().to_be_bytes());
|
||||
|
||||
// Length of public exponent e in bit
|
||||
algo_attributes.push(0x00);
|
||||
algo_attributes.push(algo_attrs.len_e() as u8);
|
||||
|
||||
// Import-Format of private key
|
||||
// (This fn currently assumes import_format "00 = standard (e, p, q)")
|
||||
if algo_attrs.import_format() != 0 {
|
||||
return Err(anyhow!(
|
||||
"Unexpected RSA input format (only 0 is supported)"
|
||||
));
|
||||
}
|
||||
|
||||
algo_attributes.push(algo_attrs.import_format());
|
||||
|
||||
Ok(algo_attributes)
|
||||
}
|
||||
|
||||
/// Helper: generate `data` for algorithm attributes with ECC
|
||||
fn ecc_algo_attrs(oid: &[u8], ecc_type: EccType) -> Vec<u8> {
|
||||
let algo_id = match ecc_type {
|
||||
EccType::EdDSA => 0x16,
|
||||
EccType::ECDH => 0x12,
|
||||
EccType::ECDSA => 0x13,
|
||||
};
|
||||
|
||||
let mut algo_attributes = vec![algo_id];
|
||||
algo_attributes.extend(oid);
|
||||
// Leave Import-Format unset, for default (pg. 35)
|
||||
|
||||
algo_attributes
|
||||
}
|
||||
|
||||
/// Import an existing private key to the card.
|
||||
/// (This implicitly sets the algorithm info, fingerprint and timestamp)
|
||||
pub fn key_import(
|
||||
|
|
Loading…
Reference in a new issue