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
use anyhow::{Error, Result};
use std::convert::TryInto;
use std::str::FromStr;
use std::string::FromUtf8Error;
use thiserror::Error;
use sequoia_openpgp::parse::Parse;
use sequoia_openpgp::serialize::SerializeInto;
use sequoia_openpgp::types::Timestamp;
use sequoia_openpgp::Cert;
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::{CardApp, KeyType};
use openpgp_card_sequoia::{
@ -96,7 +94,7 @@ pub fn test_sign(
fn check_key_upload_metadata(
ca: &mut CardApp,
meta: &[(String, u32)],
meta: &[(String, KeyGenerationTime)],
) -> Result<()> {
let ard = ca.get_app_data()?;
@ -117,21 +115,16 @@ fn check_key_upload_metadata(
// get_key_generation_times
let card_kg = ard.get_key_generation_times()?;
let sig: u32 =
card_kg.signature().expect("signature creation time").into();
assert_eq!(sig, meta[0].1);
let sig = card_kg.signature().expect("signature creation time");
assert_eq!(sig, &meta[0].1);
let dec: u32 = card_kg
.decryption()
.expect("decryption creation time")
.into();
assert_eq!(dec, meta[1].1);
let dec = card_kg.decryption().expect("decryption creation time");
assert_eq!(dec, &meta[1].1);
let auth: u32 = card_kg
let auth = card_kg
.authentication()
.expect("authentication creation time")
.into();
assert_eq!(auth, meta[2].1);
.expect("authentication creation time");
assert_eq!(auth, &meta[2].1);
Ok(())
}
@ -220,11 +213,7 @@ pub fn test_keygen(
println!(" Generate subkey for Signing");
let (pkm, ts) =
ca.generate_key_simple(public_to_fingerprint, KeyType::Signing, alg)?;
let key_sig = public_key_material_to_key(
&pkm,
KeyType::Signing,
Timestamp::from(ts).into(),
)?;
let key_sig = public_key_material_to_key(&pkm, KeyType::Signing, ts)?;
println!(" Generate subkey for Decryption");
let (pkm, ts) = ca.generate_key_simple(
@ -232,11 +221,7 @@ pub fn test_keygen(
KeyType::Decryption,
alg,
)?;
let key_dec = public_key_material_to_key(
&pkm,
KeyType::Decryption,
Timestamp::from(ts).into(),
)?;
let key_dec = public_key_material_to_key(&pkm, KeyType::Decryption, ts)?;
println!(" Generate subkey for Authentication");
let (pkm, ts) = ca.generate_key_simple(
@ -244,11 +229,8 @@ pub fn test_keygen(
KeyType::Authentication,
alg,
)?;
let key_aut = public_key_material_to_key(
&pkm,
KeyType::Authentication,
Timestamp::from(ts).into(),
)?;
let key_aut =
public_key_material_to_key(&pkm, KeyType::Authentication, ts)?;
// 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 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(
&sig,
KeyType::Signing,
@ -283,7 +265,7 @@ pub fn test_get_pub(
// --
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(
&dec,
KeyType::Decryption,
@ -295,7 +277,7 @@ pub fn test_get_pub(
// --
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(
&auth,
KeyType::Authentication,

View file

@ -18,6 +18,7 @@ use sequoia_openpgp::serialize::stream::{
};
use sequoia_openpgp::Cert;
use openpgp_card::card_do::KeyGenerationTime;
use openpgp_card::{CardApp, KeyType};
use openpgp_card_sequoia::vka_as_uploadable_key;
@ -26,7 +27,7 @@ pub const SP: &StandardPolicy = &StandardPolicy::new();
pub(crate) fn upload_subkeys(
ca: &mut CardApp,
cert: &Cert,
) -> Result<Vec<(String, u32)>> {
) -> Result<Vec<(String, KeyGenerationTime)>> {
let mut out = vec![];
for kt in [
@ -45,7 +46,7 @@ pub(crate) fn upload_subkeys(
.unwrap()
.as_secs() as u32;
out.push((fp, creation));
out.push((fp, creation.into()));
// upload key
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::card_do::{
ApplicationId, ApplicationRelatedData, Cardholder, ExtendedCap,
ExtendedLengthInfo, Features, Fingerprint, Historical, KeySet, PWStatus,
SecuritySupportTemplate, Sex,
ExtendedLengthInfo, Features, Fingerprint, Historical, KeyGenerationTime,
KeySet, PWStatus, SecuritySupportTemplate, Sex,
};
use openpgp_card::crypto_data::{
CardUploadableKey, Cryptogram, EccKey, EccType, Hash, PrivateKeyMaterial,
@ -92,8 +92,10 @@ pub fn vka_as_uploadable_key(
pub fn public_key_material_to_key(
pkm: &PublicKeyMaterial,
key_type: KeyType,
time: SystemTime,
time: KeyGenerationTime,
) -> Result<Key<PublicParts, UnspecifiedRole>> {
let time = Timestamp::from(time.get()).into();
match pkm {
PublicKeyMaterial::R(rsa) => {
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
/// (aka "UNIX timestamp")
fn get_ts(&self) -> u32 {
fn get_ts(&self) -> KeyGenerationTime {
let ts: Timestamp = Timestamp::try_from(self.key.creation_time())
.expect("Creation time cannot be converted into u32 timestamp");
let ts: u32 = ts.into();
ts.into()
}
@ -539,11 +543,11 @@ pub fn sign(
/// timestamp + KeyType" (intended for use with `CardApp.generate_key()`).
pub fn public_to_fingerprint(
pkm: &PublicKeyMaterial,
ts: SystemTime,
time: KeyGenerationTime,
kt: KeyType,
) -> Result<Fingerprint, OpenpgpCardError> {
// 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
let fp = key.fingerprint();

View file

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

View file

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

View file

@ -8,7 +8,7 @@
use anyhow::Result;
use crate::algorithm::Algo;
use crate::card_do::Fingerprint;
use crate::card_do::{Fingerprint, KeyGenerationTime};
use crate::errors::OpenpgpCardError;
/// A hash value that can be signed by the card.
@ -66,7 +66,7 @@ pub trait CardUploadableKey {
fn get_key(&self) -> Result<PrivateKeyMaterial>;
/// timestamp of (sub)key creation
fn get_ts(&self) -> u32;
fn get_ts(&self) -> KeyGenerationTime;
/// fingerprint
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::commands;
use crate::card_app::CardApp;
use crate::card_do::Fingerprint;
use crate::card_do::{Fingerprint, KeyGenerationTime};
use crate::crypto_data::{
CardUploadableKey, EccKey, EccPub, PrivateKeyMaterial, PublicKeyMaterial,
RSAKey, RSAPub,
@ -26,12 +26,12 @@ pub(crate) fn gen_key_with_metadata(
card_app: &mut CardApp,
fp_from_pub: fn(
&PublicKeyMaterial,
SystemTime,
KeyGenerationTime,
KeyType,
) -> Result<Fingerprint, OpenpgpCardError>,
key_type: KeyType,
algo: Option<&Algo>,
) -> Result<(PublicKeyMaterial, u32), OpenpgpCardError> {
) -> Result<(PublicKeyMaterial, KeyGenerationTime), OpenpgpCardError> {
// set algo on card if it's Some
if let Some(algo) = 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)))?
.as_secs() as u32;
let ts = ts.into();
card_app.set_creation_time(ts, key_type)?;
// 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)?;
Ok((pubkey, ts))
@ -421,7 +423,7 @@ fn rsa_key_cmd(
fn copy_key_to_card(
card_app: &mut CardApp,
key_type: KeyType,
ts: u32,
ts: KeyGenerationTime,
fp: Fingerprint,
algo: &Algo,
key_cmd: Command,