Implement Display for ApplicationIdentifier, CardCapabilities, CardServiceData, ExtendedCapabilities, ExtendedLengthInfo.
This commit is contained in:
parent
e6c40be8ad
commit
8e7a17faac
2 changed files with 151 additions and 7 deletions
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: 2021 Heiko Schaefer <heiko@schaefer.name>
|
// SPDX-FileCopyrightText: 2021-2022 Heiko Schaefer <heiko@schaefer.name>
|
||||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
|
||||||
//! OpenPGP card data objects (DO)
|
//! OpenPGP card data objects (DO)
|
||||||
|
@ -215,6 +215,16 @@ pub struct ApplicationIdentifier {
|
||||||
serial: u32,
|
serial: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for ApplicationIdentifier {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"D276000124 01 {:02X} {:04X} {:04X} {:08X} 0000",
|
||||||
|
self.application, self.version, self.manufacturer, self.serial
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// 6 Historical Bytes
|
/// 6 Historical Bytes
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct HistoricalBytes {
|
pub struct HistoricalBytes {
|
||||||
|
@ -239,17 +249,69 @@ pub struct CardCapabilities {
|
||||||
extended_length_information: bool,
|
extended_length_information: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Card service data (see 6 Historical Bytes
|
impl Display for CardCapabilities {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
if self.command_chaining {
|
||||||
|
writeln!(f, "- command chaining")?;
|
||||||
|
}
|
||||||
|
if self.extended_lc_le {
|
||||||
|
writeln!(f, "- extended Lc and Le fields")?;
|
||||||
|
}
|
||||||
|
if self.extended_length_information {
|
||||||
|
writeln!(f, "- extended Length Information")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Card service data (see 6 Historical Bytes)
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct CardServiceData {
|
pub struct CardServiceData {
|
||||||
select_by_full_df_name: bool,
|
select_by_full_df_name: bool, // Application Selection by full DF name (AID)
|
||||||
select_by_partial_df_name: bool,
|
select_by_partial_df_name: bool, // Application Selection by partial DF name
|
||||||
dos_available_in_ef_dir: bool,
|
dos_available_in_ef_dir: bool,
|
||||||
dos_available_in_ef_atr_info: bool,
|
dos_available_in_ef_atr_info: bool, // should be true if extended length supported
|
||||||
access_services: [bool; 3],
|
access_services: [bool; 3], // should be '010' if extended length supported
|
||||||
mf: bool,
|
mf: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for CardServiceData {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
if self.select_by_full_df_name {
|
||||||
|
writeln!(f, "- Application Selection by full DF name")?;
|
||||||
|
}
|
||||||
|
if self.select_by_partial_df_name {
|
||||||
|
writeln!(f, "- Application Selection by partial DF name")?;
|
||||||
|
}
|
||||||
|
if self.dos_available_in_ef_dir {
|
||||||
|
writeln!(f, "- DOs available in EF.DIR")?;
|
||||||
|
}
|
||||||
|
if self.dos_available_in_ef_atr_info {
|
||||||
|
writeln!(f, "- DOs available in EF.ATR/INFO")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"- EF.DIR and EF.ATR/INFO access services by the GET DATA command (BER-TLV): "
|
||||||
|
)?;
|
||||||
|
for a in self.access_services {
|
||||||
|
if a {
|
||||||
|
write!(f, "1")?;
|
||||||
|
} else {
|
||||||
|
write!(f, "0")?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writeln!(f)?;
|
||||||
|
|
||||||
|
if self.mf {
|
||||||
|
writeln!(f, "- Card with MF")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// 4.4.3.7 Extended Capabilities
|
/// 4.4.3.7 Extended Capabilities
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub struct ExtendedCapabilities {
|
pub struct ExtendedCapabilities {
|
||||||
|
@ -274,6 +336,76 @@ pub struct ExtendedCapabilities {
|
||||||
mse_command_support: Option<bool>, // v3
|
mse_command_support: Option<bool>, // v3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for ExtendedCapabilities {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
if self.secure_messaging {
|
||||||
|
writeln!(f, "- secure messaging")?;
|
||||||
|
}
|
||||||
|
if self.get_challenge {
|
||||||
|
writeln!(f, "- get challenge")?;
|
||||||
|
}
|
||||||
|
if self.key_import {
|
||||||
|
writeln!(f, "- key import")?;
|
||||||
|
}
|
||||||
|
if self.pw_status_change {
|
||||||
|
writeln!(f, "- PW Status changeable")?;
|
||||||
|
}
|
||||||
|
if self.private_use_dos {
|
||||||
|
writeln!(f, "- private use DOs")?;
|
||||||
|
}
|
||||||
|
if self.algo_attrs_changeable {
|
||||||
|
writeln!(f, "- algorithm attributes changeable")?;
|
||||||
|
}
|
||||||
|
if self.aes {
|
||||||
|
writeln!(f, "- PSO:DEC/ENC with AES")?;
|
||||||
|
}
|
||||||
|
if self.kdf_do {
|
||||||
|
writeln!(f, "- KDF-DO")?;
|
||||||
|
}
|
||||||
|
if self.sm_algo != 0 {
|
||||||
|
writeln!(f, "- secure messaging algorithm: {:#02X}", self.sm_algo)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.max_len_challenge != 0 {
|
||||||
|
writeln!(
|
||||||
|
f,
|
||||||
|
"- maximum length of challenge: {}",
|
||||||
|
self.max_len_challenge
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
writeln!(
|
||||||
|
f,
|
||||||
|
"- maximum length cardholder certificates: {}",
|
||||||
|
self.max_len_cardholder_cert
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// v2
|
||||||
|
if let Some(max_cmd_len) = self.max_cmd_len {
|
||||||
|
writeln!(f, "- maximum command length: {}", max_cmd_len)?;
|
||||||
|
}
|
||||||
|
if let Some(max_resp_len) = self.max_resp_len {
|
||||||
|
writeln!(f, "- maximum response length: {}", max_resp_len)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// v3
|
||||||
|
if let Some(max_len_special_do) = self.max_len_special_do {
|
||||||
|
writeln!(
|
||||||
|
f,
|
||||||
|
"- maximum length for special DOs: {}",
|
||||||
|
max_len_special_do
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
if self.pin_block_2_format_support == Some(true) {
|
||||||
|
writeln!(f, "- PIN block 2 format supported")?;
|
||||||
|
}
|
||||||
|
if self.mse_command_support == Some(true) {
|
||||||
|
writeln!(f, "- MSE command (for DEC and AUT) supported")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// 4.1.3.1 Extended length information
|
/// 4.1.3.1 Extended length information
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub struct ExtendedLengthInfo {
|
pub struct ExtendedLengthInfo {
|
||||||
|
@ -281,6 +413,14 @@ pub struct ExtendedLengthInfo {
|
||||||
max_response_bytes: u16,
|
max_response_bytes: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for ExtendedLengthInfo {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
writeln!(f, "- max command length: {}", self.max_command_bytes)?;
|
||||||
|
writeln!(f, "- max response length: {}", self.max_response_bytes)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Cardholder Related Data (see spec pg. 22)
|
/// Cardholder Related Data (see spec pg. 22)
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct CardholderRelatedData {
|
pub struct CardholderRelatedData {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: 2021 Heiko Schaefer <heiko@schaefer.name>
|
// SPDX-FileCopyrightText: 2021-2022 Heiko Schaefer <heiko@schaefer.name>
|
||||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
|
||||||
//! 6 Historical Bytes
|
//! 6 Historical Bytes
|
||||||
|
@ -73,6 +73,10 @@ impl HistoricalBytes {
|
||||||
pub fn card_capabilities(&self) -> Option<&CardCapabilities> {
|
pub fn card_capabilities(&self) -> Option<&CardCapabilities> {
|
||||||
self.cc.as_ref()
|
self.cc.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn card_service_data(&self) -> Option<&CardServiceData> {
|
||||||
|
self.csd.as_ref()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<&[u8]> for HistoricalBytes {
|
impl TryFrom<&[u8]> for HistoricalBytes {
|
||||||
|
|
Loading…
Reference in a new issue