diff --git a/openpgp-card/src/algorithm.rs b/openpgp-card/src/algorithm.rs index d1d4992..590723d 100644 --- a/openpgp-card/src/algorithm.rs +++ b/openpgp-card/src/algorithm.rs @@ -1,10 +1,10 @@ -// SPDX-FileCopyrightText: 2021 Heiko Schaefer +// SPDX-FileCopyrightText: 2021-2023 Heiko Schaefer // 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 -//! the OpenPGP card specification. +//! [`AlgorithmAttributes`] (and its components) model "Algorithm Attributes" +//! as described in the OpenPGP card specification. //! //! [`AlgoSimple`] offers a shorthand for specifying an algorithm, //! specifically for key generation on the card. @@ -31,7 +31,7 @@ pub enum AlgoSimple { } impl TryFrom<&str> for AlgoSimple { - type Error = crate::Error; + type Error = Error; fn try_from(algo: &str) -> Result { use AlgoSimple::*; @@ -80,25 +80,37 @@ impl AlgoSimple { /// 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; /// also, the import_format can differ). - pub(crate) fn determine_algo( + pub(crate) fn determine_algo_attributes( &self, key_type: KeyType, ard: &ApplicationRelatedData, algo_info: Option, - ) -> Result { + ) -> Result { let algo = match self { - Self::RSA1k => { - AlgorithmAttributes::Rsa(keys::determine_rsa_attrs(1024, key_type, ard, algo_info)?) - } - Self::RSA2k => { - AlgorithmAttributes::Rsa(keys::determine_rsa_attrs(2048, key_type, ard, algo_info)?) - } - Self::RSA3k => { - AlgorithmAttributes::Rsa(keys::determine_rsa_attrs(3072, key_type, ard, algo_info)?) - } - Self::RSA4k => { - AlgorithmAttributes::Rsa(keys::determine_rsa_attrs(4096, key_type, ard, algo_info)?) - } + Self::RSA1k => AlgorithmAttributes::Rsa(keys::determine_rsa_attrs( + 1024, + key_type, + ard.algorithm_attributes(key_type)?, + algo_info, + )?), + Self::RSA2k => AlgorithmAttributes::Rsa(keys::determine_rsa_attrs( + 2048, + key_type, + ard.algorithm_attributes(key_type)?, + 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( Curve::NistP256r1.oid(), Self::ecc_type(key_type), @@ -334,7 +346,7 @@ impl Curve { } impl TryFrom<&[u8]> for Curve { - type Error = crate::Error; + type Error = Error; fn try_from(oid: &[u8]) -> Result { use Curve::*; diff --git a/openpgp-card/src/keys.rs b/openpgp-card/src/keys.rs index 48c6a82..54513c4 100644 --- a/openpgp-card/src/keys.rs +++ b/openpgp-card/src/keys.rs @@ -9,7 +9,7 @@ use std::time::{SystemTime, UNIX_EPOCH}; use crate::algorithm::{AlgoInfo, AlgorithmAttributes, Curve, EccAttrs, RsaAttrs}; use crate::apdu::command::Command; use crate::apdu::commands; -use crate::card_do::{ApplicationRelatedData, Fingerprint, KeyGenerationTime}; +use crate::card_do::{Fingerprint, KeyGenerationTime}; use crate::crypto_data::{ CardUploadableKey, EccKey, EccPub, EccType, PrivateKeyMaterial, PublicKeyMaterial, RSAKey, RSAPub, @@ -189,7 +189,8 @@ pub(crate) fn key_import( // (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_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)?; @@ -233,9 +234,9 @@ pub(crate) fn key_import( pub(crate) fn determine_rsa_attrs( rsa_bits: u16, key_type: KeyType, - ard: &ApplicationRelatedData, + algo_attr: AlgorithmAttributes, algo_info: Option, -) -> Result { +) -> Result { // Figure out suitable RSA algorithm parameters: // Does the card offer a list of algorithms? @@ -246,10 +247,8 @@ pub(crate) fn determine_rsa_attrs( } else { // 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? - if let AlgorithmAttributes::Rsa(rsa) = algo { + if let AlgorithmAttributes::Rsa(rsa) = algo_attr { // If so, use the algorithm parameters from the card and // adjust the bit length based on the user-provided key. RsaAttrs::new(rsa_bits, rsa.len_e(), rsa.import_format()) diff --git a/openpgp-card/src/openpgp.rs b/openpgp-card/src/openpgp.rs index 6ac47b6..1d88def 100644 --- a/openpgp-card/src/openpgp.rs +++ b/openpgp-card/src/openpgp.rs @@ -1077,7 +1077,7 @@ impl<'a> OpenPgpTransaction<'a> { // ----------------- /// 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( &mut self, key: Box, @@ -1093,10 +1093,10 @@ impl<'a> OpenPgpTransaction<'a> { /// Generate a key on the card. /// (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". /// - /// 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 /// supports. pub fn generate_key( @@ -1107,9 +1107,9 @@ impl<'a> OpenPgpTransaction<'a> { KeyType, ) -> Result, key_type: KeyType, - algo: Option<&AlgorithmAttributes>, + algorithm_attributes: Option<&AlgorithmAttributes>, ) -> 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. @@ -1138,7 +1138,7 @@ impl<'a> OpenPgpTransaction<'a> { 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)) }