Add an AlgoSimple enum as a simplified way to select an algorithm on a card.

This commit is contained in:
Heiko Schaefer 2021-08-13 19:29:20 +02:00
parent 765b4e8fdc
commit 2ef6e0442d
2 changed files with 124 additions and 3 deletions

View file

@ -25,8 +25,9 @@ use crate::parse::{
};
use crate::tlv::{tag::Tag, Tlv, TlvEntry};
use crate::{
apdu, keys, Algo, CardCaps, CardClientBox, CardUploadableKey, DecryptMe,
EccType, Hash, KeyGeneration, KeyType, PublicKeyMaterial, RsaAttrs, Sex,
apdu, keys, Algo, AlgoSimple, CardCaps, CardClientBox, CardUploadableKey,
DecryptMe, EccType, Hash, KeyGeneration, KeyType, PublicKeyMaterial,
RsaAttrs, Sex,
};
pub struct CardApp {
@ -635,6 +636,7 @@ impl CardApp {
}
/// Generate a key on the card.
///
/// If the `algo` parameter is Some, then this algorithm will be set on
/// the card for "key_type".
pub fn generate_key(
@ -647,10 +649,25 @@ impl CardApp {
key_type: KeyType,
algo: Option<&Algo>,
) -> Result<(PublicKeyMaterial, u32), OpenpgpCardError> {
// FIXME: specify algo; pass in algo list?
keys::gen_key_with_metadata(self, fp_from_pub, key_type, algo)
}
/// Generate a key on the card.
/// Use a simplified algo selector enum.
pub fn generate_key_simple(
&mut self,
fp_from_pub: fn(
&PublicKeyMaterial,
SystemTime,
KeyType,
) -> Result<[u8; 20]>,
key_type: KeyType,
algo: AlgoSimple,
) -> Result<(PublicKeyMaterial, u32), OpenpgpCardError> {
let algo = algo.get(key_type);
self.generate_key(fp_from_pub, key_type, Some(&algo))
}
pub fn get_pub_key(
&mut self,
key_type: KeyType,

View file

@ -65,6 +65,110 @@ impl CardCaps {
}
}
/// Algorithms 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)]
pub enum AlgoSimple {
RSA1k(u16),
RSA2k(u16),
RSA3k(u16),
RSA4k(u16),
NIST256,
NIST384,
NIST521,
Curve25519,
}
impl From<&str> for AlgoSimple {
fn from(algo: &str) -> Self {
use AlgoSimple::*;
match algo {
"RSA2k/17" => RSA2k(17),
"RSA2k/32" => RSA2k(32),
"RSA3k/17" => RSA3k(17),
"RSA3k/32" => RSA3k(32),
"RSA4k/17" => RSA4k(17),
"RSA4k/32" => RSA4k(32),
"NIST256" => NIST256,
"NIST384" => NIST384,
"NIST521" => NIST521,
"Curve25519" => Curve25519,
_ => panic!("unexpected algo {}", algo),
}
}
}
impl AlgoSimple {
fn get(&self, kt: KeyType) -> Algo {
let et = match kt {
KeyType::Signing | KeyType::Authentication => EccType::ECDSA,
KeyType::Decryption => EccType::ECDH,
_ => unimplemented!(),
};
match self {
Self::RSA1k(e) => Algo::Rsa(RsaAttrs {
len_n: 1024,
len_e: *e,
import_format: 0,
}),
Self::RSA2k(e) => Algo::Rsa(RsaAttrs {
len_n: 2048,
len_e: *e,
import_format: 0,
}),
Self::RSA3k(e) => Algo::Rsa(RsaAttrs {
len_n: 3072,
len_e: *e,
import_format: 0,
}),
Self::RSA4k(e) => Algo::Rsa(RsaAttrs {
len_n: 4096,
len_e: *e,
import_format: 0,
}),
Self::NIST256 => Algo::Ecc(EccAttrs {
curve: Curve::NistP256r1,
ecc_type: et,
import_format: None,
}),
Self::NIST384 => Algo::Ecc(EccAttrs {
curve: Curve::NistP384r1,
ecc_type: et,
import_format: None,
}),
Self::NIST521 => Algo::Ecc(EccAttrs {
curve: Curve::NistP521r1,
ecc_type: et,
import_format: None,
}),
Self::Curve25519 => Algo::Ecc(EccAttrs {
curve: match kt {
KeyType::Signing | KeyType::Authentication => {
Curve::Ed25519
}
KeyType::Decryption => Curve::Cv25519,
_ => unimplemented!(),
},
ecc_type: match kt {
KeyType::Signing | KeyType::Authentication => {
EccType::EdDSA
}
KeyType::Decryption => EccType::ECDH,
_ => unimplemented!(),
},
import_format: None,
}),
}
}
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum Algo {
Rsa(RsaAttrs),