Extract ChangeRefAction enum
This commit is contained in:
+21
-8
@@ -18,6 +18,13 @@ use crate::mgm::{MgmKey, DES_LEN_3DES};
|
|||||||
|
|
||||||
const CB_PIN_MAX: usize = 8;
|
const CB_PIN_MAX: usize = 8;
|
||||||
|
|
||||||
|
#[cfg(feature = "untested")]
|
||||||
|
pub(crate) enum ChangeRefAction {
|
||||||
|
ChangePin,
|
||||||
|
ChangePuk,
|
||||||
|
UnblockPin,
|
||||||
|
}
|
||||||
|
|
||||||
/// Exclusive transaction with the YubiKey's PC/SC card.
|
/// Exclusive transaction with the YubiKey's PC/SC card.
|
||||||
pub(crate) struct Transaction<'tx> {
|
pub(crate) struct Transaction<'tx> {
|
||||||
inner: pcsc::Transaction<'tx>,
|
inner: pcsc::Transaction<'tx>,
|
||||||
@@ -179,18 +186,24 @@ impl<'tx> Transaction<'tx> {
|
|||||||
|
|
||||||
/// Change the PIN.
|
/// Change the PIN.
|
||||||
#[cfg(feature = "untested")]
|
#[cfg(feature = "untested")]
|
||||||
pub fn change_pin(&self, action: i32, current_pin: &[u8], new_pin: &[u8]) -> Result<(), Error> {
|
pub fn change_ref(
|
||||||
let mut templ = [0, Ins::ChangeReference.code(), 0, 0x80];
|
&self,
|
||||||
|
action: ChangeRefAction,
|
||||||
|
current_pin: &[u8],
|
||||||
|
new_pin: &[u8],
|
||||||
|
) -> Result<(), Error> {
|
||||||
if current_pin.len() > CB_PIN_MAX || new_pin.len() > CB_PIN_MAX {
|
if current_pin.len() > CB_PIN_MAX || new_pin.len() > CB_PIN_MAX {
|
||||||
return Err(Error::SizeError);
|
return Err(Error::SizeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
if action == CHREF_ACT_UNBLOCK_PIN {
|
const PIN: u8 = 0x80;
|
||||||
templ[1] = Ins::ResetRetry.code();
|
const PUK: u8 = 0x81;
|
||||||
} else if action == CHREF_ACT_CHANGE_PUK {
|
|
||||||
templ[3] = 0x81;
|
let templ = match action {
|
||||||
}
|
ChangeRefAction::ChangePin => [0, Ins::ChangeReference.code(), 0, PIN],
|
||||||
|
ChangeRefAction::ChangePuk => [0, Ins::ChangeReference.code(), 0, PUK],
|
||||||
|
ChangeRefAction::UnblockPin => [0, Ins::ResetRetry.code(), 0, PIN],
|
||||||
|
};
|
||||||
|
|
||||||
let mut indata = Zeroizing::new([0xff; CB_PIN_MAX * 2]);
|
let mut indata = Zeroizing::new([0xff; CB_PIN_MAX * 2]);
|
||||||
indata[0..current_pin.len()].copy_from_slice(current_pin);
|
indata[0..current_pin.len()].copy_from_slice(current_pin);
|
||||||
|
|||||||
+6
-13
@@ -50,8 +50,8 @@ use std::{
|
|||||||
|
|
||||||
#[cfg(feature = "untested")]
|
#[cfg(feature = "untested")]
|
||||||
use crate::{
|
use crate::{
|
||||||
apdu::StatusWords, metadata, Buffer, ObjectId, CB_BUF_MAX, CB_OBJ_MAX, MGMT_AID, TAG_ADMIN,
|
apdu::StatusWords, metadata, transaction::ChangeRefAction, Buffer, ObjectId, CB_BUF_MAX,
|
||||||
TAG_ADMIN_FLAGS_1, TAG_ADMIN_TIMESTAMP,
|
CB_OBJ_MAX, MGMT_AID, TAG_ADMIN, TAG_ADMIN_FLAGS_1, TAG_ADMIN_TIMESTAMP,
|
||||||
};
|
};
|
||||||
use getrandom::getrandom;
|
use getrandom::getrandom;
|
||||||
#[cfg(feature = "untested")]
|
#[cfg(feature = "untested")]
|
||||||
@@ -68,13 +68,6 @@ pub(crate) const ALGO_3DES: u8 = 0x03;
|
|||||||
/// Card management key
|
/// Card management key
|
||||||
pub(crate) const KEY_CARDMGM: u8 = 0x9b;
|
pub(crate) const KEY_CARDMGM: u8 = 0x9b;
|
||||||
|
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
pub(crate) const CHREF_ACT_CHANGE_PIN: i32 = 0;
|
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
pub(crate) const CHREF_ACT_UNBLOCK_PIN: i32 = 1;
|
|
||||||
#[cfg(feature = "untested")]
|
|
||||||
pub(crate) const CHREF_ACT_CHANGE_PUK: i32 = 2;
|
|
||||||
|
|
||||||
const TAG_DYN_AUTH: u8 = 0x7c;
|
const TAG_DYN_AUTH: u8 = 0x7c;
|
||||||
|
|
||||||
/// Cached YubiKey PIN
|
/// Cached YubiKey PIN
|
||||||
@@ -401,7 +394,7 @@ impl YubiKey {
|
|||||||
pub fn change_pin(&mut self, current_pin: &[u8], new_pin: &[u8]) -> Result<(), Error> {
|
pub fn change_pin(&mut self, current_pin: &[u8], new_pin: &[u8]) -> Result<(), Error> {
|
||||||
{
|
{
|
||||||
let txn = self.begin_transaction()?;
|
let txn = self.begin_transaction()?;
|
||||||
txn.change_pin(CHREF_ACT_CHANGE_PIN, current_pin, new_pin)?;
|
txn.change_ref(ChangeRefAction::ChangePin, current_pin, new_pin)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !new_pin.is_empty() {
|
if !new_pin.is_empty() {
|
||||||
@@ -458,7 +451,7 @@ impl YubiKey {
|
|||||||
#[cfg(feature = "untested")]
|
#[cfg(feature = "untested")]
|
||||||
pub fn change_puk(&mut self, current_puk: &[u8], new_puk: &[u8]) -> Result<(), Error> {
|
pub fn change_puk(&mut self, current_puk: &[u8], new_puk: &[u8]) -> Result<(), Error> {
|
||||||
let txn = self.begin_transaction()?;
|
let txn = self.begin_transaction()?;
|
||||||
txn.change_pin(CHREF_ACT_CHANGE_PUK, current_puk, new_puk)
|
txn.change_ref(ChangeRefAction::ChangePuk, current_puk, new_puk)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Block PUK: permanently prevent the PIN from becoming unblocked
|
/// Block PUK: permanently prevent the PIN from becoming unblocked
|
||||||
@@ -472,7 +465,7 @@ impl YubiKey {
|
|||||||
|
|
||||||
while tries_remaining != 0 {
|
while tries_remaining != 0 {
|
||||||
// 2 -> change puk
|
// 2 -> change puk
|
||||||
let res = txn.change_pin(CHREF_ACT_CHANGE_PUK, &puk, &puk);
|
let res = txn.change_ref(ChangeRefAction::ChangePuk, &puk, &puk);
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
Ok(()) => puk[0] += 1,
|
Ok(()) => puk[0] += 1,
|
||||||
@@ -533,7 +526,7 @@ impl YubiKey {
|
|||||||
#[cfg(feature = "untested")]
|
#[cfg(feature = "untested")]
|
||||||
pub fn unblock_pin(&mut self, puk: &[u8], new_pin: &[u8]) -> Result<(), Error> {
|
pub fn unblock_pin(&mut self, puk: &[u8], new_pin: &[u8]) -> Result<(), Error> {
|
||||||
let txn = self.begin_transaction()?;
|
let txn = self.begin_transaction()?;
|
||||||
txn.change_pin(CHREF_ACT_UNBLOCK_PIN, puk, new_pin)
|
txn.change_ref(ChangeRefAction::UnblockPin, puk, new_pin)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fetch an object from the YubiKey
|
/// Fetch an object from the YubiKey
|
||||||
|
|||||||
Reference in New Issue
Block a user