Use KeyGenerationTime in openpgp-card APIs (instead of u32 or SystemTime)

This commit is contained in:
Heiko Schaefer 2021-08-26 19:27:08 +02:00
parent 794b04725f
commit 7c8c72339b
7 changed files with 47 additions and 58 deletions

View file

@ -2,18 +2,16 @@
// SPDX-License-Identifier: MIT OR Apache-2.0 // SPDX-License-Identifier: MIT OR Apache-2.0
use anyhow::{Error, Result}; use anyhow::{Error, Result};
use std::convert::TryInto;
use std::str::FromStr; use std::str::FromStr;
use std::string::FromUtf8Error; use std::string::FromUtf8Error;
use thiserror::Error; use thiserror::Error;
use sequoia_openpgp::parse::Parse; use sequoia_openpgp::parse::Parse;
use sequoia_openpgp::serialize::SerializeInto; use sequoia_openpgp::serialize::SerializeInto;
use sequoia_openpgp::types::Timestamp;
use sequoia_openpgp::Cert; use sequoia_openpgp::Cert;
use openpgp_card::algorithm::AlgoSimple; use openpgp_card::algorithm::AlgoSimple;
use openpgp_card::card_do::Sex; use openpgp_card::card_do::{KeyGenerationTime, Sex};
use openpgp_card::errors::{OcErrorStatus, OpenpgpCardError}; use openpgp_card::errors::{OcErrorStatus, OpenpgpCardError};
use openpgp_card::{CardApp, KeyType}; use openpgp_card::{CardApp, KeyType};
use openpgp_card_sequoia::{ use openpgp_card_sequoia::{
@ -96,7 +94,7 @@ pub fn test_sign(
fn check_key_upload_metadata( fn check_key_upload_metadata(
ca: &mut CardApp, ca: &mut CardApp,
meta: &[(String, u32)], meta: &[(String, KeyGenerationTime)],
) -> Result<()> { ) -> Result<()> {
let ard = ca.get_app_data()?; let ard = ca.get_app_data()?;
@ -117,21 +115,16 @@ fn check_key_upload_metadata(
// get_key_generation_times // get_key_generation_times
let card_kg = ard.get_key_generation_times()?; let card_kg = ard.get_key_generation_times()?;
let sig: u32 = let sig = card_kg.signature().expect("signature creation time");
card_kg.signature().expect("signature creation time").into(); assert_eq!(sig, &meta[0].1);
assert_eq!(sig, meta[0].1);
let dec: u32 = card_kg let dec = card_kg.decryption().expect("decryption creation time");
.decryption() assert_eq!(dec, &meta[1].1);
.expect("decryption creation time")
.into();
assert_eq!(dec, meta[1].1);
let auth: u32 = card_kg let auth = card_kg
.authentication() .authentication()
.expect("authentication creation time") .expect("authentication creation time");
.into(); assert_eq!(auth, &meta[2].1);
assert_eq!(auth, meta[2].1);
Ok(()) Ok(())
} }
@ -220,11 +213,7 @@ pub fn test_keygen(
println!(" Generate subkey for Signing"); println!(" Generate subkey for Signing");
let (pkm, ts) = let (pkm, ts) =
ca.generate_key_simple(public_to_fingerprint, KeyType::Signing, alg)?; ca.generate_key_simple(public_to_fingerprint, KeyType::Signing, alg)?;
let key_sig = public_key_material_to_key( let key_sig = public_key_material_to_key(&pkm, KeyType::Signing, ts)?;
&pkm,
KeyType::Signing,
Timestamp::from(ts).into(),
)?;
println!(" Generate subkey for Decryption"); println!(" Generate subkey for Decryption");
let (pkm, ts) = ca.generate_key_simple( let (pkm, ts) = ca.generate_key_simple(
@ -232,11 +221,7 @@ pub fn test_keygen(
KeyType::Decryption, KeyType::Decryption,
alg, alg,
)?; )?;
let key_dec = public_key_material_to_key( let key_dec = public_key_material_to_key(&pkm, KeyType::Decryption, ts)?;
&pkm,
KeyType::Decryption,
Timestamp::from(ts).into(),
)?;
println!(" Generate subkey for Authentication"); println!(" Generate subkey for Authentication");
let (pkm, ts) = ca.generate_key_simple( let (pkm, ts) = ca.generate_key_simple(
@ -244,11 +229,8 @@ pub fn test_keygen(
KeyType::Authentication, KeyType::Authentication,
alg, alg,
)?; )?;
let key_aut = public_key_material_to_key( let key_aut =
&pkm, public_key_material_to_key(&pkm, KeyType::Authentication, ts)?;
KeyType::Authentication,
Timestamp::from(ts).into(),
)?;
// Generate a Cert for this set of generated keys // Generate a Cert for this set of generated keys
@ -271,7 +253,7 @@ pub fn test_get_pub(
// -- // --
let sig = ca.get_pub_key(KeyType::Signing)?; let sig = ca.get_pub_key(KeyType::Signing)?;
let ts = Timestamp::from(key_gen.signature().unwrap().get()).into(); let ts = key_gen.signature().unwrap().get().into();
let key = openpgp_card_sequoia::public_key_material_to_key( let key = openpgp_card_sequoia::public_key_material_to_key(
&sig, &sig,
KeyType::Signing, KeyType::Signing,
@ -283,7 +265,7 @@ pub fn test_get_pub(
// -- // --
let dec = ca.get_pub_key(KeyType::Decryption)?; let dec = ca.get_pub_key(KeyType::Decryption)?;
let ts = Timestamp::from(key_gen.decryption().unwrap().get()).into(); let ts = key_gen.decryption().unwrap().get().into();
let key = openpgp_card_sequoia::public_key_material_to_key( let key = openpgp_card_sequoia::public_key_material_to_key(
&dec, &dec,
KeyType::Decryption, KeyType::Decryption,
@ -295,7 +277,7 @@ pub fn test_get_pub(
// -- // --
let auth = ca.get_pub_key(KeyType::Authentication)?; let auth = ca.get_pub_key(KeyType::Authentication)?;
let ts = Timestamp::from(key_gen.authentication().unwrap().get()).into(); let ts = key_gen.authentication().unwrap().get().into();
let key = openpgp_card_sequoia::public_key_material_to_key( let key = openpgp_card_sequoia::public_key_material_to_key(
&auth, &auth,
KeyType::Authentication, KeyType::Authentication,

View file

@ -18,6 +18,7 @@ use sequoia_openpgp::serialize::stream::{
}; };
use sequoia_openpgp::Cert; use sequoia_openpgp::Cert;
use openpgp_card::card_do::KeyGenerationTime;
use openpgp_card::{CardApp, KeyType}; use openpgp_card::{CardApp, KeyType};
use openpgp_card_sequoia::vka_as_uploadable_key; use openpgp_card_sequoia::vka_as_uploadable_key;
@ -26,7 +27,7 @@ pub const SP: &StandardPolicy = &StandardPolicy::new();
pub(crate) fn upload_subkeys( pub(crate) fn upload_subkeys(
ca: &mut CardApp, ca: &mut CardApp,
cert: &Cert, cert: &Cert,
) -> Result<Vec<(String, u32)>> { ) -> Result<Vec<(String, KeyGenerationTime)>> {
let mut out = vec![]; let mut out = vec![];
for kt in [ for kt in [
@ -45,7 +46,7 @@ pub(crate) fn upload_subkeys(
.unwrap() .unwrap()
.as_secs() as u32; .as_secs() as u32;
out.push((fp, creation)); out.push((fp, creation.into()));
// upload key // upload key
let cuk = vka_as_uploadable_key(vka, None); let cuk = vka_as_uploadable_key(vka, None);

View file

@ -34,8 +34,8 @@ use sequoia_openpgp as openpgp;
use openpgp_card::algorithm::{Algo, AlgoInfo, Curve}; use openpgp_card::algorithm::{Algo, AlgoInfo, Curve};
use openpgp_card::card_do::{ use openpgp_card::card_do::{
ApplicationId, ApplicationRelatedData, Cardholder, ExtendedCap, ApplicationId, ApplicationRelatedData, Cardholder, ExtendedCap,
ExtendedLengthInfo, Features, Fingerprint, Historical, KeySet, PWStatus, ExtendedLengthInfo, Features, Fingerprint, Historical, KeyGenerationTime,
SecuritySupportTemplate, Sex, KeySet, PWStatus, SecuritySupportTemplate, Sex,
}; };
use openpgp_card::crypto_data::{ use openpgp_card::crypto_data::{
CardUploadableKey, Cryptogram, EccKey, EccType, Hash, PrivateKeyMaterial, CardUploadableKey, Cryptogram, EccKey, EccType, Hash, PrivateKeyMaterial,
@ -92,8 +92,10 @@ pub fn vka_as_uploadable_key(
pub fn public_key_material_to_key( pub fn public_key_material_to_key(
pkm: &PublicKeyMaterial, pkm: &PublicKeyMaterial,
key_type: KeyType, key_type: KeyType,
time: SystemTime, time: KeyGenerationTime,
) -> Result<Key<PublicParts, UnspecifiedRole>> { ) -> Result<Key<PublicParts, UnspecifiedRole>> {
let time = Timestamp::from(time.get()).into();
match pkm { match pkm {
PublicKeyMaterial::R(rsa) => { PublicKeyMaterial::R(rsa) => {
let k4 = Key4::import_public_rsa(rsa.v(), rsa.n(), Some(time))?; let k4 = Key4::import_public_rsa(rsa.v(), rsa.n(), Some(time))?;
@ -362,9 +364,11 @@ impl CardUploadableKey for SequoiaKey {
/// Number of non-leap seconds since January 1, 1970 0:00:00 UTC /// Number of non-leap seconds since January 1, 1970 0:00:00 UTC
/// (aka "UNIX timestamp") /// (aka "UNIX timestamp")
fn get_ts(&self) -> u32 { fn get_ts(&self) -> KeyGenerationTime {
let ts: Timestamp = Timestamp::try_from(self.key.creation_time()) let ts: Timestamp = Timestamp::try_from(self.key.creation_time())
.expect("Creation time cannot be converted into u32 timestamp"); .expect("Creation time cannot be converted into u32 timestamp");
let ts: u32 = ts.into();
ts.into() ts.into()
} }
@ -539,11 +543,11 @@ pub fn sign(
/// timestamp + KeyType" (intended for use with `CardApp.generate_key()`). /// timestamp + KeyType" (intended for use with `CardApp.generate_key()`).
pub fn public_to_fingerprint( pub fn public_to_fingerprint(
pkm: &PublicKeyMaterial, pkm: &PublicKeyMaterial,
ts: SystemTime, time: KeyGenerationTime,
kt: KeyType, kt: KeyType,
) -> Result<Fingerprint, OpenpgpCardError> { ) -> Result<Fingerprint, OpenpgpCardError> {
// Transform PublicKeyMaterial into a Sequoia Key // Transform PublicKeyMaterial into a Sequoia Key
let key = public_key_material_to_key(pkm, kt, ts)?; let key = public_key_material_to_key(pkm, kt, time)?;
// Get fingerprint from the Sequoia Key // Get fingerprint from the Sequoia Key
let fp = key.fingerprint(); let fp = key.fingerprint();

View file

@ -4,15 +4,14 @@
use std::borrow::BorrowMut; use std::borrow::BorrowMut;
use std::convert::TryFrom; use std::convert::TryFrom;
use std::convert::TryInto; use std::convert::TryInto;
use std::time::SystemTime;
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use crate::algorithm::{Algo, AlgoInfo, AlgoSimple, RsaAttrs}; use crate::algorithm::{Algo, AlgoInfo, AlgoSimple, RsaAttrs};
use crate::apdu::{commands, response::Response}; use crate::apdu::{commands, response::Response};
use crate::card_do::{ use crate::card_do::{
ApplicationRelatedData, Cardholder, Fingerprint, PWStatus, ApplicationRelatedData, Cardholder, Fingerprint, KeyGenerationTime,
SecuritySupportTemplate, Sex, PWStatus, SecuritySupportTemplate, Sex,
}; };
use crate::crypto_data::{ use crate::crypto_data::{
CardUploadableKey, Cryptogram, EccType, Hash, PublicKeyMaterial, CardUploadableKey, Cryptogram, EccType, Hash, PublicKeyMaterial,
@ -473,11 +472,12 @@ impl CardApp {
pub fn set_creation_time( pub fn set_creation_time(
&mut self, &mut self,
time: u32, time: KeyGenerationTime,
key_type: KeyType, key_type: KeyType,
) -> Result<Response, OpenpgpCardError> { ) -> Result<Response, OpenpgpCardError> {
// Timestamp update // Timestamp update
let time_value: Vec<u8> = time let time_value: Vec<u8> = time
.get()
.to_be_bytes() .to_be_bytes()
.iter() .iter()
.skip_while(|&&e| e == 0) .skip_while(|&&e| e == 0)
@ -625,12 +625,12 @@ impl CardApp {
&mut self, &mut self,
fp_from_pub: fn( fp_from_pub: fn(
&PublicKeyMaterial, &PublicKeyMaterial,
SystemTime, KeyGenerationTime,
KeyType, KeyType,
) -> Result<Fingerprint, OpenpgpCardError>, ) -> Result<Fingerprint, OpenpgpCardError>,
key_type: KeyType, key_type: KeyType,
algo: Option<&Algo>, algo: Option<&Algo>,
) -> Result<(PublicKeyMaterial, u32), OpenpgpCardError> { ) -> Result<(PublicKeyMaterial, KeyGenerationTime), OpenpgpCardError> {
keys::gen_key_with_metadata(self, fp_from_pub, key_type, algo) keys::gen_key_with_metadata(self, fp_from_pub, key_type, algo)
} }
@ -640,12 +640,12 @@ impl CardApp {
&mut self, &mut self,
fp_from_pub: fn( fp_from_pub: fn(
&PublicKeyMaterial, &PublicKeyMaterial,
SystemTime, KeyGenerationTime,
KeyType, KeyType,
) -> Result<Fingerprint, OpenpgpCardError>, ) -> Result<Fingerprint, OpenpgpCardError>,
key_type: KeyType, key_type: KeyType,
algo: AlgoSimple, algo: AlgoSimple,
) -> Result<(PublicKeyMaterial, u32), OpenpgpCardError> { ) -> Result<(PublicKeyMaterial, KeyGenerationTime), OpenpgpCardError> {
let algo = algo.get_algo(key_type); let algo = algo.get_algo(key_type);
self.generate_key(fp_from_pub, key_type, Some(&algo)) self.generate_key(fp_from_pub, key_type, Some(&algo))
} }

View file

@ -182,7 +182,7 @@ impl SecuritySupportTemplate {
} }
/// An OpenPGP key generation Time /// An OpenPGP key generation Time
#[derive(Clone, Eq, PartialEq, Debug)] #[derive(Clone, Copy, Eq, PartialEq, Debug)]
pub struct KeyGenerationTime(u32); pub struct KeyGenerationTime(u32);
impl KeyGenerationTime { impl KeyGenerationTime {

View file

@ -8,7 +8,7 @@
use anyhow::Result; use anyhow::Result;
use crate::algorithm::Algo; use crate::algorithm::Algo;
use crate::card_do::Fingerprint; use crate::card_do::{Fingerprint, KeyGenerationTime};
use crate::errors::OpenpgpCardError; use crate::errors::OpenpgpCardError;
/// A hash value that can be signed by the card. /// A hash value that can be signed by the card.
@ -66,7 +66,7 @@ pub trait CardUploadableKey {
fn get_key(&self) -> Result<PrivateKeyMaterial>; fn get_key(&self) -> Result<PrivateKeyMaterial>;
/// timestamp of (sub)key creation /// timestamp of (sub)key creation
fn get_ts(&self) -> u32; fn get_ts(&self) -> KeyGenerationTime;
/// fingerprint /// fingerprint
fn get_fp(&self) -> Result<Fingerprint, OpenpgpCardError>; fn get_fp(&self) -> Result<Fingerprint, OpenpgpCardError>;

View file

@ -11,7 +11,7 @@ use crate::algorithm::{Algo, AlgoInfo, Curve, EccAttrs, RsaAttrs};
use crate::apdu::command::Command; use crate::apdu::command::Command;
use crate::apdu::commands; use crate::apdu::commands;
use crate::card_app::CardApp; use crate::card_app::CardApp;
use crate::card_do::Fingerprint; use crate::card_do::{Fingerprint, KeyGenerationTime};
use crate::crypto_data::{ use crate::crypto_data::{
CardUploadableKey, EccKey, EccPub, PrivateKeyMaterial, PublicKeyMaterial, CardUploadableKey, EccKey, EccPub, PrivateKeyMaterial, PublicKeyMaterial,
RSAKey, RSAPub, RSAKey, RSAPub,
@ -26,12 +26,12 @@ pub(crate) fn gen_key_with_metadata(
card_app: &mut CardApp, card_app: &mut CardApp,
fp_from_pub: fn( fp_from_pub: fn(
&PublicKeyMaterial, &PublicKeyMaterial,
SystemTime, KeyGenerationTime,
KeyType, KeyType,
) -> Result<Fingerprint, OpenpgpCardError>, ) -> Result<Fingerprint, OpenpgpCardError>,
key_type: KeyType, key_type: KeyType,
algo: Option<&Algo>, algo: Option<&Algo>,
) -> Result<(PublicKeyMaterial, u32), OpenpgpCardError> { ) -> Result<(PublicKeyMaterial, KeyGenerationTime), OpenpgpCardError> {
// set algo on card if it's Some // set algo on card if it's Some
if let Some(algo) = algo { if let Some(algo) = algo {
card_app.set_algorithm_attributes(key_type, algo)?; card_app.set_algorithm_attributes(key_type, algo)?;
@ -58,10 +58,12 @@ pub(crate) fn gen_key_with_metadata(
.map_err(|e| OpenpgpCardError::InternalError(anyhow!(e)))? .map_err(|e| OpenpgpCardError::InternalError(anyhow!(e)))?
.as_secs() as u32; .as_secs() as u32;
let ts = ts.into();
card_app.set_creation_time(ts, key_type)?; card_app.set_creation_time(ts, key_type)?;
// calculate/store fingerprint // calculate/store fingerprint
let fp = fp_from_pub(&pubkey, time, key_type)?; let fp = fp_from_pub(&pubkey, ts, key_type)?;
card_app.set_fingerprint(fp, key_type)?; card_app.set_fingerprint(fp, key_type)?;
Ok((pubkey, ts)) Ok((pubkey, ts))
@ -421,7 +423,7 @@ fn rsa_key_cmd(
fn copy_key_to_card( fn copy_key_to_card(
card_app: &mut CardApp, card_app: &mut CardApp,
key_type: KeyType, key_type: KeyType,
ts: u32, ts: KeyGenerationTime,
fp: Fingerprint, fp: Fingerprint,
algo: &Algo, algo: &Algo,
key_cmd: Command, key_cmd: Command,