Skip to content

Commit

Permalink
piv: Extract management key algorithm into a separate enum
Browse files Browse the repository at this point in the history
  • Loading branch information
str4d committed Jan 3, 2025
1 parent ccccbaa commit f658a78
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 16 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- `yubikey::certificate::SelfSigned`
- `yubikey::Error::CertificateBuilder`
- `yubikey::MgmAlgorithmId`

### Changed
- MSRV is now 1.81.
Expand All @@ -19,6 +20,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `rsa 0.10.0-pre.3`
- `sha2 0.11.0-pre.4`
- `x509-cert 0.3.0-pre.0`
- `yubikey::piv`:
- `ManagementAlgorithmId` has been renamed to `SlotAlgorithmId`, and its
`ThreeDes` variant has been replaced by `SlotAlgorithmId::Management`
containing a `yubikey::MgmAlgorithmId`.

## 0.8.0 (2023-08-15)
### Added
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ pub use crate::{
chuid::ChuId,
config::Config,
error::{Error, Result},
mgm::{MgmKey, MgmType},
mgm::{MgmAlgorithmId, MgmKey, MgmType},
piv::Key,
policy::{PinPolicy, TouchPolicy},
reader::Context,
Expand Down
26 changes: 26 additions & 0 deletions src/mgm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,32 @@ pub enum MgmType {
Protected = 2,
}

/// Management key algorithm identifiers
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum MgmAlgorithmId {
/// Triple DES (3DES) in EDE mode
ThreeDes,
}

impl TryFrom<u8> for MgmAlgorithmId {
type Error = Error;

fn try_from(value: u8) -> Result<Self> {
match value {
0x03 => Ok(MgmAlgorithmId::ThreeDes),
_ => Err(Error::AlgorithmError),
}
}
}

impl From<MgmAlgorithmId> for u8 {
fn from(id: MgmAlgorithmId) -> u8 {
match id {
MgmAlgorithmId::ThreeDes => 0x03,
}
}
}

/// Management Key (MGM).
///
/// This key is used to authenticate to the management applet running on
Expand Down
32 changes: 17 additions & 15 deletions src/piv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ use crate::{
certificate::{self, Certificate},
consts::CB_OBJ_MAX,
error::{Error, Result},
mgm::MgmAlgorithmId,
policy::{PinPolicy, TouchPolicy},
serialization::*,
setting,
Expand Down Expand Up @@ -945,7 +946,7 @@ pub fn metadata(yubikey: &mut YubiKey, slot: SlotId) -> Result<SlotMetadata> {
#[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
Expand All @@ -972,7 +973,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,
Expand All @@ -983,7 +984,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 => {
Expand Down Expand Up @@ -1015,7 +1016,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)?,
Expand Down Expand Up @@ -1215,33 +1216,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(),
}
}
}

0 comments on commit f658a78

Please sign in to comment.