Implement TryFrom (instead of offering that functionality without implementing the trait)
This commit is contained in:
parent
b560d4eb5a
commit
c7751ff4ce
5 changed files with 83 additions and 60 deletions
|
@ -69,7 +69,7 @@ impl ApplicationRelatedData {
|
|||
|
||||
if let Some(eli) = eli {
|
||||
// The card has returned extended length information
|
||||
Ok(Some(ExtendedLengthInfo::from(&eli.serialize()[..])?))
|
||||
Ok(Some((&eli.serialize()[..]).try_into()?))
|
||||
} else {
|
||||
// The card didn't return this (optional) DO. That is ok.
|
||||
Ok(None)
|
||||
|
@ -117,7 +117,7 @@ impl ApplicationRelatedData {
|
|||
let psb = self.0.find(&[0xc4].into());
|
||||
|
||||
if let Some(psb) = psb {
|
||||
let pws = PWStatus::try_from(&psb.serialize())?;
|
||||
let pws = (&psb.serialize()[..]).try_into()?;
|
||||
|
||||
log::debug!("PW Status: {:x?}", pws);
|
||||
|
||||
|
@ -134,7 +134,7 @@ impl ApplicationRelatedData {
|
|||
let fp = self.0.find(&[0xc5].into());
|
||||
|
||||
if let Some(fp) = fp {
|
||||
let fp = fingerprint::to_keyset(&fp.serialize())?;
|
||||
let fp: KeySet<Fingerprint> = (&fp.serialize()[..]).try_into()?;
|
||||
|
||||
log::debug!("Fp: {:x?}", fp);
|
||||
|
||||
|
@ -151,7 +151,8 @@ impl ApplicationRelatedData {
|
|||
let kg = self.0.find(&[0xcd].into());
|
||||
|
||||
if let Some(kg) = kg {
|
||||
let kg = key_generation_times::from(&kg.serialize())?;
|
||||
let kg: KeySet<KeyGenerationTime> =
|
||||
(&kg.serialize()[..]).try_into()?;
|
||||
|
||||
log::debug!("Key generation: {:x?}", kg);
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ use anyhow::Result;
|
|||
use nom::{bytes::complete::tag, number::complete as number, sequence};
|
||||
|
||||
use crate::card_do::{complete, ExtendedLengthInfo};
|
||||
use std::convert::TryFrom;
|
||||
|
||||
fn parse(input: &[u8]) -> nom::IResult<&[u8], (u16, u16)> {
|
||||
let (input, (_, cmd, _, resp)) =
|
||||
|
@ -28,8 +29,12 @@ impl ExtendedLengthInfo {
|
|||
pub fn max_response_bytes(&self) -> u16 {
|
||||
self.max_response_bytes
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from(input: &[u8]) -> Result<Self> {
|
||||
impl TryFrom<&[u8]> for ExtendedLengthInfo {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(input: &[u8]) -> Result<Self, Self::Error> {
|
||||
let eli = complete(parse(input))?;
|
||||
|
||||
Ok(Self {
|
||||
|
|
|
@ -83,14 +83,21 @@ fn fingerprints(input: &[u8]) -> nom::IResult<&[u8], KeySet<Fingerprint>> {
|
|||
)
|
||||
}
|
||||
|
||||
/// Parse three fingerprints from the card into a KeySet of Fingerprints
|
||||
pub(crate) fn to_keyset(input: &[u8]) -> Result<KeySet<Fingerprint>, Error> {
|
||||
log::trace!("Fingerprint from input: {:x?}, len {}", input, input.len());
|
||||
impl TryFrom<&[u8]> for KeySet<Fingerprint> {
|
||||
type Error = Error;
|
||||
|
||||
// The input may be longer than 3 fingerprint, don't fail if it hasn't
|
||||
// been completely consumed.
|
||||
self::fingerprints(input)
|
||||
.map(|res| res.1)
|
||||
.map_err(|err| anyhow!("Parsing failed: {:?}", err))
|
||||
.map_err(Error::InternalError)
|
||||
fn try_from(input: &[u8]) -> Result<Self, Self::Error> {
|
||||
log::trace!(
|
||||
"Fingerprint from input: {:x?}, len {}",
|
||||
input,
|
||||
input.len()
|
||||
);
|
||||
|
||||
// The input may be longer than 3 fingerprint, don't fail if it hasn't
|
||||
// been completely consumed.
|
||||
self::fingerprints(input)
|
||||
.map(|res| res.1)
|
||||
.map_err(|err| anyhow!("Parsing failed: {:?}", err))
|
||||
.map_err(Error::InternalError)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ use nom::{combinator, number::complete as number, sequence};
|
|||
|
||||
use crate::card_do::{KeyGenerationTime, KeySet};
|
||||
use crate::Error;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
impl From<KeyGenerationTime> for DateTime<Utc> {
|
||||
fn from(kg: KeyGenerationTime) -> Self {
|
||||
|
@ -53,22 +54,26 @@ fn key_generation_set(
|
|||
)))(input)
|
||||
}
|
||||
|
||||
pub fn from(input: &[u8]) -> Result<KeySet<KeyGenerationTime>, Error> {
|
||||
// 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).
|
||||
impl TryFrom<&[u8]> for KeySet<KeyGenerationTime> {
|
||||
type Error = Error;
|
||||
|
||||
log::trace!(
|
||||
"Key generation times from input: {:x?}, len {}",
|
||||
input,
|
||||
input.len()
|
||||
);
|
||||
fn try_from(input: &[u8]) -> Result<Self, Self::Error> {
|
||||
// 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).
|
||||
|
||||
// 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(Error::InternalError)
|
||||
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(Error::InternalError)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,9 +7,43 @@ use anyhow::anyhow;
|
|||
|
||||
use crate::card_do::PWStatus;
|
||||
use crate::Error;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
impl PWStatus {
|
||||
pub fn try_from(input: &[u8]) -> Result<Self, Error> {
|
||||
/// PUT DO for PW Status Bytes accepts either 1 or 4 bytes of data.
|
||||
/// This method generates the 1 byte version for 'long==false' and the
|
||||
/// 4 bytes version for 'long==true'.
|
||||
///
|
||||
/// (See OpenPGP card spec, pg. 28)
|
||||
pub(crate) fn serialize_for_put(&self, long: bool) -> Vec<u8> {
|
||||
let mut data = vec![];
|
||||
|
||||
data.push(if !self.pw1_cds_multi { 0 } else { 1 });
|
||||
|
||||
if long {
|
||||
let mut b2 = self.pw1_len;
|
||||
if self.pw1_pin_block {
|
||||
b2 |= 0x80;
|
||||
}
|
||||
data.push(b2);
|
||||
|
||||
data.push(self.rc_len);
|
||||
|
||||
let mut b4 = self.pw3_len;
|
||||
if self.pw3_pin_block {
|
||||
b4 |= 0x80;
|
||||
}
|
||||
data.push(b4);
|
||||
}
|
||||
|
||||
data
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&[u8]> for PWStatus {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(input: &[u8]) -> Result<Self, Self::Error> {
|
||||
if input.len() == 7 {
|
||||
let pw1_cds_multi = input[0] == 0x01;
|
||||
let pw1_pin_block = input[1] & 0x80 != 0;
|
||||
|
@ -39,33 +73,4 @@ impl PWStatus {
|
|||
)))
|
||||
}
|
||||
}
|
||||
|
||||
/// PUT DO for PW Status Bytes accepts either 1 or 4 bytes of data.
|
||||
/// This method generates the 1 byte version for 'long==false' and the
|
||||
/// 4 bytes version for 'long==true'.
|
||||
///
|
||||
/// (See OpenPGP card spec, pg. 28)
|
||||
pub fn serialize_for_put(&self, long: bool) -> Vec<u8> {
|
||||
let mut data = vec![];
|
||||
|
||||
data.push(if !self.pw1_cds_multi { 0 } else { 1 });
|
||||
|
||||
if long {
|
||||
let mut b2 = self.pw1_len;
|
||||
if self.pw1_pin_block {
|
||||
b2 |= 0x80;
|
||||
}
|
||||
data.push(b2);
|
||||
|
||||
data.push(self.rc_len);
|
||||
|
||||
let mut b4 = self.pw3_len;
|
||||
if self.pw3_pin_block {
|
||||
b4 |= 0x80;
|
||||
}
|
||||
data.push(b4);
|
||||
}
|
||||
|
||||
data
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue