From 099c78d9793e0fe9eb8e8588aaeaabfcb09ef15a Mon Sep 17 00:00:00 2001 From: Kai Jan Kriegel Date: Sun, 26 Dec 2021 02:33:05 +0100 Subject: [PATCH] reformated files with rustfmt --- src/crypto/cipher/aes.rs | 16 +++---- src/crypto/cipher/mod.rs | 4 +- src/crypto/cipher/tdes.rs | 19 ++++---- src/crypto/cipher/tdes_2k.rs | 19 ++++---- src/crypto/cipher/tdes_3k.rs | 19 ++++---- src/crypto/cipher_key.rs | 30 ++++++++---- src/crypto/cipher_type.rs | 4 +- src/crypto/crc/crc16.rs | 2 +- src/crypto/crc/crc32.rs | 2 +- src/crypto/crc/mod.rs | 2 +- src/crypto/mod.rs | 6 +-- src/crypto/util.rs | 11 +++-- src/desfire/apduinstructions.rs | 76 +++++++++++++++---------------- src/desfire/mod.rs | 54 +++++++++++----------- src/error.rs | 29 +++++++++--- src/iso7816_4/apducommand.rs | 78 ++++++++++++++++++++------------ src/iso7816_4/apduresponse.rs | 73 ++++++++++++++++++------------ src/iso7816_4/apdustatuswords.rs | 7 +-- src/iso7816_4/mod.rs | 2 +- src/lib.rs | 32 ++++++------- tests/lib.rs | 2 +- 21 files changed, 271 insertions(+), 216 deletions(-) diff --git a/src/crypto/cipher/aes.rs b/src/crypto/cipher/aes.rs index aaa865d..97b2b20 100644 --- a/src/crypto/cipher/aes.rs +++ b/src/crypto/cipher/aes.rs @@ -1,8 +1,8 @@ -use aes::Aes128; -use block_modes::{BlockMode, Cbc}; -use block_modes::block_padding::NoPadding; -use crate::error::{Result, Error}; use super::Cipher; +use crate::error::{Error, Result}; +use aes::Aes128; +use block_modes::block_padding::NoPadding; +use block_modes::{BlockMode, Cbc}; type Aes128Cbc = Cbc; @@ -23,16 +23,16 @@ impl Cipher for AES { let result = cipher.decrypt_vec(data); return match result { - Ok(data) => { Ok(data) } - Err(err) => { Err(Error::BlockModeError(err)) } - } + Ok(data) => Ok(data), + Err(err) => Err(Error::BlockModeError(err)), + }; } } #[cfg(test)] mod tests { - use hex_literal::hex; use crate::crypto::cipher::Cipher; + use hex_literal::hex; #[test] fn encrypt() { diff --git a/src/crypto/cipher/mod.rs b/src/crypto/cipher/mod.rs index aa04bec..55506e0 100644 --- a/src/crypto/cipher/mod.rs +++ b/src/crypto/cipher/mod.rs @@ -10,6 +10,6 @@ pub trait Cipher { const BLOCK_SIZE: usize; const KEY_SIZE: usize; - fn encrypt (data: &[u8], key: &[u8], iv: &[u8]) -> Result>; + fn encrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result>; fn decrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result>; -} \ No newline at end of file +} diff --git a/src/crypto/cipher/tdes.rs b/src/crypto/cipher/tdes.rs index d403831..5a441a1 100644 --- a/src/crypto/cipher/tdes.rs +++ b/src/crypto/cipher/tdes.rs @@ -1,9 +1,9 @@ //FIXME: Which TDES Mode should be used by this? -use des::TdesEde2; -use block_modes::{BlockMode, Cbc}; -use block_modes::block_padding::NoPadding; -use crate::error::{Result, Error}; use crate::crypto::cipher::Cipher; +use crate::error::{Error, Result}; +use block_modes::block_padding::NoPadding; +use block_modes::{BlockMode, Cbc}; +use des::TdesEde2; type TDesEde2Cbc = Cbc; @@ -22,19 +22,18 @@ impl Cipher for Tdes { fn decrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result> { let cipher = TDesEde2Cbc::new_var(&key, &iv)?; - let result = cipher.decrypt_vec(data); return match result { - Ok(data) => { Ok(data) } - Err(err) => { Err(Error::BlockModeError(err)) } - } + Ok(data) => Ok(data), + Err(err) => Err(Error::BlockModeError(err)), + }; } } #[cfg(test)] mod tests { - use hex_literal::hex; use crate::crypto::cipher::Cipher; + use hex_literal::hex; #[test] #[ignore] @@ -49,4 +48,4 @@ mod tests { assert_eq!(data_enc, data_enc_expected); } -} \ No newline at end of file +} diff --git a/src/crypto/cipher/tdes_2k.rs b/src/crypto/cipher/tdes_2k.rs index 36fd602..0a76cd7 100644 --- a/src/crypto/cipher/tdes_2k.rs +++ b/src/crypto/cipher/tdes_2k.rs @@ -1,9 +1,9 @@ //FIXME: Which TDES Mode should be used by this? -use des::TdesEde2; -use block_modes::{BlockMode, Cbc}; -use block_modes::block_padding::NoPadding; -use crate::error::{Result, Error}; use crate::crypto::cipher::Cipher; +use crate::error::{Error, Result}; +use block_modes::block_padding::NoPadding; +use block_modes::{BlockMode, Cbc}; +use des::TdesEde2; type TDesEde2Cbc = Cbc; @@ -22,19 +22,18 @@ impl Cipher for Tdes2k { fn decrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result> { let cipher = TDesEde2Cbc::new_var(&key, &iv)?; - let result = cipher.decrypt_vec(data); return match result { - Ok(data) => { Ok(data) } - Err(err) => { Err(Error::BlockModeError(err)) } - } + Ok(data) => Ok(data), + Err(err) => Err(Error::BlockModeError(err)), + }; } } #[cfg(test)] mod tests { - use hex_literal::hex; use crate::crypto::cipher::Cipher; + use hex_literal::hex; #[test] #[ignore] @@ -49,4 +48,4 @@ mod tests { assert_eq!(data_enc, data_enc_expected); } -} \ No newline at end of file +} diff --git a/src/crypto/cipher/tdes_3k.rs b/src/crypto/cipher/tdes_3k.rs index a31d85d..81d35ee 100644 --- a/src/crypto/cipher/tdes_3k.rs +++ b/src/crypto/cipher/tdes_3k.rs @@ -1,9 +1,9 @@ //FIXME: Which TDES Mode should be used by this? -use des::TdesEde3; -use block_modes::{BlockMode, Cbc}; -use block_modes::block_padding::NoPadding; -use crate::error::{Result, Error}; use crate::crypto::cipher::Cipher; +use crate::error::{Error, Result}; +use block_modes::block_padding::NoPadding; +use block_modes::{BlockMode, Cbc}; +use des::TdesEde3; type TDesEde3Cbc = Cbc; @@ -22,19 +22,18 @@ impl Cipher for Tdes3k { fn decrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result> { let cipher = TDesEde3Cbc::new_var(&key, &iv)?; - let result = cipher.decrypt_vec(data); return match result { - Ok(data) => { Ok(data) } - Err(err) => { Err(Error::BlockModeError(err)) } - } + Ok(data) => Ok(data), + Err(err) => Err(Error::BlockModeError(err)), + }; } } #[cfg(test)] mod tests { - use hex_literal::hex; use crate::crypto::cipher::Cipher; + use hex_literal::hex; #[test] #[ignore] @@ -49,4 +48,4 @@ mod tests { assert_eq!(data_enc, data_enc_expected); } -} \ No newline at end of file +} diff --git a/src/crypto/cipher_key.rs b/src/crypto/cipher_key.rs index e0b8bb9..2435e01 100644 --- a/src/crypto/cipher_key.rs +++ b/src/crypto/cipher_key.rs @@ -1,6 +1,6 @@ +use crate::crypto::cipher::{aes, tdes, tdes_2k, tdes_3k, Cipher}; use crate::crypto::cipher_type::CipherType; use crate::crypto::cipher_type::CipherType::*; -use crate::crypto::cipher::{aes, tdes, tdes_2k, tdes_3k, Cipher}; use crate::error::Error; use crate::error::Result; @@ -15,17 +15,21 @@ pub struct CipherKey { cipher: CipherType, /// KeyVersion of Key - key_version: u8 + key_version: u8, } impl CipherKey { pub fn new(key: &[u8], cipher: CipherType, key_version: u8) -> Result { if cipher == AES && key_version < 0x10 { - return Err(Error::Boxed(Box::new(simple_error!("KeyVersion is to low for AES Key (Minimum = 0x10)")))) + return Err(Error::Boxed(Box::new(simple_error!( + "KeyVersion is to low for AES Key (Minimum = 0x10)" + )))); } if !check_key(key, cipher.clone()) { - return Err(Error::Boxed(Box::new(simple_error!("Key is not valid for CipherType")))) + return Err(Error::Boxed(Box::new(simple_error!( + "Key is not valid for CipherType" + )))); } let mut key: Box<[u8]> = Box::from(key); @@ -36,7 +40,7 @@ impl CipherKey { Ok(CipherKey { cipher, key_version, - key + key, }) } @@ -45,10 +49,10 @@ impl CipherKey { } pub fn new_empty(cipher: CipherType) -> Result { - Ok(CipherKey{ + Ok(CipherKey { key: generate_empty_key(cipher.clone()), key_version: if cipher == AES { 0x10u8 } else { 0x00u8 }, - cipher + cipher, }) } } @@ -72,7 +76,11 @@ pub fn get_key_size(cipher: CipherType) -> usize { /// Check Key Slice pub fn check_key(key: &[u8], cipher: CipherType) -> bool { - if key.len() != get_key_size(cipher) { false } else { true } + if key.len() != get_key_size(cipher) { + false + } else { + true + } } /// Set Key Version for DES/TDES Keys @@ -80,7 +88,9 @@ pub fn check_key(key: &[u8], cipher: CipherType) -> bool { /// Parity Bits are not used from DESFire Cars pub fn set_key_version(key: &[u8], version: u8) -> Box<[u8]> { - let pow2 = [0x01u8, 0x02u8, 0x04u8, 0x08u8, 0x10u8, 0x20u8, 0x40u8, 0x80u8]; + let pow2 = [ + 0x01u8, 0x02u8, 0x04u8, 0x08u8, 0x10u8, 0x20u8, 0x40u8, 0x80u8, + ]; let mut new_key = key.to_vec(); @@ -92,4 +102,4 @@ pub fn set_key_version(key: &[u8], version: u8) -> Box<[u8]> { } } new_key.into_boxed_slice() -} \ No newline at end of file +} diff --git a/src/crypto/cipher_type.rs b/src/crypto/cipher_type.rs index 1be2b31..f2ad4ff 100644 --- a/src/crypto/cipher_type.rs +++ b/src/crypto/cipher_type.rs @@ -10,5 +10,5 @@ pub enum CipherType { TDES3K, /// AES - AES -} \ No newline at end of file + AES, +} diff --git a/src/crypto/crc/crc16.rs b/src/crypto/crc/crc16.rs index c6840ab..2c0f372 100644 --- a/src/crypto/crc/crc16.rs +++ b/src/crypto/crc/crc16.rs @@ -41,4 +41,4 @@ mod tests { assert_eq!(*crc, crc_expected); } -} \ No newline at end of file +} diff --git a/src/crypto/crc/crc32.rs b/src/crypto/crc/crc32.rs index fe09913..24dcc58 100644 --- a/src/crypto/crc/crc32.rs +++ b/src/crypto/crc/crc32.rs @@ -41,4 +41,4 @@ mod tests { assert_eq!(*crc, crc_expected); } -} \ No newline at end of file +} diff --git a/src/crypto/crc/mod.rs b/src/crypto/crc/mod.rs index 7597b18..f3aaf80 100644 --- a/src/crypto/crc/mod.rs +++ b/src/crypto/crc/mod.rs @@ -1,2 +1,2 @@ pub mod crc16; -pub mod crc32; \ No newline at end of file +pub mod crc32; diff --git a/src/crypto/mod.rs b/src/crypto/mod.rs index 78915ab..3edc8d9 100644 --- a/src/crypto/mod.rs +++ b/src/crypto/mod.rs @@ -1,5 +1,5 @@ pub mod cipher; -pub mod crc; -pub mod cipher_type; pub mod cipher_key; -pub mod util; \ No newline at end of file +pub mod cipher_type; +pub mod crc; +pub mod util; diff --git a/src/crypto/util.rs b/src/crypto/util.rs index 87c2ba6..05c7745 100644 --- a/src/crypto/util.rs +++ b/src/crypto/util.rs @@ -1,10 +1,15 @@ -use crate::error::{Result, Error}; +use crate::error::{Error, Result}; use simple_error::simple_error; /// Extracts the the last `n` bytes of a slice. n being the blocksize. pub fn extract_last_block(data: &[u8], blocksize: usize) -> Result<&[u8]> { if data.len() % blocksize != 0 { - return Err(simple_error!("Data is not compatible with blocksize: data(length): {}, blocksize: {}.", data.len(), blocksize).into()) + return Err(simple_error!( + "Data is not compatible with blocksize: data(length): {}, blocksize: {}.", + data.len(), + blocksize + ) + .into()); } Ok(&data[(data.len() - blocksize)..]) @@ -21,4 +26,4 @@ pub fn expand_to_blocksize(data: &mut [u8], blocksize: usize) -> Result> buf[..data.len()].copy_from_slice(data); Ok(buf) } -} \ No newline at end of file +} diff --git a/src/desfire/apduinstructions.rs b/src/desfire/apduinstructions.rs index 3ed2b2d..3a74be9 100644 --- a/src/desfire/apduinstructions.rs +++ b/src/desfire/apduinstructions.rs @@ -1,41 +1,41 @@ #[repr(u8)] pub enum APDUInstructions { - AUTHENTICATE_ISO = 0x1A, - AUTHENTICATE_AES = 0xAA, - CHANGE_KEY_SETTINGS = 0x54, - SET_CONFIGURATION = 0x5C, - CHANGE_KEY = 0xC4, - GET_KEY_VERSION = 0x64, - CREATE_APPLICATION = 0xCA, - DELETE_APPLICATION = 0xDA, - GET_APPLICATION_IDS = 0x6A, - FREE_MEMORY = 0x6E, - GET_DF_NAMES = 0x6D, - GET_KEY_SETTINGS = 0x45, - SELECT_APPLICATION = 0x5A, - FORMAT_PICC = 0xFC, - GET_VERSION = 0x60, - GET_CARD_UID = 0x51, - GET_FILE_IDS = 0x6F, - GET_FILE_SETTINGS = 0xF5, - CHANGE_FILE_SETTINGS = 0x5F, - CREATE_STDDATAFILE = 0xCD, - CREATE_BACKUPDATAFILE = 0xCB, - CREATE_VALUE_FILE = 0xCC, - CREATE_LINEAR_RECORD_FILE = 0xC1, - CREATE_CYCLIC_RECORD_FILE = 0xC0, - DELETE_FILE = 0xDF, - GET_ISO_FILE_IDS = 0x61, - READ_DATA = 0xBD, - WRITE_DATA = 0x3D, - GET_VALUE = 0x6C, - CREDIT = 0x0C, - DEBIT = 0xDC, - LIMITED_CREDIT = 0x1C, - WRITE_RECORD = 0x3B, - READ_RECORDS = 0xBB, - CLEAR_RECORD_FILE = 0xEB, - COMMIT_TRANSACTION = 0xC7, - ABORT_TRANSACTION = 0xA7, - CONTINUE = 0xAF, + AUTHENTICATE_ISO = 0x1A, + AUTHENTICATE_AES = 0xAA, + CHANGE_KEY_SETTINGS = 0x54, + SET_CONFIGURATION = 0x5C, + CHANGE_KEY = 0xC4, + GET_KEY_VERSION = 0x64, + CREATE_APPLICATION = 0xCA, + DELETE_APPLICATION = 0xDA, + GET_APPLICATION_IDS = 0x6A, + FREE_MEMORY = 0x6E, + GET_DF_NAMES = 0x6D, + GET_KEY_SETTINGS = 0x45, + SELECT_APPLICATION = 0x5A, + FORMAT_PICC = 0xFC, + GET_VERSION = 0x60, + GET_CARD_UID = 0x51, + GET_FILE_IDS = 0x6F, + GET_FILE_SETTINGS = 0xF5, + CHANGE_FILE_SETTINGS = 0x5F, + CREATE_STDDATAFILE = 0xCD, + CREATE_BACKUPDATAFILE = 0xCB, + CREATE_VALUE_FILE = 0xCC, + CREATE_LINEAR_RECORD_FILE = 0xC1, + CREATE_CYCLIC_RECORD_FILE = 0xC0, + DELETE_FILE = 0xDF, + GET_ISO_FILE_IDS = 0x61, + READ_DATA = 0xBD, + WRITE_DATA = 0x3D, + GET_VALUE = 0x6C, + CREDIT = 0x0C, + DEBIT = 0xDC, + LIMITED_CREDIT = 0x1C, + WRITE_RECORD = 0x3B, + READ_RECORDS = 0xBB, + CLEAR_RECORD_FILE = 0xEB, + COMMIT_TRANSACTION = 0xC7, + ABORT_TRANSACTION = 0xA7, + CONTINUE = 0xAF, } diff --git a/src/desfire/mod.rs b/src/desfire/mod.rs index ad69250..2de8c1d 100644 --- a/src/desfire/mod.rs +++ b/src/desfire/mod.rs @@ -1,6 +1,5 @@ use num_derive::FromPrimitive; - /// /// hold the Access Rights for changing application keys (Change Key command) /// @@ -28,13 +27,13 @@ pub enum ChangeApplicationKey { #[derive(Clone, Copy)] pub enum ChangeMasterKey { /// -/// Application master key is not changeable anymore (frozen) -/// + /// Application master key is not changeable anymore (frozen) + /// FROZEN = 0x00, /// -/// Application master key is changeable (authentication with the current application master key necessary, default) -/// + /// Application master key is changeable (authentication with the current application master key necessary, default) + /// CHANGEABLE = 0x01, } @@ -44,16 +43,15 @@ pub enum ChangeMasterKey { #[repr(u8)] #[derive(Clone, Copy)] pub enum ChangeMasterKeySettings { + /// + /// configuration not changeable anymore (frozen) + /// + FROZEN = 0x00, -/// -/// configuration not changeable anymore (frozen) -/// -FROZEN = 0x00, - -/// -/// this configuration is changeable if authenticated with the application master key (default) -/// -WITHMASTERKEY = 0x08 + /// + /// this configuration is changeable if authenticated with the application master key (default) + /// + WITHMASTERKEY = 0x08, } /// @@ -62,15 +60,15 @@ WITHMASTERKEY = 0x08 #[repr(u8)] #[derive(Clone, Copy)] pub enum CreateDeleteFile { -/// -/// “Create File”/ “Delete File”is permitted only with application master key authentication -/// -ONLYMASTERKEY = 0x00, + /// + /// “Create File”/ “Delete File”is permitted only with application master key authentication + /// + ONLYMASTERKEY = 0x00, -/// -/// “Create File”/ “Delete File”is permitted also without application master key authentication (default) -/// -NOKEY = 0x04, + /// + /// “Create File”/ “Delete File”is permitted also without application master key authentication (default) + /// + NOKEY = 0x04, } /// @@ -88,7 +86,7 @@ pub enum CryptoOperationsType { #[derive(Clone, Copy)] pub enum FileAccessRights { FREE = 0x0E, - NEVER = 0x0F + NEVER = 0x0F, } #[repr(u8)] @@ -107,7 +105,7 @@ pub enum FileCommunication { /// /// Fully DES/3DES enciphered communication /// - ENCRYPT = 0x03 + ENCRYPT = 0x03, } /// @@ -134,7 +132,7 @@ pub enum FileDirectoryAccess { #[derive(Clone, Copy)] pub enum FileIdentifiers { NOTUSED = 0x00, - USED = 0x20 + USED = 0x20, } #[repr(u8)] @@ -143,7 +141,7 @@ pub enum FileTypes { /// /// Standard Data File /// - STANDARD = 0x00, + STANDARD = 0x00, /// /// Backup Data Files @@ -163,9 +161,9 @@ pub enum FileTypes { /// /// Cyclic Record Files with Backup /// - CYCLICRECORD = 0x04 + CYCLICRECORD = 0x04, } mod apduinstructions; mod apdustatuscodes; -mod desfire; \ No newline at end of file +mod desfire; diff --git a/src/error.rs b/src/error.rs index 7938aa9..c57b05e 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,5 +1,5 @@ -use std::io; use std::fmt; +use std::io; #[derive(Debug)] pub enum Error { @@ -66,7 +66,10 @@ impl fmt::Display for Error { write!(f, "SW2: Command code not supported.") } Error::IntegrityError => { - write!(f, "SW2: CRC or MAC does not match data. Paddingbytes not valid.") + write!( + f, + "SW2: CRC or MAC does not match data. Paddingbytes not valid." + ) } Error::NoSuchKey => { write!(f, "SW2: Invalid key number specified.") @@ -75,7 +78,10 @@ impl fmt::Display for Error { write!(f, "SW2: Length of command string invalid.") } Error::PermissionDenied => { - write!(f, "SW2: Current configuration / status does not allow the requested command.") + write!( + f, + "SW2: Current configuration / status does not allow the requested command." + ) } Error::ParameterError => { write!(f, "SW2: Value of the parameter(s) invalid.") @@ -84,7 +90,10 @@ impl fmt::Display for Error { write!(f, "SW2: Currently not allowed to authenticate. Keeptrying until full delay is spent.") } Error::AuthenticationError => { - write!(f, "SW2: Current authentication status does not allow the requested command.") + write!( + f, + "SW2: Current authentication status does not allow the requested command." + ) } Error::BoundaryError => { write!(f, "SW2: Attempt to read/write data from/to beyond the file’s/record’s limits. Attempt to exceed the limits of a value file.") @@ -139,7 +148,9 @@ impl From for Error { } impl From for Error { - fn from(e: simple_error::SimpleError) -> Error { Error::Simple(e) } + fn from(e: simple_error::SimpleError) -> Error { + Error::Simple(e) + } } impl From for Error { @@ -155,11 +166,15 @@ impl From for Error { } impl From for Error { - fn from(e: hex::FromHexError) -> Error { Error::FromHexError(e) } + fn from(e: hex::FromHexError) -> Error { + Error::FromHexError(e) + } } impl From for Error { - fn from(e: block_modes::block_padding::PadError) -> Error { Error::PadError(e) } + fn from(e: block_modes::block_padding::PadError) -> Error { + Error::PadError(e) + } } pub(crate) type Result = std::result::Result; diff --git a/src/iso7816_4/apducommand.rs b/src/iso7816_4/apducommand.rs index 398a374..d88450f 100644 --- a/src/iso7816_4/apducommand.rs +++ b/src/iso7816_4/apducommand.rs @@ -1,19 +1,19 @@ +use crate::error::{Error, Result}; +use std::convert::TryFrom; use std::fmt; use std::fmt::Formatter; -use std::convert::TryFrom; -use crate::error::{Result, Error}; #[repr(u8)] #[derive(Eq, PartialEq, Hash, Debug, Clone)] pub enum IsoCase { /// No command data. No response data. - /// - /// - /// lc is valued to 0. - /// le is valued to 0. - /// No data byte is present. - /// - /// + /// + /// + /// lc is valued to 0. + /// le is valued to 0. + /// No data byte is present. + /// + /// Case1 = 0, /// No command data. Expected response data. @@ -78,7 +78,9 @@ pub enum IsoCase { } impl Default for IsoCase { - fn default() -> Self { IsoCase::Case1 } + fn default() -> Self { + IsoCase::Case1 + } } #[repr(u8)] @@ -106,7 +108,9 @@ pub enum SCardProtocol { } impl Default for SCardProtocol { - fn default() -> Self { SCardProtocol::Any } + fn default() -> Self { + SCardProtocol::Any + } } #[derive(Eq, PartialEq, Hash, Debug, Default, Clone)] @@ -155,10 +159,7 @@ impl TryFrom for Vec { v.push(cmd.le as u8); } } - _ => { - - return Err(Error::InvalidIsoCase) - } + _ => return Err(Error::InvalidIsoCase), } Ok(v) } @@ -180,10 +181,18 @@ impl fmt::Display for APDUCommand { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self.case { IsoCase::Case1 => { - write!(f, "(CASE: 1) cla: {:#X} | ins: {:#X} | p1: {:#X} | p2: {:#X}", self.cla, self.ins, self.p1, self.p2) + write!( + f, + "(CASE: 1) cla: {:#X} | ins: {:#X} | p1: {:#X} | p2: {:#X}", + self.cla, self.ins, self.p1, self.p2 + ) } IsoCase::Case2Short | IsoCase::Case2Extended => { - write!(f, "(CASE: 2) cla: {:#X} | ins: {:#X} | p1: {:#X} | p2: {:#X} | LE: {:#X}", self.cla, self.ins, self.p1, self.p2, self.le) + write!( + f, + "(CASE: 2) cla: {:#X} | ins: {:#X} | p1: {:#X} | p2: {:#X} | LE: {:#X}", + self.cla, self.ins, self.p1, self.p2, self.le + ) } IsoCase::Case3Short | IsoCase::Case3Extended => { write!(f, "(CASE: 3) cla: {:#X} | ins: {:#X} | p1: {:#X} | p2: {:#X} | LC: {:#X} | data: [ ", self.cla, self.ins, self.p1, self.p2, self.lc())?; @@ -205,11 +214,11 @@ impl fmt::Display for APDUCommand { #[cfg(test)] mod tests { - use crate::iso7816_4::apducommand::{APDUCommand, SCardProtocol, IsoCase}; + use crate::iso7816_4::apducommand::{APDUCommand, IsoCase, SCardProtocol}; #[test] fn compare() { - let command1 = APDUCommand{ + let command1 = APDUCommand { case: IsoCase::Case4Short, protocol: SCardProtocol::Unset, cla: 0x90, @@ -218,7 +227,7 @@ mod tests { ..Default::default() }; - let command2 = APDUCommand{ + let command2 = APDUCommand { case: IsoCase::Case4Short, protocol: SCardProtocol::Unset, cla: 0x90, @@ -232,7 +241,7 @@ mod tests { #[test] fn compare_diff() { - let command1 = APDUCommand{ + let command1 = APDUCommand { case: IsoCase::Case4Short, protocol: SCardProtocol::Unset, cla: 0x90, @@ -241,7 +250,7 @@ mod tests { ..Default::default() }; - let command2 = APDUCommand{ + let command2 = APDUCommand { case: IsoCase::Case4Short, protocol: SCardProtocol::Unset, cla: 0x90, @@ -255,7 +264,7 @@ mod tests { #[test] fn to_string_case1() { - let command1 = APDUCommand{ + let command1 = APDUCommand { case: IsoCase::Case1, cla: 0x90, ins: 0x1A, @@ -263,12 +272,15 @@ mod tests { }; println!("{}", command1.to_string()); - assert_eq!("(CASE: 1) cla: 0x90 | ins: 0x1A | p1: 0x0 | p2: 0x0", command1.to_string()); + assert_eq!( + "(CASE: 1) cla: 0x90 | ins: 0x1A | p1: 0x0 | p2: 0x0", + command1.to_string() + ); } #[test] fn to_string_case2() { - let command1 = APDUCommand{ + let command1 = APDUCommand { case: IsoCase::Case2Short, cla: 0x90, ins: 0x1A, @@ -276,12 +288,15 @@ mod tests { }; println!("{}", command1.to_string()); - assert_eq!("(CASE: 2) cla: 0x90 | ins: 0x1A | p1: 0x0 | p2: 0x0 | LE: 0x0", command1.to_string()); + assert_eq!( + "(CASE: 2) cla: 0x90 | ins: 0x1A | p1: 0x0 | p2: 0x0 | LE: 0x0", + command1.to_string() + ); } #[test] fn to_string_case3() { - let command1 = APDUCommand{ + let command1 = APDUCommand { case: IsoCase::Case3Short, cla: 0x90, ins: 0x1A, @@ -290,12 +305,15 @@ mod tests { }; println!("{}", command1.to_string()); - assert_eq!("(CASE: 3) cla: 0x90 | ins: 0x1A | p1: 0x0 | p2: 0x0 | LC: 0x3 | data: [ 0x1 0x2 0x3 ]", command1.to_string()); + assert_eq!( + "(CASE: 3) cla: 0x90 | ins: 0x1A | p1: 0x0 | p2: 0x0 | LC: 0x3 | data: [ 0x1 0x2 0x3 ]", + command1.to_string() + ); } #[test] fn to_string_case4() { - let command1 = APDUCommand{ + let command1 = APDUCommand { case: IsoCase::Case4Short, cla: 0x90, ins: 0x1A, @@ -306,4 +324,4 @@ mod tests { println!("{}", command1.to_string()); assert_eq!("(CASE: 4) cla: 0x90 | ins: 0x1A | p1: 0x0 | p2: 0x0 | LC: 0x3 | data: [ 0x1 0x2 0x3 ] | LE: 0x0", command1.to_string()); } -} \ No newline at end of file +} diff --git a/src/iso7816_4/apduresponse.rs b/src/iso7816_4/apduresponse.rs index 515fac7..1240cfa 100644 --- a/src/iso7816_4/apduresponse.rs +++ b/src/iso7816_4/apduresponse.rs @@ -1,7 +1,11 @@ +use crate::error::Error::{ + ApplicationNotFound, AuthenticationDelay, AuthenticationError, BoundaryError, CommandAborted, + DuplicateError, FileNotFound, IllegalCommandCode, IntegrityError, InvalidStatusWord, + LengthError, NoSuchKey, ParameterError, PermissionDenied, +}; +use crate::error::Result; use crate::iso7816_4::apdustatuswords::{APDUStatusWord, APDUStatusWord2}; -use crate::error::{Result}; use num_traits::FromPrimitive; -use crate::error::Error::{InvalidStatusWord, IllegalCommandCode, IntegrityError, NoSuchKey, LengthError, PermissionDenied, ParameterError, AuthenticationDelay, AuthenticationError, BoundaryError, CommandAborted, DuplicateError, FileNotFound, ApplicationNotFound}; use std::fmt; #[derive(Eq, PartialEq, Hash, Debug, Default)] @@ -22,7 +26,9 @@ impl From for Vec { let mut v: Vec = vec![]; match resp.body { None => {} - Some(body) => {v.extend(body);} + Some(body) => { + v.extend(body); + } } v.push(resp.sw1); v.push(resp.sw2); @@ -35,9 +41,13 @@ impl fmt::Display for APDUResponse { match &self.body { None => { write!(f, "SW1: {:#X} | SW2: 0x{:#X}", self.sw1, self.sw2) - }, + } Some(body) => { - write!(f, "SW1: {:#X} | SW2: {:#X} | Body: {:#X?}", self.sw1, self.sw2, body) + write!( + f, + "SW1: {:#X} | SW2: {:#X} | Body: {:#X?}", + self.sw1, self.sw2, body + ) } } } @@ -66,12 +76,17 @@ impl APDUResponse { 0x61 => Ok(APDUStatusWord::DataReady), 0x62 => Ok(APDUStatusWord::StorageNotChanged), 0x63 => { - if (self.sw2 & 0xF0) == 0xC0 { Ok(APDUStatusWord::CounterReached) } else { Ok(APDUStatusWord::StorageChanged) } - }, + if (self.sw2 & 0xF0) == 0xC0 { + Ok(APDUStatusWord::CounterReached) + } else { + Ok(APDUStatusWord::StorageChanged) + } + } 0x64 => Ok(APDUStatusWord::ExecutionErrorWithoutChange), 0x65 => Ok(APDUStatusWord::ExecutionErrorWithChange), 0x6C => Ok(APDUStatusWord::InvalidLe), - _ => FromPrimitive::from_u16(((self.sw1 as u16) << 8) | self.sw2 as u16).ok_or(InvalidStatusWord) + _ => FromPrimitive::from_u16(((self.sw1 as u16) << 8) | self.sw2 as u16) + .ok_or(InvalidStatusWord), } } @@ -90,24 +105,26 @@ impl APDUResponse { pub fn check(&self) -> Result<()> { if self.sw1 == 0x91 { return match FromPrimitive::from_u8(self.sw2) { - Some(APDUStatusWord2::OperationOk) => { Ok(()) } - Some(APDUStatusWord2::NoChanges) => { Ok(()) } - Some(APDUStatusWord2::IllegalCommandCode) => {Err(IllegalCommandCode)} - Some(APDUStatusWord2::IntegrityError) => {Err(IntegrityError)} - Some(APDUStatusWord2::NoSuchKey) => {Err(NoSuchKey)} - Some(APDUStatusWord2::LengthError) => {Err(LengthError)} - Some(APDUStatusWord2::PermissionDenied) => {Err(PermissionDenied)} - Some(APDUStatusWord2::ParameterError) => {Err(ParameterError)} - Some(APDUStatusWord2::AuthenticationDelay) => {Err(AuthenticationDelay)} - Some(APDUStatusWord2::AuthenticationError) => {Err(AuthenticationError)} - Some(APDUStatusWord2::AdditionalFrame) => {Ok(())} - Some(APDUStatusWord2::BoundaryError) => {Err(BoundaryError)} - Some(APDUStatusWord2::CommandAborted) => {Err(CommandAborted)} - Some(APDUStatusWord2::DuplicateError) => {Err(DuplicateError)} - Some(APDUStatusWord2::FileNotFound) => {Err(FileNotFound)} - Some(APDUStatusWord2::ApplicationNotFound) => {Err(ApplicationNotFound)} - None => { Err(InvalidStatusWord)} - } - } else { Err(InvalidStatusWord) } + Some(APDUStatusWord2::OperationOk) => Ok(()), + Some(APDUStatusWord2::NoChanges) => Ok(()), + Some(APDUStatusWord2::IllegalCommandCode) => Err(IllegalCommandCode), + Some(APDUStatusWord2::IntegrityError) => Err(IntegrityError), + Some(APDUStatusWord2::NoSuchKey) => Err(NoSuchKey), + Some(APDUStatusWord2::LengthError) => Err(LengthError), + Some(APDUStatusWord2::PermissionDenied) => Err(PermissionDenied), + Some(APDUStatusWord2::ParameterError) => Err(ParameterError), + Some(APDUStatusWord2::AuthenticationDelay) => Err(AuthenticationDelay), + Some(APDUStatusWord2::AuthenticationError) => Err(AuthenticationError), + Some(APDUStatusWord2::AdditionalFrame) => Ok(()), + Some(APDUStatusWord2::BoundaryError) => Err(BoundaryError), + Some(APDUStatusWord2::CommandAborted) => Err(CommandAborted), + Some(APDUStatusWord2::DuplicateError) => Err(DuplicateError), + Some(APDUStatusWord2::FileNotFound) => Err(FileNotFound), + Some(APDUStatusWord2::ApplicationNotFound) => Err(ApplicationNotFound), + None => Err(InvalidStatusWord), + }; + } else { + Err(InvalidStatusWord) + } } -} \ No newline at end of file +} diff --git a/src/iso7816_4/apdustatuswords.rs b/src/iso7816_4/apdustatuswords.rs index 8442134..a32d4c4 100644 --- a/src/iso7816_4/apdustatuswords.rs +++ b/src/iso7816_4/apdustatuswords.rs @@ -108,19 +108,15 @@ pub enum APDUStatusWord { /// Parameter P1/P2 falsch WrongParameters2 = 0x6B00, - /// Falsche Lnge Le; xx gibt die korrekte Lnge an Statuswort zur Steuerung des T=0-Protokolls InvalidLe = 0x6C00, - /// Das Kommando (INS) wird nicht untersttzt InstructionNotSupported = 0x6D00, - /// Die Kommandoklasse (CLA) wird nicht untersttzt ClassNotSupported = 0x6E00, - /// Kommando wurde mit unbekanntem Fehler abgebrochen UnknownError = 0x6F00, @@ -129,7 +125,6 @@ pub enum APDUStatusWord { /// OK OK = 0x9100, - } #[derive(FromPrimitive)] @@ -151,4 +146,4 @@ pub enum APDUStatusWord2 { DuplicateError = 0xDE, FileNotFound = 0xF0, ApplicationNotFound = 0xA0, -} \ No newline at end of file +} diff --git a/src/iso7816_4/mod.rs b/src/iso7816_4/mod.rs index 371ce5c..296a599 100644 --- a/src/iso7816_4/mod.rs +++ b/src/iso7816_4/mod.rs @@ -1,3 +1,3 @@ pub mod apducommand; pub mod apduresponse; -pub mod apdustatuswords; \ No newline at end of file +pub mod apdustatuswords; diff --git a/src/lib.rs b/src/lib.rs index 1c4671c..417c505 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,27 +1,27 @@ -use crate::iso7816_4::apduresponse::APDUResponse; use crate::iso7816_4::apducommand::APDUCommand; +use crate::iso7816_4::apduresponse::APDUResponse; use error::Result; pub mod crypto; -pub mod iso7816_4; pub mod desfire; pub mod error; +pub mod iso7816_4; pub trait Card { -/// -/// Connect to Smartcard -/// -fn connect(&mut self) -> Result<()>; + /// + /// Connect to Smartcard + /// + fn connect(&mut self) -> Result<()>; -/// -/// Disconnect from Smartcard -/// -fn disconnect(&mut self) -> Result<()>; + /// + /// Disconnect from Smartcard + /// + fn disconnect(&mut self) -> Result<()>; -/// -/// Transmit APDU Command to Smartcard -/// -/// Application Protocol Data Unit Command - ISO 7816 -/// Application Protocol Data Unit Response - ISO 7816 -fn transmit(&self, apdu_cmd: APDUCommand) -> Result; + /// + /// Transmit APDU Command to Smartcard + /// + /// Application Protocol Data Unit Command - ISO 7816 + /// Application Protocol Data Unit Response - ISO 7816 + fn transmit(&self, apdu_cmd: APDUCommand) -> Result; } diff --git a/tests/lib.rs b/tests/lib.rs index b62bb10..31e1bb2 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -4,4 +4,4 @@ mod tests { fn it_works() { assert_eq!(2 + 2, 4); } -} \ No newline at end of file +}