Implement change_pw1(), change_pw3(), reset_retry_counter_pw1().

This commit is contained in:
Heiko Schaefer 2021-09-08 11:18:18 +02:00
parent 891b57df06
commit 52bdf4cffd
2 changed files with 84 additions and 9 deletions

View file

@ -139,18 +139,35 @@ pub(crate) fn put_cardholder_certificate(data: Vec<u8>) -> Command {
put_data(&[0x7F, 0x21], data)
}
/// Change PW1 (user pin).
/// This can be used to reset the counter and set a pin.
pub(crate) fn change_pw1(pin: Vec<u8>) -> Command {
Command::new(0x00, 0x2C, 0x02, 0x81, pin)
/// "RESET RETRY COUNTER" (PW1, user pin)
/// Reset the counter of PW1 and set a new pin.
pub(crate) fn reset_retry_counter_pw1(
resetting_code: Option<Vec<u8>>,
new_pin: Vec<u8>,
) -> Command {
if let Some(resetting_code) = resetting_code {
// Present the Resetting Code (DO D3) in the command data (P1 = 00)
// Data field: Resetting Code + New PW
let mut data = resetting_code;
data.extend(new_pin);
Command::new(0x00, 0x2C, 0x00, 0x81, data)
} else {
// Use after correct verification of PW3 (P1 = 02)
// (Usage of secure messaging is equivalent to PW3)
Command::new(0x00, 0x2C, 0x02, 0x81, new_pin)
}
}
/// Change PW3 (admin pin)
pub(crate) fn change_pw3(oldpin: Vec<u8>, newpin: Vec<u8>) -> Command {
let mut fullpin = oldpin;
fullpin.extend(newpin.iter());
/// "CHANGE REFERENCE DATA" - change PW1 (user pin)
pub(crate) fn change_pw1(data: Vec<u8>) -> Command {
Command::new(0x00, 0x24, 0x00, 0x81, data)
}
Command::new(0x00, 0x24, 0x00, 0x83, fullpin)
/// "CHANGE REFERENCE DATA" - change PW3 (admin pin)
pub(crate) fn change_pw3(data: Vec<u8>) -> Command {
Command::new(0x00, 0x24, 0x00, 0x83, data)
}
/// 7.2.10 PSO: COMPUTE DIGITAL SIGNATURE

View file

@ -359,6 +359,54 @@ impl CardApp {
apdu::send_command(&mut self.card_client, verify, false)?.try_into()
}
/// Change the value of PW1 (user password).
///
/// The current value of PW1 must be presented in `old` for authorization.
pub fn change_pw1(
&mut self,
old: &str,
new: &str,
) -> Result<Response, Error> {
let mut data = vec![];
data.extend(old.as_bytes());
data.extend(new.as_bytes());
let change = commands::change_pw1(data);
apdu::send_command(&mut self.card_client, change, false)?.try_into()
}
/// Change the value of PW3 (admin password).
///
/// The current value of PW3 must be presented in `old` for authorization.
pub fn change_pw3(
&mut self,
old: &str,
new: &str,
) -> Result<Response, Error> {
let mut data = vec![];
data.extend(old.as_bytes());
data.extend(new.as_bytes());
let change = commands::change_pw3(data);
apdu::send_command(&mut self.card_client, change, false)?.try_into()
}
/// Reset the error counter for PW1 (user password) and set a new value
/// for PW1.
///
/// For authorization, either:
/// - PW3 must have been verified previously,
/// - secure messaging must be currently used,
/// - the resetting_code must be presented.
pub fn reset_retry_counter_pw1(
&mut self,
new_pw1: Vec<u8>,
resetting_code: Option<Vec<u8>>,
) -> Result<Response, Error> {
let reset = commands::reset_retry_counter_pw1(resetting_code, new_pw1);
apdu::send_command(&mut self.card_client, reset, false)?.try_into()
}
// --- decrypt ---
/// Decrypt the ciphertext in `dm`, on the card.
@ -581,6 +629,16 @@ impl CardApp {
apdu::send_command(&mut self.card_client, cmd, false)?.try_into()
}
/// Set resetting code
/// (4.3.4 Resetting Code)
pub fn set_resetting_code(
&mut self,
resetting_code: Vec<u8>,
) -> Result<Response, Error> {
let cmd = commands::put_data(&[0xd3], resetting_code);
apdu::send_command(&mut self.card_client, cmd, false)?.try_into()
}
/// Import an existing private key to the card.
/// (This implicitly sets the algorithm info, fingerprint and timestamp)
pub fn key_import(