Clean up some of the management key code (#584)
* mgm: Move TDES weak key checking code into a submodule * piv: Extract management key algorithm into a separate enum * mgm: Check management key algorithm when fetching from Yubikey
This commit is contained in:
+21
-30
@@ -45,8 +45,8 @@
|
||||
use crate::{
|
||||
apdu::{Ins, StatusWords},
|
||||
certificate::{self, Certificate},
|
||||
consts::CB_OBJ_MAX,
|
||||
error::{Error, Result},
|
||||
mgm::MgmAlgorithmId,
|
||||
policy::{PinPolicy, TouchPolicy},
|
||||
serialization::*,
|
||||
setting,
|
||||
@@ -74,6 +74,9 @@ use {
|
||||
#[cfg(feature = "untested")]
|
||||
use zeroize::Zeroizing;
|
||||
|
||||
#[cfg(feature = "untested")]
|
||||
use crate::consts::CB_OBJ_MAX;
|
||||
|
||||
/// PIV Applet Name
|
||||
pub(crate) const APPLET_NAME: &str = "PIV";
|
||||
|
||||
@@ -924,28 +927,15 @@ pub fn decrypt_data(
|
||||
/// Read metadata
|
||||
pub fn metadata(yubikey: &mut YubiKey, slot: SlotId) -> Result<SlotMetadata> {
|
||||
let txn = yubikey.begin_transaction()?;
|
||||
let templ = [0, Ins::GetMetadata.code(), 0, slot.into()];
|
||||
|
||||
let response = txn.transfer_data(&templ, &[], CB_OBJ_MAX)?;
|
||||
|
||||
if !response.is_success() {
|
||||
if response.status_words() == StatusWords::NotSupportedError {
|
||||
return Err(Error::NotSupported); // Requires firmware 5.2.3
|
||||
} else {
|
||||
return Err(Error::GenericError);
|
||||
}
|
||||
}
|
||||
|
||||
let buf = Buffer::new(response.data().into());
|
||||
|
||||
SlotMetadata::try_from(buf)
|
||||
txn.get_metadata(slot)
|
||||
}
|
||||
|
||||
/// Metadata from a slot
|
||||
#[derive(Debug)]
|
||||
pub struct SlotMetadata {
|
||||
/// Algorithm / Type of key
|
||||
pub algorithm: ManagementAlgorithmId,
|
||||
pub algorithm: SlotAlgorithmId,
|
||||
/// PIN and touch policy
|
||||
pub policy: Option<(PinPolicy, TouchPolicy)>,
|
||||
/// Imported or generated key
|
||||
@@ -972,7 +962,7 @@ impl TryFrom<Buffer> for SlotMetadata {
|
||||
|input| Tlv::parse(input).map_err(|_| nom::Err::Error(())),
|
||||
|| {
|
||||
Ok(SlotMetadata {
|
||||
algorithm: ManagementAlgorithmId::PinPuk,
|
||||
algorithm: SlotAlgorithmId::PinPuk,
|
||||
policy: None,
|
||||
origin: None,
|
||||
public: None,
|
||||
@@ -983,7 +973,7 @@ impl TryFrom<Buffer> for SlotMetadata {
|
||||
|acc: Result<SlotMetadata>, tlv| match acc {
|
||||
Ok(mut metadata) => match tlv.tag {
|
||||
1 => {
|
||||
metadata.algorithm = ManagementAlgorithmId::try_from(tlv.value[0])?;
|
||||
metadata.algorithm = SlotAlgorithmId::try_from(tlv.value[0])?;
|
||||
Ok(metadata)
|
||||
}
|
||||
2 => {
|
||||
@@ -1015,7 +1005,7 @@ impl TryFrom<Buffer> for SlotMetadata {
|
||||
}
|
||||
4 => {
|
||||
match metadata.algorithm {
|
||||
ManagementAlgorithmId::Asymmetric(alg) => {
|
||||
SlotAlgorithmId::Asymmetric(alg) => {
|
||||
metadata.public = Some(read_public_key(alg, tlv.value, false)?);
|
||||
}
|
||||
_ => Err(Error::ParseError)?,
|
||||
@@ -1215,33 +1205,34 @@ fn read_public_key(
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
/// Algorithms as reported by the metadata command.
|
||||
pub enum ManagementAlgorithmId {
|
||||
pub enum SlotAlgorithmId {
|
||||
/// Used on PIN and PUK slots.
|
||||
PinPuk,
|
||||
/// Used on the key management slot.
|
||||
ThreeDes,
|
||||
Management(MgmAlgorithmId),
|
||||
/// Used on all other slots.
|
||||
Asymmetric(AlgorithmId),
|
||||
}
|
||||
|
||||
impl TryFrom<u8> for ManagementAlgorithmId {
|
||||
impl TryFrom<u8> for SlotAlgorithmId {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(value: u8) -> Result<Self> {
|
||||
match value {
|
||||
0xff => Ok(ManagementAlgorithmId::PinPuk),
|
||||
0x03 => Ok(ManagementAlgorithmId::ThreeDes),
|
||||
oth => AlgorithmId::try_from(oth).map(ManagementAlgorithmId::Asymmetric),
|
||||
0xff => Ok(SlotAlgorithmId::PinPuk),
|
||||
oth => MgmAlgorithmId::try_from(oth)
|
||||
.map(SlotAlgorithmId::Management)
|
||||
.or_else(|_| AlgorithmId::try_from(oth).map(SlotAlgorithmId::Asymmetric)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ManagementAlgorithmId> for u8 {
|
||||
fn from(id: ManagementAlgorithmId) -> u8 {
|
||||
impl From<SlotAlgorithmId> for u8 {
|
||||
fn from(id: SlotAlgorithmId) -> u8 {
|
||||
match id {
|
||||
ManagementAlgorithmId::PinPuk => 0xff,
|
||||
ManagementAlgorithmId::ThreeDes => 0x03,
|
||||
ManagementAlgorithmId::Asymmetric(oth) => oth.into(),
|
||||
SlotAlgorithmId::PinPuk => 0xff,
|
||||
SlotAlgorithmId::Management(oth) => oth.into(),
|
||||
SlotAlgorithmId::Asymmetric(oth) => oth.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user