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:
parent
10bdb32c45
commit
c37c34e525
4 changed files with 53 additions and 50 deletions
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue