Implement get_key_generation_times()
This commit is contained in:
parent
7afe2f52c2
commit
c445757633
4 changed files with 79 additions and 3 deletions
|
@ -16,11 +16,12 @@ use anyhow::{anyhow, Result};
|
|||
|
||||
use crate::apdu::{commands, response::Response};
|
||||
use crate::errors::OpenpgpCardError;
|
||||
use crate::parse::key_generation_times::KeyGeneration;
|
||||
use crate::parse::{
|
||||
algo_attrs::Algo, algo_info::AlgoInfo, application_id::ApplicationId,
|
||||
cardholder::CardHolder, extended_cap::ExtendedCap,
|
||||
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::{
|
||||
|
@ -236,8 +237,20 @@ impl CardApp {
|
|||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn get_key_generation_times() {
|
||||
unimplemented!()
|
||||
pub fn get_key_generation_times(
|
||||
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() {
|
||||
|
|
|
@ -387,6 +387,7 @@ fn copy_key_to_card(
|
|||
.copied()
|
||||
.collect();
|
||||
|
||||
// Generation date/time
|
||||
let time_cmd =
|
||||
commands::put_data(&[key_type.get_timestamp_put_tag()], time_value);
|
||||
|
||||
|
|
61
openpgp-card/src/parse/key_generation_times.rs
Normal file
61
openpgp-card/src/parse/key_generation_times.rs
Normal 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)
|
||||
}
|
|
@ -12,6 +12,7 @@ pub mod extended_cap;
|
|||
pub mod extended_length_info;
|
||||
pub mod fingerprint;
|
||||
pub mod historical;
|
||||
pub mod key_generation_times;
|
||||
pub mod pw_status;
|
||||
|
||||
use anyhow::{anyhow, Error};
|
||||
|
|
Loading…
Reference in a new issue