Add get_key_generation_times()
This commit is contained in:
commit
1c15e61fb4
3 changed files with 93 additions and 3 deletions
|
@ -20,7 +20,8 @@ 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,
|
||||
key_generation_times::KeyGeneration, pw_status::PWStatus, KeySet,
|
||||
};
|
||||
use crate::tlv::{tag::Tag, Tlv, TlvEntry};
|
||||
use crate::{
|
||||
|
@ -191,8 +192,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() {
|
||||
|
|
76
openpgp-card/src/parse/key_generation_times.rs
Normal file
76
openpgp-card/src/parse/key_generation_times.rs
Normal file
|
@ -0,0 +1,76 @@
|
|||
// 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;
|
||||
use chrono::{DateTime, NaiveDateTime, Utc};
|
||||
|
||||
#[derive(Clone, Eq, PartialEq, Debug)]
|
||||
pub struct KeyGeneration(u32);
|
||||
|
||||
impl From<KeyGeneration> for DateTime<Utc> {
|
||||
fn from(kg: KeyGeneration) -> Self {
|
||||
let naive_datetime = NaiveDateTime::from_timestamp(kg.0 as i64, 0);
|
||||
|
||||
DateTime::from_utc(naive_datetime, Utc)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&KeyGeneration> for u32 {
|
||||
fn from(kg: &KeyGeneration) -> Self {
|
||||
kg.0
|
||||
}
|
||||
}
|
||||
|
||||
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