diff --git a/openpgp-card-sequoia/src/lib.rs b/openpgp-card-sequoia/src/lib.rs index 673f3d7..8716763 100644 --- a/openpgp-card-sequoia/src/lib.rs +++ b/openpgp-card-sequoia/src/lib.rs @@ -140,7 +140,7 @@ //! ``` use card_backend::{CardBackend, SmartcardError}; -use openpgp_card::algorithm::{Algo, AlgoInfo, AlgoSimple}; +use openpgp_card::algorithm::{AlgoInfo, AlgoSimple, AlgorithmAttributes}; use openpgp_card::card_do::{ ApplicationIdentifier, CardholderRelatedData, ExtendedCapabilities, ExtendedLengthInfo, Fingerprint, HistoricalBytes, KeyGenerationTime, KeyInformation, Lang, PWStatusBytes, @@ -467,7 +467,7 @@ impl<'a> Card> { self.state.ard.extended_capabilities() } - pub fn algorithm_attributes(&self, key_type: KeyType) -> Result { + pub fn algorithm_attributes(&self, key_type: KeyType) -> Result { self.state.ard.algorithm_attributes(key_type) } @@ -617,7 +617,9 @@ impl<'a> Card> { self.state.ard.attestation_key_fingerprint() } - pub fn attestation_key_algorithm_attributes(&mut self) -> Result, Error> { + pub fn attestation_key_algorithm_attributes( + &mut self, + ) -> Result, Error> { self.state.ard.attestation_key_algorithm_attributes() } diff --git a/openpgp-card-sequoia/src/types.rs b/openpgp-card-sequoia/src/types.rs index b7dc547..589ea19 100644 --- a/openpgp-card-sequoia/src/types.rs +++ b/openpgp-card-sequoia/src/types.rs @@ -3,7 +3,7 @@ //! Re-exports of openpgp-card types to enable standalone-use of openpgp-card-sequoia. -pub use openpgp_card::algorithm::{Algo, AlgoSimple, Curve}; +pub use openpgp_card::algorithm::{AlgoSimple, AlgorithmAttributes, Curve}; pub use openpgp_card::card_do::{Fingerprint, Sex, TouchPolicy}; pub use openpgp_card::crypto_data::{EccType, PublicKeyMaterial}; pub use openpgp_card::{Error, KeyType, StatusBytes}; diff --git a/openpgp-card-sequoia/src/util.rs b/openpgp-card-sequoia/src/util.rs index f51415d..4661bc8 100644 --- a/openpgp-card-sequoia/src/util.rs +++ b/openpgp-card-sequoia/src/util.rs @@ -7,7 +7,7 @@ use std::convert::TryFrom; use std::convert::TryInto; use anyhow::Result; -use openpgp_card::algorithm::{Algo, Curve}; +use openpgp_card::algorithm::{AlgorithmAttributes, Curve}; use openpgp_card::card_do::{Fingerprint, KeyGenerationTime}; use openpgp_card::crypto_data::{CardUploadableKey, PublicKeyMaterial}; use openpgp_card::{Error, KeyType}; @@ -235,7 +235,7 @@ pub fn public_key_material_to_key( } PublicKeyMaterial::E(ecc) => { let algo = ecc.algo().clone(); // FIXME? - if let Algo::Ecc(algo_ecc) = algo { + if let AlgorithmAttributes::Ecc(algo_ecc) = algo { let curve = match algo_ecc.curve() { Curve::NistP256r1 => sequoia_openpgp::types::Curve::NistP256, Curve::NistP384r1 => sequoia_openpgp::types::Curve::NistP384, diff --git a/openpgp-card/src/algorithm.rs b/openpgp-card/src/algorithm.rs index 47f6d7e..d1d4992 100644 --- a/openpgp-card/src/algorithm.rs +++ b/openpgp-card/src/algorithm.rs @@ -3,7 +3,7 @@ //! Data structures that define OpenPGP algorithms. //! -//! [`Algo`] and its components model "Algorithm Attributes" as described in +//! [`AlgorithmAttributes`] and its components model "Algorithm Attributes" as described in //! the OpenPGP card specification. //! //! [`AlgoSimple`] offers a shorthand for specifying an algorithm, @@ -85,31 +85,39 @@ impl AlgoSimple { key_type: KeyType, ard: &ApplicationRelatedData, algo_info: Option, - ) -> Result { + ) -> Result { let algo = match self { - Self::RSA1k => Algo::Rsa(keys::determine_rsa_attrs(1024, key_type, ard, algo_info)?), - Self::RSA2k => Algo::Rsa(keys::determine_rsa_attrs(2048, key_type, ard, algo_info)?), - Self::RSA3k => Algo::Rsa(keys::determine_rsa_attrs(3072, key_type, ard, algo_info)?), - Self::RSA4k => Algo::Rsa(keys::determine_rsa_attrs(4096, key_type, ard, algo_info)?), - Self::NIST256 => Algo::Ecc(keys::determine_ecc_attrs( + 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::NIST256 => AlgorithmAttributes::Ecc(keys::determine_ecc_attrs( Curve::NistP256r1.oid(), Self::ecc_type(key_type), key_type, algo_info, )?), - Self::NIST384 => Algo::Ecc(keys::determine_ecc_attrs( + Self::NIST384 => AlgorithmAttributes::Ecc(keys::determine_ecc_attrs( Curve::NistP384r1.oid(), Self::ecc_type(key_type), key_type, algo_info, )?), - Self::NIST521 => Algo::Ecc(keys::determine_ecc_attrs( + Self::NIST521 => AlgorithmAttributes::Ecc(keys::determine_ecc_attrs( Curve::NistP521r1.oid(), Self::ecc_type(key_type), key_type, algo_info, )?), - Self::Curve25519 => Algo::Ecc(keys::determine_ecc_attrs( + Self::Curve25519 => AlgorithmAttributes::Ecc(keys::determine_ecc_attrs( Self::curve_for_25519(key_type).oid(), Self::ecc_type_25519(key_type), key_type, @@ -127,7 +135,7 @@ impl AlgoSimple { /// algorithms for each key type. This list specifies which "Algorithm /// Attributes" can be set for key generation or key import. #[derive(Debug, Clone, Eq, PartialEq)] -pub struct AlgoInfo(pub(crate) Vec<(KeyType, Algo)>); +pub struct AlgoInfo(pub(crate) Vec<(KeyType, AlgorithmAttributes)>); /// 4.4.3.9 Algorithm Attributes /// @@ -139,13 +147,13 @@ pub struct AlgoInfo(pub(crate) Vec<(KeyType, Algo)>); /// - Export of public key data from the card (e.g. after key generation) #[derive(Debug, Clone, Eq, PartialEq)] #[non_exhaustive] -pub enum Algo { +pub enum AlgorithmAttributes { Rsa(RsaAttrs), Ecc(EccAttrs), Unknown(Vec), } -impl fmt::Display for Algo { +impl fmt::Display for AlgorithmAttributes { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::Rsa(rsa) => { @@ -181,13 +189,13 @@ impl fmt::Display for Algo { } } -impl Algo { +impl AlgorithmAttributes { /// Get a DO representation of the Algo, for setting algorithm /// attributes on the card. pub(crate) fn to_data_object(&self) -> Result, Error> { match self { - Algo::Rsa(rsa) => Self::rsa_algo_attrs(rsa), - Algo::Ecc(ecc) => Self::ecc_algo_attrs(ecc.oid(), ecc.ecc_type()), + AlgorithmAttributes::Rsa(rsa) => Self::rsa_algo_attrs(rsa), + AlgorithmAttributes::Ecc(ecc) => Self::ecc_algo_attrs(ecc.oid(), ecc.ecc_type()), _ => Err(Error::UnsupportedAlgo(format!("Unexpected Algo {self:?}"))), } } @@ -225,7 +233,7 @@ impl Algo { } } -/// RSA specific attributes of [`Algo`] ("Algorithm Attributes") +/// RSA specific attributes of [`AlgorithmAttributes`] #[derive(Debug, Clone, Eq, PartialEq)] pub struct RsaAttrs { len_n: u16, @@ -255,7 +263,7 @@ impl RsaAttrs { } } -/// ECC specific attributes of [`Algo`] ("Algorithm Attributes") +/// ECC specific attributes of [`AlgorithmAttributes`] #[derive(Debug, Clone, Eq, PartialEq)] pub struct EccAttrs { ecc_type: EccType, diff --git a/openpgp-card/src/card_do.rs b/openpgp-card/src/card_do.rs index 88ddae8..2ab2b57 100644 --- a/openpgp-card/src/card_do.rs +++ b/openpgp-card/src/card_do.rs @@ -9,7 +9,7 @@ use std::time::{Duration, UNIX_EPOCH}; use chrono::{DateTime, Utc}; -use crate::{algorithm::Algo, tlv::Tlv, Error, KeySet, KeyType, Tags}; +use crate::{algorithm::AlgorithmAttributes, tlv::Tlv, Error, KeySet, KeyType, Tags}; mod algo_attrs; mod algo_info; @@ -105,11 +105,11 @@ impl ApplicationRelatedData { } /// Get algorithm attributes (for each key type) - pub fn algorithm_attributes(&self, key_type: KeyType) -> Result { + pub fn algorithm_attributes(&self, key_type: KeyType) -> Result { let aa = self.0.find(key_type.algorithm_tag()); if let Some(aa) = aa { - Algo::try_from(&aa.serialize()[..]) + AlgorithmAttributes::try_from(&aa.serialize()[..]) } else { Err(Error::NotFound(format!( "Failed to get algorithm attributes for {key_type:?}." @@ -235,10 +235,14 @@ impl ApplicationRelatedData { } /// Get Attestation key algorithm attributes. - pub fn attestation_key_algorithm_attributes(&mut self) -> Result, Error> { + pub fn attestation_key_algorithm_attributes( + &mut self, + ) -> Result, Error> { match self.0.find(Tags::AlgorithmAttributesAttestation) { None => Ok(None), - Some(data) => Ok(Some(Algo::try_from(data.serialize().as_slice())?)), + Some(data) => Ok(Some(AlgorithmAttributes::try_from( + data.serialize().as_slice(), + )?)), } } diff --git a/openpgp-card/src/card_do/algo_attrs.rs b/openpgp-card/src/card_do/algo_attrs.rs index f4e1f99..1aa83b5 100644 --- a/openpgp-card/src/card_do/algo_attrs.rs +++ b/openpgp-card/src/card_do/algo_attrs.rs @@ -10,7 +10,7 @@ use nom::bytes::complete::tag; use nom::combinator::map; use nom::{branch, bytes::complete as bytes, number::complete as number}; -use crate::algorithm::{Algo, Curve, EccAttrs, RsaAttrs}; +use crate::algorithm::{AlgorithmAttributes, Curve, EccAttrs, RsaAttrs}; use crate::card_do::complete; use crate::crypto_data::EccType; @@ -80,14 +80,17 @@ fn parse_oid(input: &[u8]) -> nom::IResult<&[u8], Curve> { ))(input) } -fn parse_rsa(input: &[u8]) -> nom::IResult<&[u8], Algo> { +fn parse_rsa(input: &[u8]) -> nom::IResult<&[u8], AlgorithmAttributes> { let (input, _) = bytes::tag([0x01])(input)?; let (input, len_n) = number::be_u16(input)?; let (input, len_e) = number::be_u16(input)?; let (input, import_format) = number::u8(input)?; - Ok((input, Algo::Rsa(RsaAttrs::new(len_n, len_e, import_format)))) + Ok(( + input, + AlgorithmAttributes::Rsa(RsaAttrs::new(len_n, len_e, import_format)), + )) } fn parse_import_format(input: &[u8]) -> nom::IResult<&[u8], Option> { @@ -99,7 +102,7 @@ fn default_import_format(input: &[u8]) -> nom::IResult<&[u8], Option> { Ok((input, None)) } -fn parse_ecdh(input: &[u8]) -> nom::IResult<&[u8], Algo> { +fn parse_ecdh(input: &[u8]) -> nom::IResult<&[u8], AlgorithmAttributes> { let (input, _) = bytes::tag([0x12])(input)?; let (input, curve) = parse_oid(input)?; @@ -107,11 +110,11 @@ fn parse_ecdh(input: &[u8]) -> nom::IResult<&[u8], Algo> { Ok(( input, - Algo::Ecc(EccAttrs::new(EccType::ECDH, curve, import_format)), + AlgorithmAttributes::Ecc(EccAttrs::new(EccType::ECDH, curve, import_format)), )) } -fn parse_ecdsa(input: &[u8]) -> nom::IResult<&[u8], Algo> { +fn parse_ecdsa(input: &[u8]) -> nom::IResult<&[u8], AlgorithmAttributes> { let (input, _) = bytes::tag([0x13])(input)?; let (input, curve) = parse_oid(input)?; @@ -119,11 +122,11 @@ fn parse_ecdsa(input: &[u8]) -> nom::IResult<&[u8], Algo> { Ok(( input, - Algo::Ecc(EccAttrs::new(EccType::ECDSA, curve, import_format)), + AlgorithmAttributes::Ecc(EccAttrs::new(EccType::ECDSA, curve, import_format)), )) } -fn parse_eddsa(input: &[u8]) -> nom::IResult<&[u8], Algo> { +fn parse_eddsa(input: &[u8]) -> nom::IResult<&[u8], AlgorithmAttributes> { let (input, _) = bytes::tag([0x16])(input)?; let (input, curve) = parse_oid(input)?; @@ -131,15 +134,15 @@ fn parse_eddsa(input: &[u8]) -> nom::IResult<&[u8], Algo> { Ok(( input, - Algo::Ecc(EccAttrs::new(EccType::EdDSA, curve, import_format)), + AlgorithmAttributes::Ecc(EccAttrs::new(EccType::EdDSA, curve, import_format)), )) } -pub(crate) fn parse(input: &[u8]) -> nom::IResult<&[u8], Algo> { +pub(crate) fn parse(input: &[u8]) -> nom::IResult<&[u8], AlgorithmAttributes> { branch::alt((parse_rsa, parse_ecdsa, parse_eddsa, parse_ecdh))(input) } -impl TryFrom<&[u8]> for Algo { +impl TryFrom<&[u8]> for AlgorithmAttributes { type Error = crate::Error; fn try_from(data: &[u8]) -> Result { diff --git a/openpgp-card/src/card_do/algo_info.rs b/openpgp-card/src/card_do/algo_info.rs index dbebbd2..5a1cee4 100644 --- a/openpgp-card/src/card_do/algo_info.rs +++ b/openpgp-card/src/card_do/algo_info.rs @@ -10,12 +10,12 @@ use nom::branch::alt; use nom::combinator::map; use nom::{branch, bytes::complete as bytes, combinator, multi, sequence}; -use crate::algorithm::{Algo, AlgoInfo}; +use crate::algorithm::{AlgoInfo, AlgorithmAttributes}; use crate::card_do::{algo_attrs, complete}; use crate::KeyType; impl AlgoInfo { - pub fn filter_by_keytype(&self, kt: KeyType) -> Vec<&Algo> { + pub fn filter_by_keytype(&self, kt: KeyType) -> Vec<&AlgorithmAttributes> { self.0 .iter() .filter(|(k, _)| *k == kt) @@ -48,11 +48,11 @@ fn key_type(input: &[u8]) -> nom::IResult<&[u8], KeyType> { ))(input) } -fn unknown(input: &[u8]) -> nom::IResult<&[u8], Algo> { - Ok((&[], Algo::Unknown(input.to_vec()))) +fn unknown(input: &[u8]) -> nom::IResult<&[u8], AlgorithmAttributes> { + Ok((&[], AlgorithmAttributes::Unknown(input.to_vec()))) } -fn parse_one(input: &[u8]) -> nom::IResult<&[u8], Algo> { +fn parse_one(input: &[u8]) -> nom::IResult<&[u8], AlgorithmAttributes> { let (input, a) = combinator::map( combinator::flat_map(crate::tlv::length::length, bytes::take), |i| alt((combinator::all_consuming(algo_attrs::parse), unknown))(i), @@ -61,18 +61,18 @@ fn parse_one(input: &[u8]) -> nom::IResult<&[u8], Algo> { Ok((input, a?.1)) } -fn parse_list(input: &[u8]) -> nom::IResult<&[u8], Vec<(KeyType, Algo)>> { +fn parse_list(input: &[u8]) -> nom::IResult<&[u8], Vec<(KeyType, AlgorithmAttributes)>> { multi::many0(sequence::pair(key_type, parse_one))(input) } -fn parse_tl_list(input: &[u8]) -> nom::IResult<&[u8], Vec<(KeyType, Algo)>> { +fn parse_tl_list(input: &[u8]) -> nom::IResult<&[u8], Vec<(KeyType, AlgorithmAttributes)>> { let (input, (_, _, list)) = sequence::tuple((bytes::tag([0xfa]), crate::tlv::length::length, parse_list))(input)?; Ok((input, list)) } -fn parse(input: &[u8]) -> nom::IResult<&[u8], Vec<(KeyType, Algo)>> { +fn parse(input: &[u8]) -> nom::IResult<&[u8], Vec<(KeyType, AlgorithmAttributes)>> { // Handle two variations of input format: // a) TLV format (e.g. YubiKey 5) // b) Plain list (e.g. Gnuk, FOSS-Store Smartcard 3.4) @@ -99,7 +99,7 @@ impl TryFrom<&[u8]> for AlgoInfo { mod test { use std::convert::TryFrom; - use crate::algorithm::{Algo::*, AlgoInfo, Curve::*, EccAttrs, RsaAttrs}; + use crate::algorithm::{AlgoInfo, AlgorithmAttributes::*, Curve::*, EccAttrs, RsaAttrs}; use crate::crypto_data::EccType::*; use crate::KeyType::*; diff --git a/openpgp-card/src/crypto_data.rs b/openpgp-card/src/crypto_data.rs index 075e301..5472bda 100644 --- a/openpgp-card/src/crypto_data.rs +++ b/openpgp-card/src/crypto_data.rs @@ -5,7 +5,7 @@ //! Private key data, public key data, cryptograms for decryption, hash //! data for signing. -use crate::algorithm::Algo; +use crate::algorithm::AlgorithmAttributes; use crate::card_do::{Fingerprint, KeyGenerationTime}; use crate::{oid, Error}; @@ -169,18 +169,18 @@ impl RSAPub { #[non_exhaustive] pub struct EccPub { data: Vec, - algo: Algo, + algo: AlgorithmAttributes, } impl EccPub { - pub fn new(data: Vec, algo: Algo) -> Self { + pub fn new(data: Vec, algo: AlgorithmAttributes) -> Self { Self { data, algo } } pub fn data(&self) -> &[u8] { &self.data } - pub fn algo(&self) -> &Algo { + pub fn algo(&self) -> &AlgorithmAttributes { &self.algo } } diff --git a/openpgp-card/src/keys.rs b/openpgp-card/src/keys.rs index 507d809..48c6a82 100644 --- a/openpgp-card/src/keys.rs +++ b/openpgp-card/src/keys.rs @@ -6,7 +6,7 @@ use std::convert::TryFrom; use std::time::{SystemTime, UNIX_EPOCH}; -use crate::algorithm::{Algo, AlgoInfo, Curve, EccAttrs, RsaAttrs}; +use crate::algorithm::{AlgoInfo, AlgorithmAttributes, Curve, EccAttrs, RsaAttrs}; use crate::apdu::command::Command; use crate::apdu::commands; use crate::card_do::{ApplicationRelatedData, Fingerprint, KeyGenerationTime}; @@ -32,7 +32,7 @@ pub(crate) fn gen_key_with_metadata( card_tx: &mut OpenPgpTransaction, fp_from_pub: fn(&PublicKeyMaterial, KeyGenerationTime, KeyType) -> Result, key_type: KeyType, - algo: Option<&Algo>, + algo: Option<&AlgorithmAttributes>, ) -> Result<(PublicKeyMaterial, KeyGenerationTime), Error> { // Set algo on card if it's Some if let Some(target_algo) = algo { @@ -91,7 +91,7 @@ pub(crate) fn gen_key_with_metadata( } /// Transform a public key Tlv from the card into PublicKeyMaterial -fn tlv_to_pubkey(tlv: &Tlv, algo: &Algo) -> Result { +fn tlv_to_pubkey(tlv: &Tlv, algo: &AlgorithmAttributes) -> Result { let n = tlv.find(Tags::PublicKeyDataRsaModulus); let v = tlv.find(Tags::PublicKeyDataRsaExponent); @@ -193,7 +193,7 @@ pub(crate) fn key_import( let key_cmd = rsa_key_import_cmd(key_type, rsa_key, &rsa_attrs)?; - (Algo::Rsa(rsa_attrs), key_cmd) + (AlgorithmAttributes::Rsa(rsa_attrs), key_cmd) } PrivateKeyMaterial::E(ecc_key) => { let ecc_attrs = @@ -201,7 +201,7 @@ pub(crate) fn key_import( let key_cmd = ecc_key_import_cmd(key_type, ecc_key, &ecc_attrs)?; - (Algo::Ecc(ecc_attrs), key_cmd) + (AlgorithmAttributes::Ecc(ecc_attrs), key_cmd) } }; @@ -249,7 +249,7 @@ pub(crate) fn determine_rsa_attrs( let algo = ard.algorithm_attributes(key_type)?; // Is the algorithm on the card currently set to RSA? - if let Algo::Rsa(rsa) = algo { + if let AlgorithmAttributes::Rsa(rsa) = algo { // 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()) @@ -322,7 +322,13 @@ fn card_algo_rsa(algo_info: AlgoInfo, key_type: KeyType, rsa_bits: u16) -> Resul // Get RSA algo attributes let rsa_algos: Vec<_> = keytype_algos .iter() - .filter_map(|a| if let Algo::Rsa(r) = a { Some(r) } else { None }) + .filter_map(|a| { + if let AlgorithmAttributes::Rsa(r) = a { + Some(r) + } else { + None + } + }) .collect(); // Filter card algorithms by rsa bitlength of the key we want to upload @@ -355,7 +361,13 @@ fn check_card_algo_ecc(algo_info: AlgoInfo, key_type: KeyType, oid: &[u8]) -> Ve // Get attributes let ecc_algos: Vec<_> = keytype_algos .iter() - .filter_map(|a| if let Algo::Ecc(e) = a { Some(e) } else { None }) + .filter_map(|a| { + if let AlgorithmAttributes::Ecc(e) = a { + Some(e) + } else { + None + } + }) .collect(); // Find entries with this OID in the algorithm information for key_type diff --git a/openpgp-card/src/openpgp.rs b/openpgp-card/src/openpgp.rs index 51c26af..6ac47b6 100644 --- a/openpgp-card/src/openpgp.rs +++ b/openpgp-card/src/openpgp.rs @@ -5,7 +5,7 @@ use std::convert::{TryFrom, TryInto}; use card_backend::{CardBackend, CardCaps, CardTransaction, PinType, SmartcardError}; -use crate::algorithm::{Algo, AlgoInfo, AlgoSimple}; +use crate::algorithm::{AlgoInfo, AlgoSimple, AlgorithmAttributes}; use crate::apdu::command::Command; use crate::apdu::commands; use crate::apdu::response::RawResponse; @@ -905,7 +905,7 @@ impl<'a> OpenPgpTransaction<'a> { pub fn set_algorithm_attributes( &mut self, key_type: KeyType, - algo: &Algo, + algo: &AlgorithmAttributes, ) -> Result<(), Error> { log::info!("OpenPgpTransaction: set_algorithm_attributes"); @@ -1107,7 +1107,7 @@ impl<'a> OpenPgpTransaction<'a> { KeyType, ) -> Result, key_type: KeyType, - algo: Option<&Algo>, + algo: Option<&AlgorithmAttributes>, ) -> Result<(PublicKeyMaterial, KeyGenerationTime), Error> { keys::gen_key_with_metadata(self, fp_from_pub, key_type, algo) }