reformated files with rustfmt

This commit is contained in:
Kai Jan Kriegel 2021-12-26 02:33:05 +01:00
parent dce2bc30a8
commit 099c78d979
21 changed files with 271 additions and 216 deletions

View File

@ -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<Aes128, NoPadding>;
@ -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() {

View File

@ -10,6 +10,6 @@ pub trait Cipher {
const BLOCK_SIZE: usize;
const KEY_SIZE: usize;
fn encrypt (data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>>;
fn encrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>>;
fn decrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>>;
}

View File

@ -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<TdesEde2, NoPadding>;
@ -22,19 +22,18 @@ impl Cipher for Tdes {
fn decrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> {
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]

View File

@ -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<TdesEde2, NoPadding>;
@ -22,19 +22,18 @@ impl Cipher for Tdes2k {
fn decrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> {
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]

View File

@ -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<TdesEde3, NoPadding>;
@ -22,19 +22,18 @@ impl Cipher for Tdes3k {
fn decrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> {
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]

View File

@ -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<CipherKey> {
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<CipherKey> {
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();

View File

@ -10,5 +10,5 @@ pub enum CipherType {
TDES3K,
/// AES
AES
AES,
}

View File

@ -1,5 +1,5 @@
pub mod cipher;
pub mod crc;
pub mod cipher_type;
pub mod cipher_key;
pub mod cipher_type;
pub mod crc;
pub mod util;

View File

@ -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)..])

View File

@ -1,6 +1,5 @@
use num_derive::FromPrimitive;
/// <summary>
/// hold the Access Rights for changing application keys (Change Key command)
/// </summary>
@ -28,13 +27,13 @@ pub enum ChangeApplicationKey {
#[derive(Clone, Copy)]
pub enum ChangeMasterKey {
/// <summary>
/// Application master key is not changeable anymore (frozen)
/// </summary>
/// Application master key is not changeable anymore (frozen)
/// </summary>
FROZEN = 0x00,
/// <summary>
/// Application master key is changeable (authentication with the current application master key necessary, default)
/// </summary>
/// Application master key is changeable (authentication with the current application master key necessary, default)
/// </summary>
CHANGEABLE = 0x01,
}
@ -44,16 +43,15 @@ pub enum ChangeMasterKey {
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum ChangeMasterKeySettings {
/// <summary>
/// configuration not changeable anymore (frozen)
/// </summary>
FROZEN = 0x00,
/// <summary>
/// configuration not changeable anymore (frozen)
/// </summary>
FROZEN = 0x00,
/// <summary>
/// this configuration is changeable if authenticated with the application master key (default)
/// </summary>
WITHMASTERKEY = 0x08
/// <summary>
/// this configuration is changeable if authenticated with the application master key (default)
/// </summary>
WITHMASTERKEY = 0x08,
}
/// <summary>
@ -62,15 +60,15 @@ WITHMASTERKEY = 0x08
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum CreateDeleteFile {
/// <summary>
/// “Create File”/ “Delete File”is permitted only with application master key authentication
/// </summary>
ONLYMASTERKEY = 0x00,
/// <summary>
/// “Create File”/ “Delete File”is permitted only with application master key authentication
/// </summary>
ONLYMASTERKEY = 0x00,
/// <summary>
/// “Create File”/ “Delete File”is permitted also without application master key authentication (default)
/// </summary>
NOKEY = 0x04,
/// <summary>
/// “Create File”/ “Delete File”is permitted also without application master key authentication (default)
/// </summary>
NOKEY = 0x04,
}
/// <summary>
@ -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 {
/// <summary>
/// Fully DES/3DES enciphered communication
/// </summary>
ENCRYPT = 0x03
ENCRYPT = 0x03,
}
/// <summary>
@ -134,7 +132,7 @@ pub enum FileDirectoryAccess {
#[derive(Clone, Copy)]
pub enum FileIdentifiers {
NOTUSED = 0x00,
USED = 0x20
USED = 0x20,
}
#[repr(u8)]
@ -163,7 +161,7 @@ pub enum FileTypes {
/// <summary>
/// Cyclic Record Files with Backup
/// </summary>
CYCLICRECORD = 0x04
CYCLICRECORD = 0x04,
}
mod apduinstructions;

View File

@ -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 files/records limits. Attempt to exceed the limits of a value file.")
@ -139,7 +148,9 @@ impl From<io::Error> for Error {
}
impl From<simple_error::SimpleError> for Error {
fn from(e: simple_error::SimpleError) -> Error { Error::Simple(e) }
fn from(e: simple_error::SimpleError) -> Error {
Error::Simple(e)
}
}
impl From<block_modes::BlockModeError> for Error {
@ -155,11 +166,15 @@ impl From<block_modes::InvalidKeyIvLength> for Error {
}
impl From<hex::FromHexError> for Error {
fn from(e: hex::FromHexError) -> Error { Error::FromHexError(e) }
fn from(e: hex::FromHexError) -> Error {
Error::FromHexError(e)
}
}
impl From<block_modes::block_padding::PadError> 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<T> = std::result::Result<T, Error>;

View File

@ -1,7 +1,7 @@
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)]
@ -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<APDUCommand> for Vec<u8> {
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,

View File

@ -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<APDUResponse> for Vec<u8> {
let mut v: Vec<u8> = 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)}
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)
}
} else { Err(InvalidStatusWord) }
}
}

View File

@ -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)]

View File

@ -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 {
/// <summary>
/// Connect to Smartcard
/// </summary>
fn connect(&mut self) -> Result<()>;
/// <summary>
/// Connect to Smartcard
/// </summary>
fn connect(&mut self) -> Result<()>;
/// <summary>
/// Disconnect from Smartcard
/// </summary>
fn disconnect(&mut self) -> Result<()>;
/// <summary>
/// Disconnect from Smartcard
/// </summary>
fn disconnect(&mut self) -> Result<()>;
/// <summary>
/// Transmit APDU Command to Smartcard
/// </summary>
/// <param name="apdu_cmd">Application Protocol Data Unit Command - ISO 7816</param>
/// <returns>Application Protocol Data Unit Response - ISO 7816</returns>
fn transmit(&self, apdu_cmd: APDUCommand) -> Result<APDUResponse>;
/// <summary>
/// Transmit APDU Command to Smartcard
/// </summary>
/// <param name="apdu_cmd">Application Protocol Data Unit Command - ISO 7816</param>
/// <returns>Application Protocol Data Unit Response - ISO 7816</returns>
fn transmit(&self, apdu_cmd: APDUCommand) -> Result<APDUResponse>;
}