Implement get_key_generation_times()

This commit is contained in:
Heiko Schaefer 2021-07-14 21:59:33 +02:00
parent 7afe2f52c2
commit c445757633
4 changed files with 79 additions and 3 deletions

View file

@ -16,11 +16,12 @@ use anyhow::{anyhow, Result};
use crate::apdu::{commands, response::Response}; use crate::apdu::{commands, response::Response};
use crate::errors::OpenpgpCardError; use crate::errors::OpenpgpCardError;
use crate::parse::key_generation_times::KeyGeneration;
use crate::parse::{ use crate::parse::{
algo_attrs::Algo, algo_info::AlgoInfo, application_id::ApplicationId, algo_attrs::Algo, algo_info::AlgoInfo, application_id::ApplicationId,
cardholder::CardHolder, extended_cap::ExtendedCap, cardholder::CardHolder, extended_cap::ExtendedCap,
extended_length_info::ExtendedLengthInfo, fingerprint, extended_length_info::ExtendedLengthInfo, fingerprint,
historical::Historical, pw_status::PWStatus, KeySet, historical::Historical, key_generation_times, pw_status::PWStatus, KeySet,
}; };
use crate::tlv::{tag::Tag, Tlv, TlvEntry}; use crate::tlv::{tag::Tag, Tlv, TlvEntry};
use crate::{ use crate::{
@ -236,8 +237,20 @@ impl CardApp {
unimplemented!() unimplemented!()
} }
pub fn get_key_generation_times() { pub fn get_key_generation_times(
unimplemented!() ard: &Tlv,
) -> Result<KeySet<KeyGeneration>, OpenpgpCardError> {
let kg = ard.find(&Tag::from([0xCD]));
if let Some(kg) = kg {
let kg = key_generation_times::from(&kg.serialize())?;
log::debug!("Key generation: {:x?}", kg);
Ok(kg)
} else {
Err(anyhow!("Failed to get key generation times.").into())
}
} }
pub fn get_key_information() { pub fn get_key_information() {

View file

@ -387,6 +387,7 @@ fn copy_key_to_card(
.copied() .copied()
.collect(); .collect();
// Generation date/time
let time_cmd = let time_cmd =
commands::put_data(&[key_type.get_timestamp_put_tag()], time_value); commands::put_data(&[key_type.get_timestamp_put_tag()], time_value);

View file

@ -0,0 +1,61 @@
// SPDX-FileCopyrightText: 2021 Heiko Schaefer <heiko@schaefer.name>
// SPDX-License-Identifier: MIT OR Apache-2.0
use anyhow::anyhow;
use nom::{
bytes::complete as bytes, combinator, number::complete as number, sequence,
};
use std::fmt;
use crate::errors::OpenpgpCardError;
use crate::parse::KeySet;
#[derive(Clone, Eq, PartialEq, Debug)]
pub struct KeyGeneration(u32);
impl From<u32> for KeyGeneration {
fn from(data: u32) -> Self {
Self(data)
}
}
fn gen_time(input: &[u8]) -> nom::IResult<&[u8], u32> {
(number::be_u32)(input)
}
fn key_generation(input: &[u8]) -> nom::IResult<&[u8], Option<KeyGeneration>> {
combinator::map(gen_time, |kg| match kg {
0 => None,
kg => Some(KeyGeneration(kg)),
})(input)
}
fn key_generation_set(
input: &[u8],
) -> nom::IResult<&[u8], KeySet<KeyGeneration>> {
combinator::into(sequence::tuple((
key_generation,
key_generation,
key_generation,
)))(input)
}
pub fn from(input: &[u8]) -> Result<KeySet<KeyGeneration>, OpenpgpCardError> {
// List of generation dates/times of key pairs, binary.
// 4 bytes, Big Endian each for Sig, Dec and Aut. Each
// value shall be seconds since Jan 1, 1970. Default
// value is 00000000 (not specified).
log::trace!(
"Key generation times from input: {:x?}, len {}",
input,
input.len()
);
// The input may be longer than 3 key generation times, don't fail if it
// hasn't been completely consumed.
self::key_generation_set(input)
.map(|res| res.1)
.map_err(|err| anyhow!("Parsing failed: {:?}", err))
.map_err(OpenpgpCardError::InternalError)
}

View file

@ -12,6 +12,7 @@ pub mod extended_cap;
pub mod extended_length_info; pub mod extended_length_info;
pub mod fingerprint; pub mod fingerprint;
pub mod historical; pub mod historical;
pub mod key_generation_times;
pub mod pw_status; pub mod pw_status;
use anyhow::{anyhow, Error}; use anyhow::{anyhow, Error};