openpgp-card: internal API tweaks

Reduce unnecessary use of ApplicationRelatedData.
This commit is contained in:
Heiko Schaefer 2023-08-29 13:07:43 +02:00
parent e6658713cb
commit 01ef1ec4d1
No known key found for this signature in database
GPG key ID: 4A849A1904CCBD7D
3 changed files with 44 additions and 33 deletions

View file

@ -1,10 +1,10 @@
// SPDX-FileCopyrightText: 2021 Heiko Schaefer <heiko@schaefer.name> // SPDX-FileCopyrightText: 2021-2023 Heiko Schaefer <heiko@schaefer.name>
// SPDX-License-Identifier: MIT OR Apache-2.0 // SPDX-License-Identifier: MIT OR Apache-2.0
//! Data structures that define OpenPGP algorithms. //! Data structures that specify algorithms to use on an OpenPGP card.
//! //!
//! [`AlgorithmAttributes`] and its components model "Algorithm Attributes" as described in //! [`AlgorithmAttributes`] (and its components) model "Algorithm Attributes"
//! the OpenPGP card specification. //! as described in the OpenPGP card specification.
//! //!
//! [`AlgoSimple`] offers a shorthand for specifying an algorithm, //! [`AlgoSimple`] offers a shorthand for specifying an algorithm,
//! specifically for key generation on the card. //! specifically for key generation on the card.
@ -31,7 +31,7 @@ pub enum AlgoSimple {
} }
impl TryFrom<&str> for AlgoSimple { impl TryFrom<&str> for AlgoSimple {
type Error = crate::Error; type Error = Error;
fn try_from(algo: &str) -> Result<Self, Self::Error> { fn try_from(algo: &str) -> Result<Self, Self::Error> {
use AlgoSimple::*; use AlgoSimple::*;
@ -80,25 +80,37 @@ impl AlgoSimple {
/// This mapping differs between cards, based on `ard` and `algo_info` /// This mapping differs between cards, based on `ard` and `algo_info`
/// (e.g. the exact Algo variant can have a different size for e, in RSA; /// (e.g. the exact Algo variant can have a different size for e, in RSA;
/// also, the import_format can differ). /// also, the import_format can differ).
pub(crate) fn determine_algo( pub(crate) fn determine_algo_attributes(
&self, &self,
key_type: KeyType, key_type: KeyType,
ard: &ApplicationRelatedData, ard: &ApplicationRelatedData,
algo_info: Option<AlgoInfo>, algo_info: Option<AlgoInfo>,
) -> Result<AlgorithmAttributes, crate::Error> { ) -> Result<AlgorithmAttributes, Error> {
let algo = match self { let algo = match self {
Self::RSA1k => { Self::RSA1k => AlgorithmAttributes::Rsa(keys::determine_rsa_attrs(
AlgorithmAttributes::Rsa(keys::determine_rsa_attrs(1024, key_type, ard, algo_info)?) 1024,
} key_type,
Self::RSA2k => { ard.algorithm_attributes(key_type)?,
AlgorithmAttributes::Rsa(keys::determine_rsa_attrs(2048, key_type, ard, algo_info)?) algo_info,
} )?),
Self::RSA3k => { Self::RSA2k => AlgorithmAttributes::Rsa(keys::determine_rsa_attrs(
AlgorithmAttributes::Rsa(keys::determine_rsa_attrs(3072, key_type, ard, algo_info)?) 2048,
} key_type,
Self::RSA4k => { ard.algorithm_attributes(key_type)?,
AlgorithmAttributes::Rsa(keys::determine_rsa_attrs(4096, key_type, ard, algo_info)?) algo_info,
} )?),
Self::RSA3k => AlgorithmAttributes::Rsa(keys::determine_rsa_attrs(
3072,
key_type,
ard.algorithm_attributes(key_type)?,
algo_info,
)?),
Self::RSA4k => AlgorithmAttributes::Rsa(keys::determine_rsa_attrs(
4096,
key_type,
ard.algorithm_attributes(key_type)?,
algo_info,
)?),
Self::NIST256 => AlgorithmAttributes::Ecc(keys::determine_ecc_attrs( Self::NIST256 => AlgorithmAttributes::Ecc(keys::determine_ecc_attrs(
Curve::NistP256r1.oid(), Curve::NistP256r1.oid(),
Self::ecc_type(key_type), Self::ecc_type(key_type),
@ -334,7 +346,7 @@ impl Curve {
} }
impl TryFrom<&[u8]> for Curve { impl TryFrom<&[u8]> for Curve {
type Error = crate::Error; type Error = Error;
fn try_from(oid: &[u8]) -> Result<Self, Self::Error> { fn try_from(oid: &[u8]) -> Result<Self, Self::Error> {
use Curve::*; use Curve::*;

View file

@ -9,7 +9,7 @@ use std::time::{SystemTime, UNIX_EPOCH};
use crate::algorithm::{AlgoInfo, AlgorithmAttributes, Curve, EccAttrs, RsaAttrs}; use crate::algorithm::{AlgoInfo, AlgorithmAttributes, Curve, EccAttrs, RsaAttrs};
use crate::apdu::command::Command; use crate::apdu::command::Command;
use crate::apdu::commands; use crate::apdu::commands;
use crate::card_do::{ApplicationRelatedData, Fingerprint, KeyGenerationTime}; use crate::card_do::{Fingerprint, KeyGenerationTime};
use crate::crypto_data::{ use crate::crypto_data::{
CardUploadableKey, EccKey, EccPub, EccType, PrivateKeyMaterial, PublicKeyMaterial, RSAKey, CardUploadableKey, EccKey, EccPub, EccType, PrivateKeyMaterial, PublicKeyMaterial, RSAKey,
RSAPub, RSAPub,
@ -189,7 +189,8 @@ pub(crate) fn key_import(
// (round up to 4-bytes, in case the key has 8+ leading zero bits) // (round up to 4-bytes, in case the key has 8+ leading zero bits)
let rsa_bits = (((rsa_key.n().len() * 8 + 31) / 32) * 32) as u16; let rsa_bits = (((rsa_key.n().len() * 8 + 31) / 32) * 32) as u16;
let rsa_attrs = determine_rsa_attrs(rsa_bits, key_type, &ard, algo_info)?; let algo_attr = ard.algorithm_attributes(key_type)?;
let rsa_attrs = determine_rsa_attrs(rsa_bits, key_type, algo_attr, algo_info)?;
let key_cmd = rsa_key_import_cmd(key_type, rsa_key, &rsa_attrs)?; let key_cmd = rsa_key_import_cmd(key_type, rsa_key, &rsa_attrs)?;
@ -233,9 +234,9 @@ pub(crate) fn key_import(
pub(crate) fn determine_rsa_attrs( pub(crate) fn determine_rsa_attrs(
rsa_bits: u16, rsa_bits: u16,
key_type: KeyType, key_type: KeyType,
ard: &ApplicationRelatedData, algo_attr: AlgorithmAttributes,
algo_info: Option<AlgoInfo>, algo_info: Option<AlgoInfo>,
) -> Result<RsaAttrs, crate::Error> { ) -> Result<RsaAttrs, Error> {
// Figure out suitable RSA algorithm parameters: // Figure out suitable RSA algorithm parameters:
// Does the card offer a list of algorithms? // Does the card offer a list of algorithms?
@ -246,10 +247,8 @@ pub(crate) fn determine_rsa_attrs(
} else { } else {
// No -> Get the current algorithm attributes for key_type. // No -> Get the current algorithm attributes for key_type.
let algo = ard.algorithm_attributes(key_type)?;
// Is the algorithm on the card currently set to RSA? // Is the algorithm on the card currently set to RSA?
if let AlgorithmAttributes::Rsa(rsa) = algo { if let AlgorithmAttributes::Rsa(rsa) = algo_attr {
// If so, use the algorithm parameters from the card and // If so, use the algorithm parameters from the card and
// adjust the bit length based on the user-provided key. // adjust the bit length based on the user-provided key.
RsaAttrs::new(rsa_bits, rsa.len_e(), rsa.import_format()) RsaAttrs::new(rsa_bits, rsa.len_e(), rsa.import_format())

View file

@ -1077,7 +1077,7 @@ impl<'a> OpenPgpTransaction<'a> {
// ----------------- // -----------------
/// Import an existing private key to the card. /// Import an existing private key to the card.
/// (This implicitly sets the algorithm info, fingerprint and timestamp) /// (This implicitly sets the algorithm attributes, fingerprint and timestamp)
pub fn key_import( pub fn key_import(
&mut self, &mut self,
key: Box<dyn CardUploadableKey>, key: Box<dyn CardUploadableKey>,
@ -1093,10 +1093,10 @@ impl<'a> OpenPgpTransaction<'a> {
/// Generate a key on the card. /// Generate a key on the card.
/// (7.2.14 GENERATE ASYMMETRIC KEY PAIR) /// (7.2.14 GENERATE ASYMMETRIC KEY PAIR)
/// ///
/// If the `algo` parameter is Some, then this algorithm will be set on /// If the `algorithm_attributes` parameter is Some, then this algorithm will be set on
/// the card for "key_type". /// the card for "key_type".
/// ///
/// Note: `algo` needs to precisely specify the RSA bitsize of e (if /// Note: `algorithm_attributes` needs to precisely specify the RSA bitsize of e (if
/// applicable), and import format, with values that the current card /// applicable), and import format, with values that the current card
/// supports. /// supports.
pub fn generate_key( pub fn generate_key(
@ -1107,9 +1107,9 @@ impl<'a> OpenPgpTransaction<'a> {
KeyType, KeyType,
) -> Result<Fingerprint, Error>, ) -> Result<Fingerprint, Error>,
key_type: KeyType, key_type: KeyType,
algo: Option<&AlgorithmAttributes>, algorithm_attributes: Option<&AlgorithmAttributes>,
) -> Result<(PublicKeyMaterial, KeyGenerationTime), Error> { ) -> Result<(PublicKeyMaterial, KeyGenerationTime), Error> {
keys::gen_key_with_metadata(self, fp_from_pub, key_type, algo) keys::gen_key_with_metadata(self, fp_from_pub, key_type, algorithm_attributes)
} }
/// Generate a key on the card. /// Generate a key on the card.
@ -1138,7 +1138,7 @@ impl<'a> OpenPgpTransaction<'a> {
None None
}; };
let algo = simple.determine_algo(key_type, &ard, algo_info)?; let algo = simple.determine_algo_attributes(key_type, &ard, algo_info)?;
Self::generate_key(self, fp_from_pub, key_type, Some(&algo)) Self::generate_key(self, fp_from_pub, key_type, Some(&algo))
} }