Convert SlotId into an enum
This commit is contained in:
+4
-9
@@ -31,13 +31,8 @@
|
|||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
consts::*,
|
consts::*, error::Error, key::SlotId, serialization::*, transaction::Transaction,
|
||||||
error::Error,
|
yubikey::YubiKey, Buffer,
|
||||||
key::{self, SlotId},
|
|
||||||
serialization::*,
|
|
||||||
transaction::Transaction,
|
|
||||||
yubikey::YubiKey,
|
|
||||||
Buffer,
|
|
||||||
};
|
};
|
||||||
use log::error;
|
use log::error;
|
||||||
use zeroize::Zeroizing;
|
use zeroize::Zeroizing;
|
||||||
@@ -100,7 +95,7 @@ impl AsRef<[u8]> for Certificate {
|
|||||||
/// Read certificate
|
/// Read certificate
|
||||||
pub(crate) fn read_certificate(txn: &Transaction<'_>, slot: SlotId) -> Result<Buffer, Error> {
|
pub(crate) fn read_certificate(txn: &Transaction<'_>, slot: SlotId) -> Result<Buffer, Error> {
|
||||||
let mut len: usize = 0;
|
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) {
|
let mut buf = match txn.fetch_object(object_id) {
|
||||||
Ok(b) => b,
|
Ok(b) => b,
|
||||||
@@ -141,7 +136,7 @@ pub(crate) fn write_certificate(
|
|||||||
let mut buf = [0u8; CB_OBJ_MAX];
|
let mut buf = [0u8; CB_OBJ_MAX];
|
||||||
let mut offset = 0;
|
let mut offset = 0;
|
||||||
|
|
||||||
let object_id = key::slot_object(slot)?;
|
let object_id = slot.object_id();
|
||||||
|
|
||||||
if data.is_none() {
|
if data.is_none() {
|
||||||
return txn.save_object(object_id, &[]);
|
return txn.save_object(object_id, &[]);
|
||||||
|
|||||||
+3
-3
@@ -158,7 +158,7 @@ impl Container {
|
|||||||
|
|
||||||
Ok(Container {
|
Ok(Container {
|
||||||
name,
|
name,
|
||||||
slot: bytes[name_bytes_len],
|
slot: bytes[name_bytes_len].try_into()?,
|
||||||
key_spec: bytes[name_bytes_len + 1],
|
key_spec: bytes[name_bytes_len + 1],
|
||||||
key_size_bits: u16::from_le_bytes(
|
key_size_bits: u16::from_le_bytes(
|
||||||
bytes[(name_bytes_len + 2)..(name_bytes_len + 4)]
|
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.extend_from_slice(&self.name[i].to_le_bytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes.push(self.slot);
|
bytes.push(self.slot.into());
|
||||||
bytes.push(self.key_spec);
|
bytes.push(self.key_spec);
|
||||||
bytes.extend_from_slice(&self.key_size_bits.to_le_bytes());
|
bytes.extend_from_slice(&self.key_size_bits.to_le_bytes());
|
||||||
bytes.push(self.flags);
|
bytes.push(self.flags);
|
||||||
@@ -204,7 +204,7 @@ impl Debug for Container {
|
|||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
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: {:?} }}",
|
flags: {}, pin_id: {}, associated_echd_container: {}, cert_fingerprint: {:?} }}",
|
||||||
&self.name[..],
|
&self.name[..],
|
||||||
self.slot,
|
self.slot,
|
||||||
|
|||||||
+216
-43
@@ -48,56 +48,229 @@ use crate::{
|
|||||||
AlgorithmId, Buffer, ObjectId,
|
AlgorithmId, Buffer, ObjectId,
|
||||||
};
|
};
|
||||||
use log::{debug, error, warn};
|
use log::{debug, error, warn};
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
/// Slot identifiers.
|
/// Slot identifiers.
|
||||||
/// <https://developers.yubico.com/PIV/Introduction/Certificate_slots.html>
|
/// <https://developers.yubico.com/PIV/Introduction/Certificate_slots.html>
|
||||||
// TODO(tarcieri): replace these with enums
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub type SlotId = u8;
|
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`]
|
/// This certificate and its associated private key is used for digital signatures for
|
||||||
// TODO(tarcieri): factor this into a slot ID enum
|
/// the purpose of document signing, or signing files and executables. The end user
|
||||||
pub(crate) fn slot_object(slot: SlotId) -> Result<ObjectId, Error> {
|
/// PIN is required to perform any private key operations. The PIN must be submitted
|
||||||
let id = match slot {
|
/// every time immediately before a sign operation, to ensure cardholder participation
|
||||||
YKPIV_KEY_AUTHENTICATION => YKPIV_OBJ_AUTHENTICATION,
|
/// for every digital signature generated.
|
||||||
YKPIV_KEY_SIGNATURE => YKPIV_OBJ_SIGNATURE,
|
Signature,
|
||||||
YKPIV_KEY_KEYMGM => YKPIV_OBJ_KEY_MANAGEMENT,
|
|
||||||
YKPIV_KEY_CARDAUTH => YKPIV_OBJ_CARD_AUTH,
|
/// This certificate and its associated private key is used for encryption for the
|
||||||
YKPIV_KEY_ATTESTATION => YKPIV_OBJ_ATTESTATION,
|
/// purpose of confidentiality. This slot is used for things like encrypting e-mails
|
||||||
slot if slot >= YKPIV_KEY_RETIRED1 && (slot <= YKPIV_KEY_RETIRED20) => {
|
/// or files. The end user PIN is required to perform any private key operations. Once
|
||||||
YKPIV_OBJ_RETIRED1 + (slot - YKPIV_KEY_RETIRED1) as u32
|
/// 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,
|
||||||
}
|
}
|
||||||
_ => return Err(Error::InvalidObject),
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(id)
|
impl TryFrom<u8> for SlotId {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
||||||
|
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),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<SlotId> 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<u8> for RetiredSlotId {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
||||||
|
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<RetiredSlotId> 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
|
/// Personal Identity Verification (PIV) key slots
|
||||||
pub const SLOTS: [u8; 24] = [
|
pub const SLOTS: [SlotId; 24] = [
|
||||||
YKPIV_KEY_AUTHENTICATION,
|
SlotId::Authentication,
|
||||||
YKPIV_KEY_SIGNATURE,
|
SlotId::Signature,
|
||||||
YKPIV_KEY_KEYMGM,
|
SlotId::KeyManagement,
|
||||||
YKPIV_KEY_RETIRED1,
|
SlotId::Retired(RetiredSlotId::R1),
|
||||||
YKPIV_KEY_RETIRED2,
|
SlotId::Retired(RetiredSlotId::R2),
|
||||||
YKPIV_KEY_RETIRED3,
|
SlotId::Retired(RetiredSlotId::R3),
|
||||||
YKPIV_KEY_RETIRED4,
|
SlotId::Retired(RetiredSlotId::R4),
|
||||||
YKPIV_KEY_RETIRED5,
|
SlotId::Retired(RetiredSlotId::R5),
|
||||||
YKPIV_KEY_RETIRED6,
|
SlotId::Retired(RetiredSlotId::R6),
|
||||||
YKPIV_KEY_RETIRED7,
|
SlotId::Retired(RetiredSlotId::R7),
|
||||||
YKPIV_KEY_RETIRED8,
|
SlotId::Retired(RetiredSlotId::R8),
|
||||||
YKPIV_KEY_RETIRED9,
|
SlotId::Retired(RetiredSlotId::R9),
|
||||||
YKPIV_KEY_RETIRED10,
|
SlotId::Retired(RetiredSlotId::R10),
|
||||||
YKPIV_KEY_RETIRED11,
|
SlotId::Retired(RetiredSlotId::R11),
|
||||||
YKPIV_KEY_RETIRED12,
|
SlotId::Retired(RetiredSlotId::R12),
|
||||||
YKPIV_KEY_RETIRED13,
|
SlotId::Retired(RetiredSlotId::R13),
|
||||||
YKPIV_KEY_RETIRED14,
|
SlotId::Retired(RetiredSlotId::R14),
|
||||||
YKPIV_KEY_RETIRED15,
|
SlotId::Retired(RetiredSlotId::R15),
|
||||||
YKPIV_KEY_RETIRED16,
|
SlotId::Retired(RetiredSlotId::R16),
|
||||||
YKPIV_KEY_RETIRED17,
|
SlotId::Retired(RetiredSlotId::R17),
|
||||||
YKPIV_KEY_RETIRED18,
|
SlotId::Retired(RetiredSlotId::R18),
|
||||||
YKPIV_KEY_RETIRED19,
|
SlotId::Retired(RetiredSlotId::R19),
|
||||||
YKPIV_KEY_RETIRED20,
|
SlotId::Retired(RetiredSlotId::R20),
|
||||||
YKPIV_KEY_CARDAUTH,
|
SlotId::CardAuthentication,
|
||||||
];
|
];
|
||||||
|
|
||||||
/// PIV cryptographic keys stored in a YubiKey
|
/// PIV cryptographic keys stored in a YubiKey
|
||||||
@@ -120,7 +293,7 @@ impl Key {
|
|||||||
let buf = match certificate::read_certificate(&txn, slot) {
|
let buf = match certificate::read_certificate(&txn, slot) {
|
||||||
Ok(b) => b,
|
Ok(b) => b,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
debug!("error reading certificate in slot {}: {}", slot, e);
|
debug!("error reading certificate in slot {:?}: {}", slot, e);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -252,7 +425,7 @@ pub fn generate(
|
|||||||
|
|
||||||
let txn = yubikey.begin_transaction()?;
|
let txn = yubikey.begin_transaction()?;
|
||||||
|
|
||||||
templ[3] = slot;
|
templ[3] = slot.into();
|
||||||
|
|
||||||
let mut offset = 5;
|
let mut offset = 5;
|
||||||
in_data[..offset].copy_from_slice(&[
|
in_data[..offset].copy_from_slice(&[
|
||||||
|
|||||||
+3
-2
@@ -9,6 +9,7 @@ use crate::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
apdu::{Response, StatusWords},
|
apdu::{Response, StatusWords},
|
||||||
consts::*,
|
consts::*,
|
||||||
|
key::SlotId,
|
||||||
mgm::MgmKey,
|
mgm::MgmKey,
|
||||||
serialization::*,
|
serialization::*,
|
||||||
Buffer, ObjectId,
|
Buffer, ObjectId,
|
||||||
@@ -267,12 +268,12 @@ impl<'tx> Transaction<'tx> {
|
|||||||
&self,
|
&self,
|
||||||
sign_in: &[u8],
|
sign_in: &[u8],
|
||||||
algorithm: u8,
|
algorithm: u8,
|
||||||
key: u8,
|
key: SlotId,
|
||||||
decipher: bool,
|
decipher: bool,
|
||||||
) -> Result<Buffer, Error> {
|
) -> Result<Buffer, Error> {
|
||||||
let in_len = sign_in.len();
|
let in_len = sign_in.len();
|
||||||
let mut indata = [0u8; 1024];
|
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;
|
let mut len: usize = 0;
|
||||||
|
|
||||||
match algorithm {
|
match algorithm {
|
||||||
|
|||||||
+7
-9
@@ -609,15 +609,13 @@ impl YubiKey {
|
|||||||
touch_policy: u8,
|
touch_policy: u8,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let mut key_data = Zeroizing::new(vec![0u8; 1024]);
|
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
|
// Only slot we want to exclude is CardManagement, which isn't in the enum.
|
||||||
|| key < YKPIV_KEY_RETIRED1
|
// TODO: Decide whether to add it or not.
|
||||||
|| (key > YKPIV_KEY_RETIRED20 && key < YKPIV_KEY_AUTHENTICATION)
|
// match key {
|
||||||
|| (key > YKPIV_KEY_CARDAUTH && key != YKPIV_KEY_ATTESTATION)
|
// SlotId::CardManagement => return Err(Error::KeyError),
|
||||||
{
|
// }
|
||||||
return Err(Error::KeyError);
|
|
||||||
}
|
|
||||||
|
|
||||||
if pin_policy != YKPIV_PINPOLICY_DEFAULT
|
if pin_policy != YKPIV_PINPOLICY_DEFAULT
|
||||||
&& pin_policy != YKPIV_PINPOLICY_NEVER
|
&& pin_policy != YKPIV_PINPOLICY_NEVER
|
||||||
@@ -730,7 +728,7 @@ impl YubiKey {
|
|||||||
/// <https://developers.yubico.com/PIV/Introduction/PIV_attestation.html>
|
/// <https://developers.yubico.com/PIV/Introduction/PIV_attestation.html>
|
||||||
#[cfg(feature = "untested")]
|
#[cfg(feature = "untested")]
|
||||||
pub fn attest(&mut self, key: SlotId) -> Result<Buffer, Error> {
|
pub fn attest(&mut self, key: SlotId) -> Result<Buffer, Error> {
|
||||||
let templ = [0, Ins::Attest.code(), key, 0];
|
let templ = [0, Ins::Attest.code(), key.into(), 0];
|
||||||
let txn = self.begin_transaction()?;
|
let txn = self.begin_transaction()?;
|
||||||
let response = txn.transfer_data(&templ, &[], CB_OBJ_MAX)?;
|
let response = txn.transfer_data(&templ, &[], CB_OBJ_MAX)?;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user