mirror of
https://gitlab.com/fabinfra/fabaccess/nfc_rs.git
synced 2025-03-12 06:41:46 +01:00
Merge branch 'fix/clippy-warnings' into 'main'
chore: fix warning as reported by `cargo cippy` See merge request fabinfra/fabaccess/nfc_rs!6
This commit is contained in:
commit
2d550a5bc3
@ -13,19 +13,19 @@ impl Cipher for AES {
|
|||||||
const KEY_SIZE: usize = 16;
|
const KEY_SIZE: usize = 16;
|
||||||
|
|
||||||
fn encrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> {
|
fn encrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> {
|
||||||
let cipher = Aes128Cbc::new_from_slices(&key, &iv)?;
|
let cipher = Aes128Cbc::new_from_slices(key, iv)?;
|
||||||
|
|
||||||
return Ok(cipher.encrypt_vec(data));
|
Ok(cipher.encrypt_vec(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> {
|
fn decrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> {
|
||||||
let cipher = Aes128Cbc::new_from_slices(&key, &iv)?;
|
let cipher = Aes128Cbc::new_from_slices(key, iv)?;
|
||||||
|
|
||||||
let result = cipher.decrypt_vec(data);
|
let result = cipher.decrypt_vec(data);
|
||||||
return match result {
|
match result {
|
||||||
Ok(data) => Ok(data),
|
Ok(data) => Ok(data),
|
||||||
Err(err) => Err(Error::BlockModeError(err)),
|
Err(err) => Err(Error::BlockModeError(err)),
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,19 +14,19 @@ impl Cipher for Tdes {
|
|||||||
const KEY_SIZE: usize = 16;
|
const KEY_SIZE: usize = 16;
|
||||||
|
|
||||||
fn encrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> {
|
fn encrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> {
|
||||||
let cipher = TDesEde2Cbc::new_from_slices(&key, &iv)?;
|
let cipher = TDesEde2Cbc::new_from_slices(key, iv)?;
|
||||||
|
|
||||||
return Ok(cipher.encrypt_vec(data));
|
Ok(cipher.encrypt_vec(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> {
|
fn decrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> {
|
||||||
let cipher = TDesEde2Cbc::new_from_slices(&key, &iv)?;
|
let cipher = TDesEde2Cbc::new_from_slices(key, iv)?;
|
||||||
|
|
||||||
let result = cipher.decrypt_vec(data);
|
let result = cipher.decrypt_vec(data);
|
||||||
return match result {
|
match result {
|
||||||
Ok(data) => Ok(data),
|
Ok(data) => Ok(data),
|
||||||
Err(err) => Err(Error::BlockModeError(err)),
|
Err(err) => Err(Error::BlockModeError(err)),
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,19 +14,19 @@ impl Cipher for Tdes2k {
|
|||||||
const KEY_SIZE: usize = 16;
|
const KEY_SIZE: usize = 16;
|
||||||
|
|
||||||
fn encrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> {
|
fn encrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> {
|
||||||
let cipher = TDesEde2Cbc::new_from_slices(&key, &iv)?;
|
let cipher = TDesEde2Cbc::new_from_slices(key, iv)?;
|
||||||
|
|
||||||
return Ok(cipher.encrypt_vec(data));
|
Ok(cipher.encrypt_vec(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> {
|
fn decrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> {
|
||||||
let cipher = TDesEde2Cbc::new_from_slices(&key, &iv)?;
|
let cipher = TDesEde2Cbc::new_from_slices(key, iv)?;
|
||||||
|
|
||||||
let result = cipher.decrypt_vec(data);
|
let result = cipher.decrypt_vec(data);
|
||||||
return match result {
|
match result {
|
||||||
Ok(data) => Ok(data),
|
Ok(data) => Ok(data),
|
||||||
Err(err) => Err(Error::BlockModeError(err)),
|
Err(err) => Err(Error::BlockModeError(err)),
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,19 +14,19 @@ impl Cipher for Tdes3k {
|
|||||||
const KEY_SIZE: usize = 24;
|
const KEY_SIZE: usize = 24;
|
||||||
|
|
||||||
fn encrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> {
|
fn encrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> {
|
||||||
let cipher = TDesEde3Cbc::new_from_slices(&key, &iv)?;
|
let cipher = TDesEde3Cbc::new_from_slices(key, iv)?;
|
||||||
|
|
||||||
return Ok(cipher.encrypt_vec(data));
|
Ok(cipher.encrypt_vec(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> {
|
fn decrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> {
|
||||||
let cipher = TDesEde3Cbc::new_from_slices(&key, &iv)?;
|
let cipher = TDesEde3Cbc::new_from_slices(key, iv)?;
|
||||||
|
|
||||||
let result = cipher.decrypt_vec(data);
|
let result = cipher.decrypt_vec(data);
|
||||||
return match result {
|
match result {
|
||||||
Ok(data) => Ok(data),
|
Ok(data) => Ok(data),
|
||||||
Err(err) => Err(Error::BlockModeError(err)),
|
Err(err) => Err(Error::BlockModeError(err)),
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,11 +74,7 @@ pub fn get_key_size(cipher: CipherType) -> usize {
|
|||||||
|
|
||||||
/// Check Key Slice
|
/// Check Key Slice
|
||||||
pub fn check_key(key: &[u8], cipher: CipherType) -> bool {
|
pub fn check_key(key: &[u8], cipher: CipherType) -> bool {
|
||||||
if key.len() != get_key_size(cipher) {
|
key.len() == get_key_size(cipher)
|
||||||
false
|
|
||||||
} else {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set Key Version for DES/TDES Keys
|
/// Set Key Version for DES/TDES Keys
|
||||||
|
@ -20,9 +20,9 @@ pub fn expand_to_blocksize(data: &mut [u8], blocksize: usize) -> Result<Vec<u8>>
|
|||||||
let diff = data.len() % blocksize;
|
let diff = data.len() % blocksize;
|
||||||
|
|
||||||
if diff == 0 {
|
if diff == 0 {
|
||||||
return Ok(data.to_vec());
|
Ok(data.to_vec())
|
||||||
} else {
|
} else {
|
||||||
let mut buf = vec![0 as u8; data.len() + blocksize - diff];
|
let mut buf = vec![0_u8; data.len() + blocksize - diff];
|
||||||
buf[..data.len()].copy_from_slice(data);
|
buf[..data.len()].copy_from_slice(data);
|
||||||
Ok(buf)
|
Ok(buf)
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ impl Desfire {
|
|||||||
let rnd_b_enc = rnd_b_response_body.as_slice();
|
let rnd_b_enc = rnd_b_response_body.as_slice();
|
||||||
// println!("RND_B_ENC: {:x?}", rnd_b_enc);
|
// println!("RND_B_ENC: {:x?}", rnd_b_enc);
|
||||||
|
|
||||||
let rnd_b = Tdes::decrypt(rnd_b_enc, key, vec![0 as u8; 8].as_slice()).unwrap();
|
let rnd_b = Tdes::decrypt(rnd_b_enc, key, vec![0_u8; 8].as_slice()).unwrap();
|
||||||
// println!("RND_B: {:x?}", rnd_b);
|
// println!("RND_B: {:x?}", rnd_b);
|
||||||
|
|
||||||
let mut rnd_b_rl = rnd_b.clone();
|
let mut rnd_b_rl = rnd_b.clone();
|
||||||
@ -153,7 +153,7 @@ impl Desfire {
|
|||||||
self.session_key = Some(generate_session_key_des(&rnd_a, rnd_b.as_slice()).unwrap());
|
self.session_key = Some(generate_session_key_des(&rnd_a, rnd_b.as_slice()).unwrap());
|
||||||
// println!("SESSION_KEY: {:x?}", self.session_key.as_ref().unwrap());
|
// println!("SESSION_KEY: {:x?}", self.session_key.as_ref().unwrap());
|
||||||
|
|
||||||
self.cbc_iv = Some(vec![0 as u8; 8]);
|
self.cbc_iv = Some(vec![0_u8; 8]);
|
||||||
// println!("CBC_IV: {:x?}", self.cbc_iv.as_ref().unwrap());
|
// println!("CBC_IV: {:x?}", self.cbc_iv.as_ref().unwrap());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -184,7 +184,7 @@ impl Desfire {
|
|||||||
) -> Result<(APDUCommand, Vec<u8>, Vec<u8>)> {
|
) -> Result<(APDUCommand, Vec<u8>, Vec<u8>)> {
|
||||||
// println!("RND_B_ENC: {:x?}", challenge);
|
// println!("RND_B_ENC: {:x?}", challenge);
|
||||||
|
|
||||||
let rnd_b = AES::decrypt(challenge, key, vec![0 as u8; 16].as_slice()).unwrap();
|
let rnd_b = AES::decrypt(challenge, key, vec![0_u8; 16].as_slice()).unwrap();
|
||||||
// println!("RND_B: {:x?}", rnd_b);
|
// println!("RND_B: {:x?}", rnd_b);
|
||||||
|
|
||||||
// auth_iv = rnd_b.clone();
|
// auth_iv = rnd_b.clone();
|
||||||
@ -192,7 +192,7 @@ impl Desfire {
|
|||||||
rnd_b_rl.rotate_left(1);
|
rnd_b_rl.rotate_left(1);
|
||||||
// println!("RND_B_RL: {:x?}", rnd_b_rl);
|
// println!("RND_B_RL: {:x?}", rnd_b_rl);
|
||||||
|
|
||||||
let rnd_ab = [&rnd_a, rnd_b_rl.as_slice()].concat();
|
let rnd_ab = [rnd_a, rnd_b_rl.as_slice()].concat();
|
||||||
// println!("RND_AB: {:x?}", rnd_ab);
|
// println!("RND_AB: {:x?}", rnd_ab);
|
||||||
|
|
||||||
let rnd_ab_enc = AES::encrypt(rnd_ab.as_slice(), key, challenge).unwrap();
|
let rnd_ab_enc = AES::encrypt(rnd_ab.as_slice(), key, challenge).unwrap();
|
||||||
@ -233,8 +233,8 @@ impl Desfire {
|
|||||||
self.session_key = Some(generate_session_key_aes(expected_response, challenge).unwrap());
|
self.session_key = Some(generate_session_key_aes(expected_response, challenge).unwrap());
|
||||||
// println!("SESSION_KEY: {:x?}", self.session_key.as_ref().unwrap());
|
// println!("SESSION_KEY: {:x?}", self.session_key.as_ref().unwrap());
|
||||||
|
|
||||||
self.cbc_iv = Some(vec![0 as u8; 16]); //FIXME: this should be a random value
|
self.cbc_iv = Some(vec![0_u8; 16]); //FIXME: this should be a random value
|
||||||
// println!("CBC_IV: {:x?}", self.cbc_iv.as_ref().unwrap());
|
// println!("CBC_IV: {:x?}", self.cbc_iv.as_ref().unwrap());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -619,7 +619,7 @@ impl Desfire {
|
|||||||
ret = response.check();
|
ret = response.check();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_data_chunk_cmd(
|
pub fn read_data_chunk_cmd(
|
||||||
@ -648,7 +648,7 @@ impl Desfire {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
return Ok(cmd_read_data_chunk);
|
Ok(cmd_read_data_chunk)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read data from a file
|
/// Read data from a file
|
||||||
@ -685,13 +685,13 @@ impl Desfire {
|
|||||||
let response = self.card.as_ref().unwrap().transmit(cmd_read_data).unwrap();
|
let response = self.card.as_ref().unwrap().transmit(cmd_read_data).unwrap();
|
||||||
// println!("RESPONSE: {}", response);
|
// println!("RESPONSE: {}", response);
|
||||||
|
|
||||||
response.check().or_else(|e| return Err(e))?;
|
response.check()?;
|
||||||
// // println!("RESPONSE_DATA: {:x?}, WITHOUT_CMAC: {:x?}", response.body.as_ref().unwrap(), response.body.as_ref().unwrap()[..bytes_toread].to_vec());
|
// // println!("RESPONSE_DATA: {:x?}, WITHOUT_CMAC: {:x?}", response.body.as_ref().unwrap(), response.body.as_ref().unwrap()[..bytes_toread].to_vec());
|
||||||
|
|
||||||
read_buffer.append(&mut response.body.unwrap()[..bytes_toread].to_vec());
|
read_buffer.append(&mut response.body.unwrap()[..bytes_toread].to_vec());
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(read_buffer);
|
Ok(read_buffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -726,7 +726,7 @@ pub fn generate_keysetting1(
|
|||||||
file_directory_access: FileDirectoryAccess,
|
file_directory_access: FileDirectoryAccess,
|
||||||
change_master_key: ChangeMasterKey,
|
change_master_key: ChangeMasterKey,
|
||||||
) -> Result<u8> {
|
) -> Result<u8> {
|
||||||
return match FromPrimitive::from_u8(change_key) {
|
match FromPrimitive::from_u8(change_key) {
|
||||||
Some(ChangeApplicationKey::MASTERKEY)
|
Some(ChangeApplicationKey::MASTERKEY)
|
||||||
| Some(ChangeApplicationKey::SAMEKEY)
|
| Some(ChangeApplicationKey::SAMEKEY)
|
||||||
| Some(ChangeApplicationKey::ALLKEYS) => Ok((change_key << 4)
|
| Some(ChangeApplicationKey::ALLKEYS) => Ok((change_key << 4)
|
||||||
@ -735,7 +735,7 @@ pub fn generate_keysetting1(
|
|||||||
| file_directory_access as u8
|
| file_directory_access as u8
|
||||||
| change_master_key as u8),
|
| change_master_key as u8),
|
||||||
None => {
|
None => {
|
||||||
if change_key < 0x01 || change_key >= 0x08 {
|
if !(0x01..0x08).contains(&change_key) {
|
||||||
Err(InvalidKeyID)
|
Err(InvalidKeyID)
|
||||||
} else {
|
} else {
|
||||||
Ok((change_key << 4)
|
Ok((change_key << 4)
|
||||||
@ -745,7 +745,7 @@ pub fn generate_keysetting1(
|
|||||||
| change_master_key as u8)
|
| change_master_key as u8)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate KeySetting2 for Application Creation
|
/// Generate KeySetting2 for Application Creation
|
||||||
@ -759,11 +759,11 @@ pub fn generate_keysetting2(
|
|||||||
file_identifier: FileIdentifiers,
|
file_identifier: FileIdentifiers,
|
||||||
num_keys: u8,
|
num_keys: u8,
|
||||||
) -> Result<u8> {
|
) -> Result<u8> {
|
||||||
return if num_keys < 0x01 || num_keys >= 0x0D {
|
if !(0x01..0x0D).contains(&num_keys) {
|
||||||
Err(NumKeys)
|
Err(NumKeys)
|
||||||
} else {
|
} else {
|
||||||
Ok(crypto_operations as u8 | file_identifier as u8 | num_keys)
|
Ok(crypto_operations as u8 | file_identifier as u8 | num_keys)
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate FileAccess Rights for File Settings
|
/// Generate FileAccess Rights for File Settings
|
||||||
@ -784,14 +784,14 @@ pub fn generate_file_access_rights(
|
|||||||
read_write: u8,
|
read_write: u8,
|
||||||
configure: u8,
|
configure: u8,
|
||||||
) -> Result<u16> {
|
) -> Result<u16> {
|
||||||
return if read > 0x0F || write >= 0x0F || read_write >= 0x0F || configure >= 0x0F {
|
if read > 0x0F || write >= 0x0F || read_write >= 0x0F || configure >= 0x0F {
|
||||||
Err(InvalidKeyID)
|
Err(InvalidKeyID)
|
||||||
} else {
|
} else {
|
||||||
Ok((((read as u16) << 12)
|
Ok((((read as u16) << 12)
|
||||||
| ((write as u16) << 8)
|
| ((write as u16) << 8)
|
||||||
| ((read_write as u16) << 4)
|
| ((read_write as u16) << 4)
|
||||||
| configure as u16) as u16)
|
| configure as u16) as u16)
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -876,12 +876,12 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn generate_sessionkey_des() {
|
fn generate_sessionkey_des() {
|
||||||
let rndA = hex!("a541a9dc9138df07");
|
let rnd_a = hex!("a541a9dc9138df07");
|
||||||
let rndB = hex!("cbe55aa893b2da25");
|
let rnd_b = hex!("cbe55aa893b2da25");
|
||||||
|
|
||||||
let expected_sessionkey = hex!("a541a9dccbe55aa8a541a9dccbe55aa8");
|
let expected_sessionkey = hex!("a541a9dccbe55aa8a541a9dccbe55aa8");
|
||||||
|
|
||||||
let sessionkey = generate_session_key_des(&rndA, &rndB).unwrap();
|
let sessionkey = generate_session_key_des(&rnd_a, &rnd_b).unwrap();
|
||||||
|
|
||||||
// println!("expected sessionkey: {:X?}", expected_sessionkey);
|
// println!("expected sessionkey: {:X?}", expected_sessionkey);
|
||||||
// println!("actual sessionkey: {:X?}", sessionkey.as_slice());
|
// println!("actual sessionkey: {:X?}", sessionkey.as_slice());
|
||||||
@ -891,12 +891,12 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn generate_sessionkey_aes() {
|
fn generate_sessionkey_aes() {
|
||||||
let rndA = hex!("bc14dfde20074617e45a8822f06fdd91");
|
let rnd_a = hex!("bc14dfde20074617e45a8822f06fdd91");
|
||||||
let rndB = hex!("482ddc54426e6dee560413b8d95471f5");
|
let rnd_b = hex!("482ddc54426e6dee560413b8d95471f5");
|
||||||
|
|
||||||
let expected_sessionkey = hex!("bc14dfde482ddc54f06fdd91d95471f5");
|
let expected_sessionkey = hex!("bc14dfde482ddc54f06fdd91d95471f5");
|
||||||
|
|
||||||
let sessionkey = generate_session_key_aes(&rndA, &rndB).unwrap();
|
let sessionkey = generate_session_key_aes(&rnd_a, &rnd_b).unwrap();
|
||||||
|
|
||||||
// println!("expected sessionkey: {:X?}", expected_sessionkey);
|
// println!("expected sessionkey: {:X?}", expected_sessionkey);
|
||||||
// println!("actual sessionkey: {:X?}", sessionkey.as_slice());
|
// println!("actual sessionkey: {:X?}", sessionkey.as_slice());
|
||||||
@ -1092,7 +1092,7 @@ mod tests {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
let rndA = hex!("5f7d1dd12d979173");
|
let rnd_a = hex!("5f7d1dd12d979173");
|
||||||
let key = CipherKey::new_empty(CipherType::TDES).unwrap();
|
let key = CipherKey::new_empty(CipherType::TDES).unwrap();
|
||||||
// println!("{:x?}", key.key.deref());
|
// println!("{:x?}", key.key.deref());
|
||||||
|
|
||||||
@ -1103,7 +1103,7 @@ mod tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
desfire
|
desfire
|
||||||
.authenticate_iso_des(0x00, key.key.as_ref(), Some(rndA))
|
.authenticate_iso_des(0x00, key.key.as_ref(), Some(rnd_a))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let sessionkey_expected = hex!("5f7d1dd1f449db5c5f7d1dd1f449db5c");
|
let sessionkey_expected = hex!("5f7d1dd1f449db5c5f7d1dd1f449db5c");
|
||||||
@ -1207,7 +1207,7 @@ mod tests {
|
|||||||
body: Some(hex!("8fdc476f6bac44fe9150e285abd68d48").to_vec())
|
body: Some(hex!("8fdc476f6bac44fe9150e285abd68d48").to_vec())
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let rndA = hex!("2176770e7a6eb4bef00d5e4b201d1e57");
|
let rnd_a = hex!("2176770e7a6eb4bef00d5e4b201d1e57");
|
||||||
let key = CipherKey::new_empty(CipherType::AES).unwrap();
|
let key = CipherKey::new_empty(CipherType::AES).unwrap();
|
||||||
// println!("{:x?}", key.key.deref());
|
// println!("{:x?}", key.key.deref());
|
||||||
|
|
||||||
@ -1218,7 +1218,7 @@ mod tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
desfire
|
desfire
|
||||||
.authenticate_iso_aes(0x00, key.key.as_ref(), Some(rndA))
|
.authenticate_iso_aes(0x00, key.key.as_ref(), Some(rnd_a))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let sessionkey_expected = hex!("2176770e11c512ca201d1e57fde6e15a");
|
let sessionkey_expected = hex!("2176770e11c512ca201d1e57fde6e15a");
|
||||||
|
@ -116,5 +116,6 @@ pub enum FileTypes {
|
|||||||
|
|
||||||
mod apduinstructions;
|
mod apduinstructions;
|
||||||
mod apdustatuscodes;
|
mod apdustatuscodes;
|
||||||
|
#[allow(clippy::module_inception)]
|
||||||
pub mod desfire;
|
pub mod desfire;
|
||||||
pub use crate::desfire::desfire::Desfire;
|
pub use crate::desfire::desfire::Desfire;
|
||||||
|
@ -113,12 +113,7 @@ impl TryFrom<APDUCommand> for Vec<u8> {
|
|||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn try_from(cmd: APDUCommand) -> Result<Self> {
|
fn try_from(cmd: APDUCommand) -> Result<Self> {
|
||||||
let mut v: Vec<u8> = vec![];
|
let mut v = vec![cmd.cla, cmd.ins, cmd.p1, cmd.p2];
|
||||||
//build header
|
|
||||||
v.push(cmd.cla);
|
|
||||||
v.push(cmd.ins);
|
|
||||||
v.push(cmd.p1);
|
|
||||||
v.push(cmd.p2);
|
|
||||||
|
|
||||||
//build body according to case
|
//build body according to case
|
||||||
match cmd.case {
|
match cmd.case {
|
||||||
|
@ -56,7 +56,8 @@ impl APDUResponse {
|
|||||||
pub fn new(raw: &[u8]) -> Self {
|
pub fn new(raw: &[u8]) -> Self {
|
||||||
if raw.len() < 2 {
|
if raw.len() < 2 {
|
||||||
panic!("APDU response must be at least 2 bytes long");
|
panic!("APDU response must be at least 2 bytes long");
|
||||||
} else if raw.len() == 2 {
|
}
|
||||||
|
if raw.len() == 2 {
|
||||||
APDUResponse {
|
APDUResponse {
|
||||||
body: None,
|
body: None,
|
||||||
sw1: raw[0],
|
sw1: raw[0],
|
||||||
@ -104,7 +105,7 @@ impl APDUResponse {
|
|||||||
|
|
||||||
pub fn check(&self) -> Result<()> {
|
pub fn check(&self) -> Result<()> {
|
||||||
if self.sw1 == 0x91 {
|
if self.sw1 == 0x91 {
|
||||||
return match FromPrimitive::from_u8(self.sw2) {
|
match FromPrimitive::from_u8(self.sw2) {
|
||||||
Some(APDUStatusWord2::OperationOk) => Ok(()),
|
Some(APDUStatusWord2::OperationOk) => Ok(()),
|
||||||
Some(APDUStatusWord2::NoChanges) => Ok(()),
|
Some(APDUStatusWord2::NoChanges) => Ok(()),
|
||||||
Some(APDUStatusWord2::IllegalCommandCode) => Err(IllegalCommandCode),
|
Some(APDUStatusWord2::IllegalCommandCode) => Err(IllegalCommandCode),
|
||||||
@ -122,7 +123,7 @@ impl APDUResponse {
|
|||||||
Some(APDUStatusWord2::FileNotFound) => Err(FileNotFound),
|
Some(APDUStatusWord2::FileNotFound) => Err(FileNotFound),
|
||||||
Some(APDUStatusWord2::ApplicationNotFound) => Err(ApplicationNotFound),
|
Some(APDUStatusWord2::ApplicationNotFound) => Err(ApplicationNotFound),
|
||||||
None => Err(InvalidStatusWord),
|
None => Err(InvalidStatusWord),
|
||||||
};
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(InvalidStatusWord)
|
Err(InvalidStatusWord)
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ use num_derive::FromPrimitive;
|
|||||||
#[derive(FromPrimitive)]
|
#[derive(FromPrimitive)]
|
||||||
#[repr(u16)]
|
#[repr(u16)]
|
||||||
pub enum APDUStatusWord {
|
pub enum APDUStatusWord {
|
||||||
/// Kommando erfolgreich ausgefhrt. xx Datenbytes knnen mit dem GET RESPONSE-Kommando abgeholt werden. Statuswort zur Steuerung des T=0-Protokolls
|
/// Kommando erfolgreich ausgefhrt. xx Datenbytes knnen mit dem GET RESPONSE-Kommando abgeholt werden. Statuswort zur Steuerung des T=0-Protokolls
|
||||||
DataReady = 0x6100,
|
DataReady = 0x6100,
|
||||||
|
|
||||||
/// Die zurckgegebenen Daten knnen fehlerhaft sein.
|
/// Die zurckgegebenen Daten knnen fehlerhaft sein.
|
||||||
@ -108,7 +108,7 @@ pub enum APDUStatusWord {
|
|||||||
/// Parameter P1/P2 falsch
|
/// Parameter P1/P2 falsch
|
||||||
WrongParameters2 = 0x6B00,
|
WrongParameters2 = 0x6B00,
|
||||||
|
|
||||||
/// Falsche Lnge Le; xx gibt die korrekte Lnge an Statuswort zur Steuerung des T=0-Protokolls
|
/// Falsche Lnge Le; xx gibt die korrekte Lnge an Statuswort zur Steuerung des T=0-Protokolls
|
||||||
InvalidLe = 0x6C00,
|
InvalidLe = 0x6C00,
|
||||||
|
|
||||||
/// Das Kommando (INS) wird nicht untersttzt
|
/// Das Kommando (INS) wird nicht untersttzt
|
||||||
|
Loading…
x
Reference in New Issue
Block a user