Merge pull request #82 from str4d/chref-enum

Extract ChangeRefAction enum
This commit is contained in:
Tony Arcieri
2019-12-16 07:11:29 -08:00
committed by GitHub
3 changed files with 31 additions and 21 deletions
Generated
+4
View File
@@ -966,7 +966,11 @@ dependencies = [
"env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gumdrop 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "gumdrop 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"subtle-encoding 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"x509-parser 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"yubikey-piv 0.0.3", "yubikey-piv 0.0.3",
] ]
+21 -8
View File
@@ -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
View File
@@ -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