Remove bitsize of e parameter for RSA from SimpleAlgo.

Use determine_rsa_attrs() to get a concrete Algo for a specific card from an AlgoSimple.
This commit is contained in:
Heiko Schaefer 2021-12-02 13:19:27 +01:00
parent 10bdb32c45
commit c37c34e525
No known key found for this signature in database
GPG key ID: 4A849A1904CCBD7D
4 changed files with 53 additions and 50 deletions

View file

@ -9,27 +9,22 @@
//! [`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.
use crate::card_do::ApplicationRelatedData;
use crate::crypto_data::EccType; use crate::crypto_data::EccType;
use crate::{Error, KeyType}; use crate::{keys, Error, KeyType};
use anyhow::anyhow; use anyhow::{anyhow, Result};
use std::convert::TryFrom; use std::convert::TryFrom;
use std::fmt; use std::fmt;
/// A shorthand way to specify algorithms (e.g. for key generation). /// A shorthand way to specify algorithms (e.g. for key generation).
///
/// RSA variants require "number of bits in 'e'" as parameter.
///
/// There are (at least) two common supported values for e:
/// e=17 [YK4, YK5]
/// e=32 [YK5, Floss3.4, Gnuk1.2]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
#[non_exhaustive] #[non_exhaustive]
pub enum AlgoSimple { pub enum AlgoSimple {
RSA1k(u16), RSA1k,
RSA2k(u16), RSA2k,
RSA3k(u16), RSA3k,
RSA4k(u16), RSA4k,
NIST256, NIST256,
NIST384, NIST384,
NIST521, NIST521,
@ -43,14 +38,10 @@ impl TryFrom<&str> for AlgoSimple {
use AlgoSimple::*; use AlgoSimple::*;
Ok(match algo { Ok(match algo {
"RSA1k/17" => RSA1k(17), "RSA1k" => RSA1k,
"RSA1k/32" => RSA1k(32), "RSA2k" => RSA2k,
"RSA2k/17" => RSA2k(17), "RSA3k" => RSA3k,
"RSA2k/32" => RSA2k(32), "RSA4k" => RSA4k,
"RSA3k/17" => RSA3k(17),
"RSA3k/32" => RSA3k(32),
"RSA4k/17" => RSA4k(17),
"RSA4k/32" => RSA4k(32),
"NIST256" => NIST256, "NIST256" => NIST256,
"NIST384" => NIST384, "NIST384" => NIST384,
"NIST521" => NIST521, "NIST521" => NIST521,
@ -91,28 +82,26 @@ impl AlgoSimple {
} }
} }
pub(crate) fn as_algo(&self, key_type: KeyType) -> Algo { pub(crate) fn determine_algo(
match self { &self,
Self::RSA1k(e) => Algo::Rsa(RsaAttrs { key_type: KeyType,
len_n: 1024, ard: &ApplicationRelatedData,
len_e: *e, algo_info: Option<AlgoInfo>,
import_format: 0, ) -> Result<Algo> {
}), let algo = match self {
Self::RSA2k(e) => Algo::Rsa(RsaAttrs { Self::RSA1k => Algo::Rsa(keys::determine_rsa_attrs(
len_n: 2048, 1024, key_type, ard, algo_info,
len_e: *e, )?),
import_format: 0, Self::RSA2k => Algo::Rsa(keys::determine_rsa_attrs(
}), 2048, key_type, ard, algo_info,
Self::RSA3k(e) => Algo::Rsa(RsaAttrs { )?),
len_n: 3072, Self::RSA3k => Algo::Rsa(keys::determine_rsa_attrs(
len_e: *e, 3072, key_type, ard, algo_info,
import_format: 0, )?),
}), Self::RSA4k => Algo::Rsa(keys::determine_rsa_attrs(
Self::RSA4k(e) => Algo::Rsa(RsaAttrs { 4096, key_type, ard, algo_info,
len_n: 4096, )?),
len_e: *e,
import_format: 0,
}),
Self::NIST256 => Algo::Ecc(EccAttrs { Self::NIST256 => Algo::Ecc(EccAttrs {
curve: Curve::NistP256r1, curve: Curve::NistP256r1,
ecc_type: Self::ecc_type(key_type), ecc_type: Self::ecc_type(key_type),
@ -133,7 +122,9 @@ impl AlgoSimple {
ecc_type: Self::ecc_type_25519(key_type), ecc_type: Self::ecc_type_25519(key_type),
import_format: None, import_format: None,
}), }),
} };
Ok(algo)
} }
} }

View file

@ -805,6 +805,10 @@ impl CardApp {
/// ///
/// If the `algo` parameter is Some, then this algorithm will be set on /// If the `algo` 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
/// applicable), and import format, with values that the current card
/// supports.
pub fn generate_key( pub fn generate_key(
&mut self, &mut self,
fp_from_pub: fn( fp_from_pub: fn(
@ -821,8 +825,12 @@ impl CardApp {
/// 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)
/// ///
/// This is a convenience wrapper around generate_key() which allows /// This is a wrapper around generate_key() which allows
/// using the simplified `AlgoSimple` algorithm selector enum. /// using the simplified `AlgoSimple` algorithm selector enum.
///
/// Note: AlgoSimple doesn't specify card specific details (such as
/// bitsize of e for RSA, and import format). This function determines
/// these values based on information from the card.
pub fn generate_key_simple( pub fn generate_key_simple(
&mut self, &mut self,
fp_from_pub: fn( fp_from_pub: fn(
@ -831,9 +839,13 @@ impl CardApp {
KeyType, KeyType,
) -> Result<Fingerprint, Error>, ) -> Result<Fingerprint, Error>,
key_type: KeyType, key_type: KeyType,
algo: AlgoSimple, simple: AlgoSimple,
) -> Result<(PublicKeyMaterial, KeyGenerationTime), Error> { ) -> Result<(PublicKeyMaterial, KeyGenerationTime), Error> {
let algo = algo.as_algo(key_type); let ard = self.application_related_data()?;
let algo_info = self.algorithm_information()?;
let algo = simple.determine_algo(key_type, &ard, algo_info)?;
self.generate_key(fp_from_pub, key_type, Some(&algo)) self.generate_key(fp_from_pub, key_type, Some(&algo))
} }

View file

@ -64,7 +64,7 @@ pub(crate) fn gen_key_with_metadata(
} }
} }
// get new state of algo // get current (possibly updated) state of algo
let ard = card_app.application_related_data()?; // no caching, here! let ard = card_app.application_related_data()?; // no caching, here!
let cur_algo = ard.algorithm_attributes(key_type)?; let cur_algo = ard.algorithm_attributes(key_type)?;
@ -230,7 +230,7 @@ pub(crate) fn key_import(
/// If available, via lookup in `algo_list`, otherwise the current /// If available, via lookup in `algo_list`, otherwise the current
/// algorithm attributes are checked. If neither method yields a /// algorithm attributes are checked. If neither method yields a
/// result, we 'guess' the RsaAttrs setting. /// result, we 'guess' the RsaAttrs setting.
fn determine_rsa_attrs( pub(crate) fn determine_rsa_attrs(
rsa_bits: u16, rsa_bits: u16,
key_type: KeyType, key_type: KeyType,
ard: &ApplicationRelatedData, ard: &ApplicationRelatedData,
@ -299,7 +299,7 @@ fn determine_ecc_attrs(
if !algos.is_empty() { if !algos.is_empty() {
return Ok(EccAttrs::new( return Ok(EccAttrs::new(
ecc_key.ecc_type(), ecc_key.ecc_type(),
Curve::try_from(ecc_key.oid())?, Curve::try_from(oid)?,
algos[0].import_format(), algos[0].import_format(),
)); ));
} }

View file

@ -31,7 +31,7 @@ mod card_app;
pub mod card_do; pub mod card_do;
pub mod crypto_data; pub mod crypto_data;
mod errors; mod errors;
mod keys; pub(crate) mod keys;
mod tlv; mod tlv;
pub use crate::apdu::response::Response; pub use crate::apdu::response::Response;