From c3698dcffbc44292fc1d2de3d05e77876653e49b Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Sat, 30 Nov 2019 16:40:15 +0000 Subject: [PATCH 1/5] Key::list: Skip Certificate::new for empty buffers This matches the C code behaviour. --- src/key.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/key.rs b/src/key.rs index 8c07e15..64c1b1a 100644 --- a/src/key.rs +++ b/src/key.rs @@ -125,8 +125,10 @@ impl Key { } }; - let cert = Certificate::new(buf)?; - keys.push(Key { slot, cert }); + if !buf.is_empty() { + let cert = Certificate::new(buf)?; + keys.push(Key { slot, cert }); + } } Ok(keys) From 12b5bd1e3cdbcc9e57aeae68d649ec4a971d701d Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Sat, 30 Nov 2019 19:08:49 +0000 Subject: [PATCH 2/5] Convert SlotId into an enum --- src/certificate.rs | 13 +-- src/container.rs | 6 +- src/key.rs | 259 +++++++++++++++++++++++++++++++++++++-------- src/transaction.rs | 5 +- src/yubikey.rs | 16 ++- 5 files changed, 233 insertions(+), 66 deletions(-) diff --git a/src/certificate.rs b/src/certificate.rs index 71a3db4..6dbf4a5 100644 --- a/src/certificate.rs +++ b/src/certificate.rs @@ -31,13 +31,8 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. use crate::{ - consts::*, - error::Error, - key::{self, SlotId}, - serialization::*, - transaction::Transaction, - yubikey::YubiKey, - Buffer, + consts::*, error::Error, key::SlotId, serialization::*, transaction::Transaction, + yubikey::YubiKey, Buffer, }; use log::error; use zeroize::Zeroizing; @@ -100,7 +95,7 @@ impl AsRef<[u8]> for Certificate { /// Read certificate pub(crate) fn read_certificate(txn: &Transaction<'_>, slot: SlotId) -> Result { let mut len: usize = 0; - let object_id = key::slot_object(slot)?; + let object_id = slot.object_id(); let mut buf = match txn.fetch_object(object_id) { Ok(b) => b, @@ -141,7 +136,7 @@ pub(crate) fn write_certificate( let mut buf = [0u8; CB_OBJ_MAX]; let mut offset = 0; - let object_id = key::slot_object(slot)?; + let object_id = slot.object_id(); if data.is_none() { return txn.save_object(object_id, &[]); diff --git a/src/container.rs b/src/container.rs index ee5d8d3..56c4898 100644 --- a/src/container.rs +++ b/src/container.rs @@ -158,7 +158,7 @@ impl Container { Ok(Container { name, - slot: bytes[name_bytes_len], + slot: bytes[name_bytes_len].try_into()?, key_spec: bytes[name_bytes_len + 1], key_size_bits: u16::from_le_bytes( bytes[(name_bytes_len + 2)..(name_bytes_len + 4)] @@ -185,7 +185,7 @@ impl Container { bytes.extend_from_slice(&self.name[i].to_le_bytes()); } - bytes.push(self.slot); + bytes.push(self.slot.into()); bytes.push(self.key_spec); bytes.extend_from_slice(&self.key_size_bits.to_le_bytes()); bytes.push(self.flags); @@ -204,7 +204,7 @@ impl Debug for Container { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "PivContainer {{ name: {:?}, slot: {}, key_spec: {}, key_size_bits: {}, \ + "PivContainer {{ name: {:?}, slot: {:?}, key_spec: {}, key_size_bits: {}, \ flags: {}, pin_id: {}, associated_echd_container: {}, cert_fingerprint: {:?} }}", &self.name[..], self.slot, diff --git a/src/key.rs b/src/key.rs index 64c1b1a..53dbb0d 100644 --- a/src/key.rs +++ b/src/key.rs @@ -48,56 +48,229 @@ use crate::{ AlgorithmId, Buffer, ObjectId, }; use log::{debug, error, warn}; +use std::convert::TryFrom; /// Slot identifiers. /// -// TODO(tarcieri): replace these with enums -pub type SlotId = u8; +#[derive(Clone, Copy, Debug)] +pub enum SlotId { + /// This certificate and its associated private key is used to authenticate the card + /// and the cardholder. This slot is used for things like system login. The end user + /// PIN is required to perform any private key operations. Once the PIN has been + /// provided successfully, multiple private key operations may be performed without + /// additional cardholder consent. + Authentication, -/// Get the [`ObjectId`] that corresponds to a given [`SlotId`] -// TODO(tarcieri): factor this into a slot ID enum -pub(crate) fn slot_object(slot: SlotId) -> Result { - let id = match slot { - YKPIV_KEY_AUTHENTICATION => YKPIV_OBJ_AUTHENTICATION, - YKPIV_KEY_SIGNATURE => YKPIV_OBJ_SIGNATURE, - YKPIV_KEY_KEYMGM => YKPIV_OBJ_KEY_MANAGEMENT, - YKPIV_KEY_CARDAUTH => YKPIV_OBJ_CARD_AUTH, - YKPIV_KEY_ATTESTATION => YKPIV_OBJ_ATTESTATION, - slot if slot >= YKPIV_KEY_RETIRED1 && (slot <= YKPIV_KEY_RETIRED20) => { - YKPIV_OBJ_RETIRED1 + (slot - YKPIV_KEY_RETIRED1) as u32 + /// This certificate and its associated private key is used for digital signatures for + /// the purpose of document signing, or signing files and executables. The end user + /// PIN is required to perform any private key operations. The PIN must be submitted + /// every time immediately before a sign operation, to ensure cardholder participation + /// for every digital signature generated. + Signature, + + /// This certificate and its associated private key is used for encryption for the + /// purpose of confidentiality. This slot is used for things like encrypting e-mails + /// or files. The end user PIN is required to perform any private key operations. Once + /// the PIN has been provided successfully, multiple private key operations may be + /// performed without additional cardholder consent. + KeyManagement, + + /// This certificate and its associated private key is used to support additional + /// physical access applications, such as providing physical access to buildings via + /// PIV-enabled door locks. The end user PIN is NOT required to perform private key + /// operations for this slot. + CardAuthentication, + + /// These slots are only available on the YubiKey 4 & 5. They are meant for previously + /// used Key Management keys to be able to decrypt earlier encrypted documents or + /// emails. In the YubiKey 4 & 5 all 20 of them are fully available for use. + Retired(RetiredSlotId), + + /// This slot is only available on YubiKey version 4.3 and newer. It is only used for + /// attestation of other keys generated on device with instruction `f9`. This slot is + /// not cleared on reset, but can be overwritten. + Attestation, +} + +impl TryFrom for SlotId { + type Error = Error; + + fn try_from(value: u8) -> Result { + match value { + YKPIV_KEY_AUTHENTICATION => Ok(SlotId::Authentication), + YKPIV_KEY_SIGNATURE => Ok(SlotId::Signature), + YKPIV_KEY_KEYMGM => Ok(SlotId::KeyManagement), + YKPIV_KEY_CARDAUTH => Ok(SlotId::CardAuthentication), + YKPIV_KEY_ATTESTATION => Ok(SlotId::Attestation), + _ => RetiredSlotId::try_from(value).map(SlotId::Retired), } - _ => return Err(Error::InvalidObject), - }; + } +} - Ok(id) +impl From for u8 { + fn from(slot: SlotId) -> u8 { + match slot { + SlotId::Authentication => YKPIV_KEY_AUTHENTICATION, + SlotId::Signature => YKPIV_KEY_SIGNATURE, + SlotId::KeyManagement => YKPIV_KEY_KEYMGM, + SlotId::CardAuthentication => YKPIV_KEY_CARDAUTH, + SlotId::Retired(retired) => retired.into(), + SlotId::Attestation => YKPIV_KEY_ATTESTATION, + } + } +} + +impl SlotId { + /// Returns the [`ObjectId`] that corresponds to a given [`SlotId`]. + pub(crate) fn object_id(self) -> ObjectId { + match self { + SlotId::Authentication => YKPIV_OBJ_AUTHENTICATION, + SlotId::Signature => YKPIV_OBJ_SIGNATURE, + SlotId::KeyManagement => YKPIV_OBJ_KEY_MANAGEMENT, + SlotId::CardAuthentication => YKPIV_OBJ_CARD_AUTH, + SlotId::Retired(retired) => retired.object_id(), + SlotId::Attestation => YKPIV_OBJ_ATTESTATION, + } + } +} + +/// Retired slot IDs. +#[allow(missing_docs)] +#[derive(Clone, Copy, Debug)] +pub enum RetiredSlotId { + R1, + R2, + R3, + R4, + R5, + R6, + R7, + R8, + R9, + R10, + R11, + R12, + R13, + R14, + R15, + R16, + R17, + R18, + R19, + R20, +} + +impl TryFrom for RetiredSlotId { + type Error = Error; + + fn try_from(value: u8) -> Result { + match value { + YKPIV_KEY_RETIRED1 => Ok(RetiredSlotId::R1), + YKPIV_KEY_RETIRED2 => Ok(RetiredSlotId::R2), + YKPIV_KEY_RETIRED3 => Ok(RetiredSlotId::R3), + YKPIV_KEY_RETIRED4 => Ok(RetiredSlotId::R4), + YKPIV_KEY_RETIRED5 => Ok(RetiredSlotId::R5), + YKPIV_KEY_RETIRED6 => Ok(RetiredSlotId::R6), + YKPIV_KEY_RETIRED7 => Ok(RetiredSlotId::R7), + YKPIV_KEY_RETIRED8 => Ok(RetiredSlotId::R8), + YKPIV_KEY_RETIRED9 => Ok(RetiredSlotId::R9), + YKPIV_KEY_RETIRED10 => Ok(RetiredSlotId::R10), + YKPIV_KEY_RETIRED11 => Ok(RetiredSlotId::R11), + YKPIV_KEY_RETIRED12 => Ok(RetiredSlotId::R12), + YKPIV_KEY_RETIRED13 => Ok(RetiredSlotId::R13), + YKPIV_KEY_RETIRED14 => Ok(RetiredSlotId::R14), + YKPIV_KEY_RETIRED15 => Ok(RetiredSlotId::R15), + YKPIV_KEY_RETIRED16 => Ok(RetiredSlotId::R16), + YKPIV_KEY_RETIRED17 => Ok(RetiredSlotId::R17), + YKPIV_KEY_RETIRED18 => Ok(RetiredSlotId::R18), + YKPIV_KEY_RETIRED19 => Ok(RetiredSlotId::R19), + YKPIV_KEY_RETIRED20 => Ok(RetiredSlotId::R20), + _ => Err(Error::InvalidObject), + } + } +} + +impl From for u8 { + fn from(slot: RetiredSlotId) -> u8 { + match slot { + RetiredSlotId::R1 => YKPIV_KEY_RETIRED1, + RetiredSlotId::R2 => YKPIV_KEY_RETIRED2, + RetiredSlotId::R3 => YKPIV_KEY_RETIRED3, + RetiredSlotId::R4 => YKPIV_KEY_RETIRED4, + RetiredSlotId::R5 => YKPIV_KEY_RETIRED5, + RetiredSlotId::R6 => YKPIV_KEY_RETIRED6, + RetiredSlotId::R7 => YKPIV_KEY_RETIRED7, + RetiredSlotId::R8 => YKPIV_KEY_RETIRED8, + RetiredSlotId::R9 => YKPIV_KEY_RETIRED9, + RetiredSlotId::R10 => YKPIV_KEY_RETIRED10, + RetiredSlotId::R11 => YKPIV_KEY_RETIRED11, + RetiredSlotId::R12 => YKPIV_KEY_RETIRED12, + RetiredSlotId::R13 => YKPIV_KEY_RETIRED13, + RetiredSlotId::R14 => YKPIV_KEY_RETIRED14, + RetiredSlotId::R15 => YKPIV_KEY_RETIRED15, + RetiredSlotId::R16 => YKPIV_KEY_RETIRED16, + RetiredSlotId::R17 => YKPIV_KEY_RETIRED17, + RetiredSlotId::R18 => YKPIV_KEY_RETIRED18, + RetiredSlotId::R19 => YKPIV_KEY_RETIRED19, + RetiredSlotId::R20 => YKPIV_KEY_RETIRED20, + } + } +} + +impl RetiredSlotId { + /// Returns the [`ObjectId`] that corresponds to a given [`RetiredSlotId`]. + pub(crate) fn object_id(self) -> ObjectId { + match self { + RetiredSlotId::R1 => YKPIV_OBJ_RETIRED1, + RetiredSlotId::R2 => YKPIV_OBJ_RETIRED2, + RetiredSlotId::R3 => YKPIV_OBJ_RETIRED3, + RetiredSlotId::R4 => YKPIV_OBJ_RETIRED4, + RetiredSlotId::R5 => YKPIV_OBJ_RETIRED5, + RetiredSlotId::R6 => YKPIV_OBJ_RETIRED6, + RetiredSlotId::R7 => YKPIV_OBJ_RETIRED7, + RetiredSlotId::R8 => YKPIV_OBJ_RETIRED8, + RetiredSlotId::R9 => YKPIV_OBJ_RETIRED9, + RetiredSlotId::R10 => YKPIV_OBJ_RETIRED10, + RetiredSlotId::R11 => YKPIV_OBJ_RETIRED11, + RetiredSlotId::R12 => YKPIV_OBJ_RETIRED12, + RetiredSlotId::R13 => YKPIV_OBJ_RETIRED13, + RetiredSlotId::R14 => YKPIV_OBJ_RETIRED14, + RetiredSlotId::R15 => YKPIV_OBJ_RETIRED15, + RetiredSlotId::R16 => YKPIV_OBJ_RETIRED16, + RetiredSlotId::R17 => YKPIV_OBJ_RETIRED17, + RetiredSlotId::R18 => YKPIV_OBJ_RETIRED18, + RetiredSlotId::R19 => YKPIV_OBJ_RETIRED19, + RetiredSlotId::R20 => YKPIV_OBJ_RETIRED20, + } + } } /// Personal Identity Verification (PIV) key slots -pub const SLOTS: [u8; 24] = [ - YKPIV_KEY_AUTHENTICATION, - YKPIV_KEY_SIGNATURE, - YKPIV_KEY_KEYMGM, - YKPIV_KEY_RETIRED1, - YKPIV_KEY_RETIRED2, - YKPIV_KEY_RETIRED3, - YKPIV_KEY_RETIRED4, - YKPIV_KEY_RETIRED5, - YKPIV_KEY_RETIRED6, - YKPIV_KEY_RETIRED7, - YKPIV_KEY_RETIRED8, - YKPIV_KEY_RETIRED9, - YKPIV_KEY_RETIRED10, - YKPIV_KEY_RETIRED11, - YKPIV_KEY_RETIRED12, - YKPIV_KEY_RETIRED13, - YKPIV_KEY_RETIRED14, - YKPIV_KEY_RETIRED15, - YKPIV_KEY_RETIRED16, - YKPIV_KEY_RETIRED17, - YKPIV_KEY_RETIRED18, - YKPIV_KEY_RETIRED19, - YKPIV_KEY_RETIRED20, - YKPIV_KEY_CARDAUTH, +pub const SLOTS: [SlotId; 24] = [ + SlotId::Authentication, + SlotId::Signature, + SlotId::KeyManagement, + SlotId::Retired(RetiredSlotId::R1), + SlotId::Retired(RetiredSlotId::R2), + SlotId::Retired(RetiredSlotId::R3), + SlotId::Retired(RetiredSlotId::R4), + SlotId::Retired(RetiredSlotId::R5), + SlotId::Retired(RetiredSlotId::R6), + SlotId::Retired(RetiredSlotId::R7), + SlotId::Retired(RetiredSlotId::R8), + SlotId::Retired(RetiredSlotId::R9), + SlotId::Retired(RetiredSlotId::R10), + SlotId::Retired(RetiredSlotId::R11), + SlotId::Retired(RetiredSlotId::R12), + SlotId::Retired(RetiredSlotId::R13), + SlotId::Retired(RetiredSlotId::R14), + SlotId::Retired(RetiredSlotId::R15), + SlotId::Retired(RetiredSlotId::R16), + SlotId::Retired(RetiredSlotId::R17), + SlotId::Retired(RetiredSlotId::R18), + SlotId::Retired(RetiredSlotId::R19), + SlotId::Retired(RetiredSlotId::R20), + SlotId::CardAuthentication, ]; /// PIV cryptographic keys stored in a YubiKey @@ -120,7 +293,7 @@ impl Key { let buf = match certificate::read_certificate(&txn, slot) { Ok(b) => b, Err(e) => { - debug!("error reading certificate in slot {}: {}", slot, e); + debug!("error reading certificate in slot {:?}: {}", slot, e); continue; } }; @@ -252,7 +425,7 @@ pub fn generate( let txn = yubikey.begin_transaction()?; - templ[3] = slot; + templ[3] = slot.into(); let mut offset = 5; in_data[..offset].copy_from_slice(&[ diff --git a/src/transaction.rs b/src/transaction.rs index 68fa89f..bda9caf 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -9,6 +9,7 @@ use crate::{ use crate::{ apdu::{Response, StatusWords}, consts::*, + key::SlotId, mgm::MgmKey, serialization::*, Buffer, ObjectId, @@ -267,12 +268,12 @@ impl<'tx> Transaction<'tx> { &self, sign_in: &[u8], algorithm: u8, - key: u8, + key: SlotId, decipher: bool, ) -> Result { let in_len = sign_in.len(); let mut indata = [0u8; 1024]; - let templ = [0, Ins::Authenticate.code(), algorithm, key]; + let templ = [0, Ins::Authenticate.code(), algorithm, key.into()]; let mut len: usize = 0; match algorithm { diff --git a/src/yubikey.rs b/src/yubikey.rs index cedfc80..e18e5a6 100644 --- a/src/yubikey.rs +++ b/src/yubikey.rs @@ -609,15 +609,13 @@ impl YubiKey { touch_policy: u8, ) -> Result<(), Error> { let mut key_data = Zeroizing::new(vec![0u8; 1024]); - let templ = [0, Ins::ImportKey.code(), algorithm, key]; + let templ = [0, Ins::ImportKey.code(), algorithm, key.into()]; - if key == YKPIV_KEY_CARDMGM - || key < YKPIV_KEY_RETIRED1 - || (key > YKPIV_KEY_RETIRED20 && key < YKPIV_KEY_AUTHENTICATION) - || (key > YKPIV_KEY_CARDAUTH && key != YKPIV_KEY_ATTESTATION) - { - return Err(Error::KeyError); - } + // Only slot we want to exclude is CardManagement, which isn't in the enum. + // TODO: Decide whether to add it or not. + // match key { + // SlotId::CardManagement => return Err(Error::KeyError), + // } if pin_policy != YKPIV_PINPOLICY_DEFAULT && pin_policy != YKPIV_PINPOLICY_NEVER @@ -730,7 +728,7 @@ impl YubiKey { /// #[cfg(feature = "untested")] pub fn attest(&mut self, key: SlotId) -> Result { - let templ = [0, Ins::Attest.code(), key, 0]; + let templ = [0, Ins::Attest.code(), key.into(), 0]; let txn = self.begin_transaction()?; let response = txn.transfer_data(&templ, &[], CB_OBJ_MAX)?; From afca0fec0a72fae6a79e7f24bb37136146d5cea8 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Sat, 30 Nov 2019 19:36:09 +0000 Subject: [PATCH 3/5] Convert AlgorithmId into an enum 3DES also has an algorithm ID, but it is completely disjoint from the key algorithms, and can be handled separately later. --- src/consts.rs | 4 -- src/key.rs | 133 ++++++++++++++++++++++++++++----------------- src/lib.rs | 4 -- src/transaction.rs | 25 ++++----- src/yubikey.rs | 23 ++++---- 5 files changed, 104 insertions(+), 85 deletions(-) diff --git a/src/consts.rs b/src/consts.rs index 75ef5dd..ab903e7 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -124,10 +124,6 @@ pub const TAG_ECC_POINT: u8 = 0x86; pub const YKPIV_ALGO_TAG: u8 = 0x80; pub const YKPIV_ALGO_3DES: u8 = 0x03; -pub const YKPIV_ALGO_RSA1024: u8 = 0x06; -pub const YKPIV_ALGO_RSA2048: u8 = 0x07; -pub const YKPIV_ALGO_ECCP256: u8 = 0x11; -pub const YKPIV_ALGO_ECCP384: u8 = 0x14; pub const YKPIV_ATR_NEO_R3: &[u8] = b";\xFC\x13\0\0\x811\xFE\x15YubikeyNEOr3\xE1\0"; diff --git a/src/key.rs b/src/key.rs index 53dbb0d..59cd178 100644 --- a/src/key.rs +++ b/src/key.rs @@ -45,7 +45,7 @@ use crate::{ serialization::*, settings, yubikey::YubiKey, - AlgorithmId, Buffer, ObjectId, + Buffer, ObjectId, }; use log::{debug, error, warn}; use std::convert::TryFrom; @@ -273,6 +273,44 @@ pub const SLOTS: [SlotId; 24] = [ SlotId::CardAuthentication, ]; +/// Algorithm identifiers +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum AlgorithmId { + /// 1024-bit RSA. + Rsa1024, + /// 2048-bit RSA. + Rsa2048, + /// ECDSA with the NIST P256 curve. + EccP256, + /// ECDSA with the NIST P384 curve. + EccP384, +} + +impl TryFrom for AlgorithmId { + type Error = Error; + + fn try_from(value: u8) -> Result { + match value { + 0x06 => Ok(AlgorithmId::Rsa1024), + 0x07 => Ok(AlgorithmId::Rsa2048), + 0x11 => Ok(AlgorithmId::EccP256), + 0x14 => Ok(AlgorithmId::EccP384), + _ => Err(Error::AlgorithmError), + } + } +} + +impl From for u8 { + fn from(id: AlgorithmId) -> u8 { + match id { + AlgorithmId::Rsa1024 => 0x06, + AlgorithmId::Rsa2048 => 0x07, + AlgorithmId::EccP256 => 0x11, + AlgorithmId::EccP384 => 0x14, + } + } +} + /// PIV cryptographic keys stored in a YubiKey #[derive(Clone, Debug)] pub struct Key { @@ -377,50 +415,47 @@ pub fn generate( let mut templ = [0, Ins::GenerateAsymmetric.code(), 0, 0]; let setting_roca: settings::BoolValue; - if yubikey.device_model() == DEVTYPE_YK4 - && (algorithm == YKPIV_ALGO_RSA1024 || algorithm == YKPIV_ALGO_RSA2048) - && yubikey.version.major == 4 - && (yubikey.version.minor < 3 || yubikey.version.minor == 3 && (yubikey.version.patch < 5)) - { - setting_roca = settings::BoolValue::get(SZ_SETTING_ROCA, true); - - let psz_msg = match setting_roca.source { - settings::Source::User => { - if setting_roca.value { - SZ_ROCA_ALLOW_USER - } else { - SZ_ROCA_BLOCK_USER - } - } - settings::Source::Admin => { - if setting_roca.value { - SZ_ROCA_ALLOW_ADMIN - } else { - SZ_ROCA_BLOCK_ADMIN - } - } - _ => SZ_ROCA_DEFAULT, - }; - - warn!( - "YubiKey serial number {} is affected by vulnerability CVE-2017-15361 \ - (ROCA) and should be replaced. On-chip key generation {} See \ - YSA-2017-01 \ - for additional information on device replacement and mitigation assistance", - yubikey.serial, psz_msg - ); - - if !setting_roca.value { - return Err(Error::NotSupported); - } - } - match algorithm { - YKPIV_ALGO_RSA1024 | YKPIV_ALGO_RSA2048 | YKPIV_ALGO_ECCP256 | YKPIV_ALGO_ECCP384 => (), - _ => { - error!("invalid algorithm specified"); - return Err(Error::GenericError); + AlgorithmId::Rsa1024 | AlgorithmId::Rsa2048 => { + if yubikey.device_model() == DEVTYPE_YK4 + && yubikey.version.major == 4 + && (yubikey.version.minor < 3 + || yubikey.version.minor == 3 && (yubikey.version.patch < 5)) + { + setting_roca = settings::BoolValue::get(SZ_SETTING_ROCA, true); + + let psz_msg = match setting_roca.source { + settings::Source::User => { + if setting_roca.value { + SZ_ROCA_ALLOW_USER + } else { + SZ_ROCA_BLOCK_USER + } + } + settings::Source::Admin => { + if setting_roca.value { + SZ_ROCA_ALLOW_ADMIN + } else { + SZ_ROCA_BLOCK_ADMIN + } + } + _ => SZ_ROCA_DEFAULT, + }; + + warn!( + "YubiKey serial number {} is affected by vulnerability CVE-2017-15361 \ + (ROCA) and should be replaced. On-chip key generation {} See \ + YSA-2017-01 \ + for additional information on device replacement and mitigation assistance", + yubikey.serial, psz_msg + ); + + if !setting_roca.value { + return Err(Error::NotSupported); + } + } } + _ => (), } let txn = yubikey.begin_transaction()?; @@ -433,7 +468,7 @@ pub fn generate( 3, // length sans this 2-byte header YKPIV_ALGO_TAG, 1, - algorithm, + algorithm.into(), ]); if in_data[4] == 0 { @@ -487,7 +522,7 @@ pub fn generate( let data = Buffer::new(response.data().into()); match algorithm { - YKPIV_ALGO_RSA1024 | YKPIV_ALGO_RSA2048 => { + AlgorithmId::Rsa1024 | AlgorithmId::Rsa2048 => { let mut offset = 5; let mut len = 0; @@ -515,10 +550,10 @@ pub fn generate( exp, }) } - YKPIV_ALGO_ECCP256 | YKPIV_ALGO_ECCP384 => { + AlgorithmId::EccP256 | AlgorithmId::EccP384 => { let mut offset = 3; - let len = if algorithm == YKPIV_ALGO_ECCP256 { + let len = if let AlgorithmId::EccP256 = algorithm { CB_ECC_POINTP256 } else { CB_ECC_POINTP384 @@ -542,9 +577,5 @@ pub fn generate( let point = data[offset..(offset + len)].to_vec(); Ok(GeneratedKey::Ecc { algorithm, point }) } - _ => { - error!("wrong algorithm"); - Err(Error::AlgorithmError) - } } } diff --git a/src/lib.rs b/src/lib.rs index b4d9851..37fd0c2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -167,10 +167,6 @@ pub mod yubikey; pub use self::{key::Key, mgm::MgmKey}; pub use yubikey::YubiKey; -/// Algorithm identifiers -// TODO(tarcieri): make this an enum -pub type AlgorithmId = u8; - /// Object identifiers pub type ObjectId = u32; diff --git a/src/transaction.rs b/src/transaction.rs index bda9caf..2514024 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -9,7 +9,7 @@ use crate::{ use crate::{ apdu::{Response, StatusWords}, consts::*, - key::SlotId, + key::{AlgorithmId, SlotId}, mgm::MgmKey, serialization::*, Buffer, ObjectId, @@ -267,18 +267,18 @@ impl<'tx> Transaction<'tx> { pub(crate) fn authenticated_command( &self, sign_in: &[u8], - algorithm: u8, + algorithm: AlgorithmId, key: SlotId, decipher: bool, ) -> Result { let in_len = sign_in.len(); let mut indata = [0u8; 1024]; - let templ = [0, Ins::Authenticate.code(), algorithm, key.into()]; + let templ = [0, Ins::Authenticate.code(), algorithm.into(), key.into()]; let mut len: usize = 0; match algorithm { - YKPIV_ALGO_RSA1024 | YKPIV_ALGO_RSA2048 => { - let key_len = if algorithm == YKPIV_ALGO_RSA1024 { + AlgorithmId::Rsa1024 | AlgorithmId::Rsa2048 => { + let key_len = if let AlgorithmId::Rsa1024 = algorithm { 128 } else { 256 @@ -288,8 +288,8 @@ impl<'tx> Transaction<'tx> { return Err(Error::SizeError); } } - YKPIV_ALGO_ECCP256 | YKPIV_ALGO_ECCP384 => { - let key_len = if algorithm == YKPIV_ALGO_ECCP256 { + AlgorithmId::EccP256 | AlgorithmId::EccP384 => { + let key_len = if let AlgorithmId::EccP256 = algorithm { 32 } else { 48 @@ -300,7 +300,6 @@ impl<'tx> Transaction<'tx> { return Err(Error::SizeError); } } - _ => return Err(Error::AlgorithmError), } let bytes = if in_len < 0x80 { @@ -315,12 +314,10 @@ impl<'tx> Transaction<'tx> { let mut offset = 1 + set_length(&mut indata[1..], in_len + bytes + 3); indata[offset] = 0x82; indata[offset + 1] = 0x00; - indata[offset + 2] = - if (algorithm == YKPIV_ALGO_ECCP256 || algorithm == YKPIV_ALGO_ECCP384) && decipher { - 0x85 - } else { - 0x81 - }; + indata[offset + 2] = match (algorithm, decipher) { + (AlgorithmId::EccP256, true) | (AlgorithmId::EccP384, true) => 0x85, + _ => 0x81, + }; offset += 3; offset += set_length(&mut indata[offset..], in_len); diff --git a/src/yubikey.rs b/src/yubikey.rs index e18e5a6..eba6e04 100644 --- a/src/yubikey.rs +++ b/src/yubikey.rs @@ -36,7 +36,7 @@ #[cfg(feature = "untested")] use crate::{ apdu::{Ins, StatusWords, APDU}, - key::SlotId, + key::{AlgorithmId, SlotId}, metadata, mgm::MgmKey, serialization::*, @@ -356,7 +356,7 @@ impl YubiKey { pub fn sign_data( &mut self, raw_in: &[u8], - algorithm: u8, + algorithm: AlgorithmId, key: SlotId, ) -> Result { let txn = self.begin_transaction()?; @@ -370,7 +370,7 @@ impl YubiKey { pub fn decrypt_data( &mut self, input: &[u8], - algorithm: u8, + algorithm: AlgorithmId, key: SlotId, ) -> Result { let txn = self.begin_transaction()?; @@ -598,7 +598,7 @@ impl YubiKey { pub fn import_private_key( &mut self, key: SlotId, - algorithm: u8, + algorithm: AlgorithmId, p: Option<&[u8]>, q: Option<&[u8]>, dp: Option<&[u8]>, @@ -609,7 +609,7 @@ impl YubiKey { touch_policy: u8, ) -> Result<(), Error> { let mut key_data = Zeroizing::new(vec![0u8; 1024]); - let templ = [0, Ins::ImportKey.code(), algorithm, key.into()]; + let templ = [0, Ins::ImportKey.code(), algorithm.into(), key.into()]; // Only slot we want to exclude is CardManagement, which isn't in the enum. // TODO: Decide whether to add it or not. @@ -634,7 +634,7 @@ impl YubiKey { } let (elem_len, params, param_tag) = match algorithm { - YKPIV_ALGO_RSA1024 | YKPIV_ALGO_RSA2048 => match (p, q, dp, dq, qinv) { + AlgorithmId::Rsa1024 | AlgorithmId::Rsa2048 => match (p, q, dp, dq, qinv) { (Some(p), Some(q), Some(dp), Some(dq), Some(qinv)) => { if p.len() + q.len() + dp.len() + dq.len() + qinv.len() >= key_data.len() { return Err(Error::SizeError); @@ -642,8 +642,8 @@ impl YubiKey { ( match algorithm { - YKPIV_ALGO_RSA1024 => 64, - YKPIV_ALGO_RSA2048 => 128, + AlgorithmId::Rsa1024 => 64, + AlgorithmId::Rsa2048 => 128, _ => unreachable!(), }, vec![p, q, dp, dq, qinv], @@ -652,7 +652,7 @@ impl YubiKey { } _ => return Err(Error::GenericError), }, - YKPIV_ALGO_ECCP256 | YKPIV_ALGO_ECCP384 => match ec_data { + AlgorithmId::EccP256 | AlgorithmId::EccP384 => match ec_data { Some(ec_data) => { if ec_data.len() >= key_data.len() { // This can never be true, but check to be explicit. @@ -661,8 +661,8 @@ impl YubiKey { ( match algorithm { - YKPIV_ALGO_ECCP256 => 32, - YKPIV_ALGO_ECCP384 => 48, + AlgorithmId::EccP256 => 32, + AlgorithmId::EccP384 => 48, _ => unreachable!(), }, vec![ec_data], @@ -671,7 +671,6 @@ impl YubiKey { } _ => return Err(Error::GenericError), }, - _ => return Err(Error::AlgorithmError), }; let mut offset = 0; From 11c93d6421e9851dee26440cdac6c55e65782e13 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Sat, 30 Nov 2019 22:01:22 +0000 Subject: [PATCH 4/5] Inline SlotId constants --- src/consts.rs | 51 ----------------- src/key.rs | 150 +++++++++++++++++++++++++------------------------- 2 files changed, 75 insertions(+), 126 deletions(-) diff --git a/src/consts.rs b/src/consts.rs index ab903e7..2988342 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -137,72 +137,21 @@ pub const YKPIV_CCCID_SIZE: usize = 14; pub const YKPIV_CERTINFO_UNCOMPRESSED: u8 = 0; pub const YKPIV_CERTINFO_GZIP: u8 = 1; -pub const YKPIV_KEY_AUTHENTICATION: u8 = 0x9a; pub const YKPIV_KEY_CARDMGM: u8 = 0x9b; -pub const YKPIV_KEY_SIGNATURE: u8 = 0x9c; -pub const YKPIV_KEY_KEYMGM: u8 = 0x9d; -pub const YKPIV_KEY_CARDAUTH: u8 = 0x9e; -pub const YKPIV_KEY_RETIRED1: u8 = 0x82; -pub const YKPIV_KEY_RETIRED2: u8 = 0x83; -pub const YKPIV_KEY_RETIRED3: u8 = 0x84; -pub const YKPIV_KEY_RETIRED4: u8 = 0x85; -pub const YKPIV_KEY_RETIRED5: u8 = 0x86; -pub const YKPIV_KEY_RETIRED6: u8 = 0x87; -pub const YKPIV_KEY_RETIRED7: u8 = 0x88; -pub const YKPIV_KEY_RETIRED8: u8 = 0x89; -pub const YKPIV_KEY_RETIRED9: u8 = 0x8a; -pub const YKPIV_KEY_RETIRED10: u8 = 0x8b; -pub const YKPIV_KEY_RETIRED11: u8 = 0x8c; -pub const YKPIV_KEY_RETIRED12: u8 = 0x8d; -pub const YKPIV_KEY_RETIRED13: u8 = 0x8e; -pub const YKPIV_KEY_RETIRED14: u8 = 0x8f; -pub const YKPIV_KEY_RETIRED15: u8 = 0x90; -pub const YKPIV_KEY_RETIRED16: u8 = 0x91; -pub const YKPIV_KEY_RETIRED17: u8 = 0x92; -pub const YKPIV_KEY_RETIRED18: u8 = 0x93; -pub const YKPIV_KEY_RETIRED19: u8 = 0x94; -pub const YKPIV_KEY_RETIRED20: u8 = 0x95; -pub const YKPIV_KEY_ATTESTATION: u8 = 0xf9; pub const YKPIV_OBJ_CAPABILITY: u32 = 0x005f_c107; pub const YKPIV_OBJ_CHUID: u32 = 0x005f_c102; -pub const YKPIV_OBJ_AUTHENTICATION: u32 = 0x005f_c105; // cert for 9a key pub const YKPIV_OBJ_FINGERPRINTS: u32 = 0x005f_c103; pub const YKPIV_OBJ_SECURITY: u32 = 0x005f_c106; pub const YKPIV_OBJ_FACIAL: u32 = 0x005f_c108; pub const YKPIV_OBJ_PRINTED: u32 = 0x005f_c109; -pub const YKPIV_OBJ_SIGNATURE: u32 = 0x005f_c10a; // cert for 9c key -pub const YKPIV_OBJ_KEY_MANAGEMENT: u32 = 0x005f_c10b; // cert for 9d key -pub const YKPIV_OBJ_CARD_AUTH: u32 = 0x005f_c101; // cert for 9e key pub const YKPIV_OBJ_DISCOVERY: u32 = 0x7e; pub const YKPIV_OBJ_KEY_HISTORY: u32 = 0x005f_c10c; pub const YKPIV_OBJ_IRIS: u32 = 0x005f_c121; -pub const YKPIV_OBJ_RETIRED1: u32 = 0x005f_c10d; -pub const YKPIV_OBJ_RETIRED2: u32 = 0x005f_c10e; -pub const YKPIV_OBJ_RETIRED3: u32 = 0x005f_c10f; -pub const YKPIV_OBJ_RETIRED4: u32 = 0x005f_c110; -pub const YKPIV_OBJ_RETIRED5: u32 = 0x005f_c111; -pub const YKPIV_OBJ_RETIRED6: u32 = 0x005f_c112; -pub const YKPIV_OBJ_RETIRED7: u32 = 0x005f_c113; -pub const YKPIV_OBJ_RETIRED8: u32 = 0x005f_c114; -pub const YKPIV_OBJ_RETIRED9: u32 = 0x005f_c115; -pub const YKPIV_OBJ_RETIRED10: u32 = 0x005f_c116; -pub const YKPIV_OBJ_RETIRED11: u32 = 0x005f_c117; -pub const YKPIV_OBJ_RETIRED12: u32 = 0x005f_c118; -pub const YKPIV_OBJ_RETIRED13: u32 = 0x005f_c119; -pub const YKPIV_OBJ_RETIRED14: u32 = 0x005f_c11a; -pub const YKPIV_OBJ_RETIRED15: u32 = 0x005f_c11b; -pub const YKPIV_OBJ_RETIRED16: u32 = 0x005f_c11c; -pub const YKPIV_OBJ_RETIRED17: u32 = 0x005f_c11d; -pub const YKPIV_OBJ_RETIRED18: u32 = 0x005f_c11e; -pub const YKPIV_OBJ_RETIRED19: u32 = 0x005f_c11f; -pub const YKPIV_OBJ_RETIRED20: u32 = 0x005f_c120; - // Internal object IDs pub const YKPIV_OBJ_ADMIN_DATA: u32 = 0x005f_ff00; -pub const YKPIV_OBJ_ATTESTATION: u32 = 0x005f_ff01; pub const YKPIV_OBJ_MSCMAP: u32 = 0x005f_ff10; pub const YKPIV_OBJ_MSROOTS1: u32 = 0x005f_ff11; pub const YKPIV_OBJ_MSROOTS2: u32 = 0x005f_ff12; diff --git a/src/key.rs b/src/key.rs index 59cd178..96392c7 100644 --- a/src/key.rs +++ b/src/key.rs @@ -97,11 +97,11 @@ impl TryFrom for SlotId { fn try_from(value: u8) -> Result { match value { - YKPIV_KEY_AUTHENTICATION => Ok(SlotId::Authentication), - YKPIV_KEY_SIGNATURE => Ok(SlotId::Signature), - YKPIV_KEY_KEYMGM => Ok(SlotId::KeyManagement), - YKPIV_KEY_CARDAUTH => Ok(SlotId::CardAuthentication), - YKPIV_KEY_ATTESTATION => Ok(SlotId::Attestation), + 0x9a => Ok(SlotId::Authentication), + 0x9c => Ok(SlotId::Signature), + 0x9d => Ok(SlotId::KeyManagement), + 0x9e => Ok(SlotId::CardAuthentication), + 0xf9 => Ok(SlotId::Attestation), _ => RetiredSlotId::try_from(value).map(SlotId::Retired), } } @@ -110,12 +110,12 @@ impl TryFrom for SlotId { impl From for u8 { fn from(slot: SlotId) -> u8 { match slot { - SlotId::Authentication => YKPIV_KEY_AUTHENTICATION, - SlotId::Signature => YKPIV_KEY_SIGNATURE, - SlotId::KeyManagement => YKPIV_KEY_KEYMGM, - SlotId::CardAuthentication => YKPIV_KEY_CARDAUTH, + SlotId::Authentication => 0x9a, + SlotId::Signature => 0x9c, + SlotId::KeyManagement => 0x9d, + SlotId::CardAuthentication => 0x9e, SlotId::Retired(retired) => retired.into(), - SlotId::Attestation => YKPIV_KEY_ATTESTATION, + SlotId::Attestation => 0xf9, } } } @@ -124,12 +124,12 @@ impl SlotId { /// Returns the [`ObjectId`] that corresponds to a given [`SlotId`]. pub(crate) fn object_id(self) -> ObjectId { match self { - SlotId::Authentication => YKPIV_OBJ_AUTHENTICATION, - SlotId::Signature => YKPIV_OBJ_SIGNATURE, - SlotId::KeyManagement => YKPIV_OBJ_KEY_MANAGEMENT, - SlotId::CardAuthentication => YKPIV_OBJ_CARD_AUTH, + SlotId::Authentication => 0x005f_c105, + SlotId::Signature => 0x005f_c10a, + SlotId::KeyManagement => 0x005f_c10b, + SlotId::CardAuthentication => 0x005f_c101, SlotId::Retired(retired) => retired.object_id(), - SlotId::Attestation => YKPIV_OBJ_ATTESTATION, + SlotId::Attestation => 0x005f_ff01, } } } @@ -165,26 +165,26 @@ impl TryFrom for RetiredSlotId { fn try_from(value: u8) -> Result { match value { - YKPIV_KEY_RETIRED1 => Ok(RetiredSlotId::R1), - YKPIV_KEY_RETIRED2 => Ok(RetiredSlotId::R2), - YKPIV_KEY_RETIRED3 => Ok(RetiredSlotId::R3), - YKPIV_KEY_RETIRED4 => Ok(RetiredSlotId::R4), - YKPIV_KEY_RETIRED5 => Ok(RetiredSlotId::R5), - YKPIV_KEY_RETIRED6 => Ok(RetiredSlotId::R6), - YKPIV_KEY_RETIRED7 => Ok(RetiredSlotId::R7), - YKPIV_KEY_RETIRED8 => Ok(RetiredSlotId::R8), - YKPIV_KEY_RETIRED9 => Ok(RetiredSlotId::R9), - YKPIV_KEY_RETIRED10 => Ok(RetiredSlotId::R10), - YKPIV_KEY_RETIRED11 => Ok(RetiredSlotId::R11), - YKPIV_KEY_RETIRED12 => Ok(RetiredSlotId::R12), - YKPIV_KEY_RETIRED13 => Ok(RetiredSlotId::R13), - YKPIV_KEY_RETIRED14 => Ok(RetiredSlotId::R14), - YKPIV_KEY_RETIRED15 => Ok(RetiredSlotId::R15), - YKPIV_KEY_RETIRED16 => Ok(RetiredSlotId::R16), - YKPIV_KEY_RETIRED17 => Ok(RetiredSlotId::R17), - YKPIV_KEY_RETIRED18 => Ok(RetiredSlotId::R18), - YKPIV_KEY_RETIRED19 => Ok(RetiredSlotId::R19), - YKPIV_KEY_RETIRED20 => Ok(RetiredSlotId::R20), + 0x82 => Ok(RetiredSlotId::R1), + 0x83 => Ok(RetiredSlotId::R2), + 0x84 => Ok(RetiredSlotId::R3), + 0x85 => Ok(RetiredSlotId::R4), + 0x86 => Ok(RetiredSlotId::R5), + 0x87 => Ok(RetiredSlotId::R6), + 0x88 => Ok(RetiredSlotId::R7), + 0x89 => Ok(RetiredSlotId::R8), + 0x8a => Ok(RetiredSlotId::R9), + 0x8b => Ok(RetiredSlotId::R10), + 0x8c => Ok(RetiredSlotId::R11), + 0x8d => Ok(RetiredSlotId::R12), + 0x8e => Ok(RetiredSlotId::R13), + 0x8f => Ok(RetiredSlotId::R14), + 0x90 => Ok(RetiredSlotId::R15), + 0x91 => Ok(RetiredSlotId::R16), + 0x92 => Ok(RetiredSlotId::R17), + 0x93 => Ok(RetiredSlotId::R18), + 0x94 => Ok(RetiredSlotId::R19), + 0x95 => Ok(RetiredSlotId::R20), _ => Err(Error::InvalidObject), } } @@ -193,26 +193,26 @@ impl TryFrom for RetiredSlotId { impl From for u8 { fn from(slot: RetiredSlotId) -> u8 { match slot { - RetiredSlotId::R1 => YKPIV_KEY_RETIRED1, - RetiredSlotId::R2 => YKPIV_KEY_RETIRED2, - RetiredSlotId::R3 => YKPIV_KEY_RETIRED3, - RetiredSlotId::R4 => YKPIV_KEY_RETIRED4, - RetiredSlotId::R5 => YKPIV_KEY_RETIRED5, - RetiredSlotId::R6 => YKPIV_KEY_RETIRED6, - RetiredSlotId::R7 => YKPIV_KEY_RETIRED7, - RetiredSlotId::R8 => YKPIV_KEY_RETIRED8, - RetiredSlotId::R9 => YKPIV_KEY_RETIRED9, - RetiredSlotId::R10 => YKPIV_KEY_RETIRED10, - RetiredSlotId::R11 => YKPIV_KEY_RETIRED11, - RetiredSlotId::R12 => YKPIV_KEY_RETIRED12, - RetiredSlotId::R13 => YKPIV_KEY_RETIRED13, - RetiredSlotId::R14 => YKPIV_KEY_RETIRED14, - RetiredSlotId::R15 => YKPIV_KEY_RETIRED15, - RetiredSlotId::R16 => YKPIV_KEY_RETIRED16, - RetiredSlotId::R17 => YKPIV_KEY_RETIRED17, - RetiredSlotId::R18 => YKPIV_KEY_RETIRED18, - RetiredSlotId::R19 => YKPIV_KEY_RETIRED19, - RetiredSlotId::R20 => YKPIV_KEY_RETIRED20, + RetiredSlotId::R1 => 0x82, + RetiredSlotId::R2 => 0x83, + RetiredSlotId::R3 => 0x84, + RetiredSlotId::R4 => 0x85, + RetiredSlotId::R5 => 0x86, + RetiredSlotId::R6 => 0x87, + RetiredSlotId::R7 => 0x88, + RetiredSlotId::R8 => 0x89, + RetiredSlotId::R9 => 0x8a, + RetiredSlotId::R10 => 0x8b, + RetiredSlotId::R11 => 0x8c, + RetiredSlotId::R12 => 0x8d, + RetiredSlotId::R13 => 0x8e, + RetiredSlotId::R14 => 0x8f, + RetiredSlotId::R15 => 0x90, + RetiredSlotId::R16 => 0x91, + RetiredSlotId::R17 => 0x92, + RetiredSlotId::R18 => 0x93, + RetiredSlotId::R19 => 0x94, + RetiredSlotId::R20 => 0x95, } } } @@ -221,26 +221,26 @@ impl RetiredSlotId { /// Returns the [`ObjectId`] that corresponds to a given [`RetiredSlotId`]. pub(crate) fn object_id(self) -> ObjectId { match self { - RetiredSlotId::R1 => YKPIV_OBJ_RETIRED1, - RetiredSlotId::R2 => YKPIV_OBJ_RETIRED2, - RetiredSlotId::R3 => YKPIV_OBJ_RETIRED3, - RetiredSlotId::R4 => YKPIV_OBJ_RETIRED4, - RetiredSlotId::R5 => YKPIV_OBJ_RETIRED5, - RetiredSlotId::R6 => YKPIV_OBJ_RETIRED6, - RetiredSlotId::R7 => YKPIV_OBJ_RETIRED7, - RetiredSlotId::R8 => YKPIV_OBJ_RETIRED8, - RetiredSlotId::R9 => YKPIV_OBJ_RETIRED9, - RetiredSlotId::R10 => YKPIV_OBJ_RETIRED10, - RetiredSlotId::R11 => YKPIV_OBJ_RETIRED11, - RetiredSlotId::R12 => YKPIV_OBJ_RETIRED12, - RetiredSlotId::R13 => YKPIV_OBJ_RETIRED13, - RetiredSlotId::R14 => YKPIV_OBJ_RETIRED14, - RetiredSlotId::R15 => YKPIV_OBJ_RETIRED15, - RetiredSlotId::R16 => YKPIV_OBJ_RETIRED16, - RetiredSlotId::R17 => YKPIV_OBJ_RETIRED17, - RetiredSlotId::R18 => YKPIV_OBJ_RETIRED18, - RetiredSlotId::R19 => YKPIV_OBJ_RETIRED19, - RetiredSlotId::R20 => YKPIV_OBJ_RETIRED20, + RetiredSlotId::R1 => 0x005f_c10d, + RetiredSlotId::R2 => 0x005f_c10e, + RetiredSlotId::R3 => 0x005f_c10f, + RetiredSlotId::R4 => 0x005f_c110, + RetiredSlotId::R5 => 0x005f_c111, + RetiredSlotId::R6 => 0x005f_c112, + RetiredSlotId::R7 => 0x005f_c113, + RetiredSlotId::R8 => 0x005f_c114, + RetiredSlotId::R9 => 0x005f_c115, + RetiredSlotId::R10 => 0x005f_c116, + RetiredSlotId::R11 => 0x005f_c117, + RetiredSlotId::R12 => 0x005f_c118, + RetiredSlotId::R13 => 0x005f_c119, + RetiredSlotId::R14 => 0x005f_c11a, + RetiredSlotId::R15 => 0x005f_c11b, + RetiredSlotId::R16 => 0x005f_c11c, + RetiredSlotId::R17 => 0x005f_c11d, + RetiredSlotId::R18 => 0x005f_c11e, + RetiredSlotId::R19 => 0x005f_c11f, + RetiredSlotId::R20 => 0x005f_c120, } } } From bc95d8b7b91497a2a71d91f5951921043ab22f30 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Sat, 30 Nov 2019 22:18:31 +0000 Subject: [PATCH 5/5] Delete unnecessary commented-out code We will handle the CardManagement slot separately. --- src/yubikey.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/yubikey.rs b/src/yubikey.rs index eba6e04..74e6097 100644 --- a/src/yubikey.rs +++ b/src/yubikey.rs @@ -611,12 +611,6 @@ impl YubiKey { let mut key_data = Zeroizing::new(vec![0u8; 1024]); let templ = [0, Ins::ImportKey.code(), algorithm.into(), key.into()]; - // Only slot we want to exclude is CardManagement, which isn't in the enum. - // TODO: Decide whether to add it or not. - // match key { - // SlotId::CardManagement => return Err(Error::KeyError), - // } - if pin_policy != YKPIV_PINPOLICY_DEFAULT && pin_policy != YKPIV_PINPOLICY_NEVER && pin_policy != YKPIV_PINPOLICY_ONCE