mirror of
https://github.com/trussed-dev/piv-authenticator.git
synced 2026-06-20 04:16:15 -07:00
Use macros to have one source of KeyReferences
This commit is contained in:
+17
-150
@@ -9,7 +9,13 @@ use core::convert::{TryFrom, TryInto};
|
||||
use iso7816::{Instruction, Status};
|
||||
|
||||
use crate::state::TouchPolicy;
|
||||
pub use crate::{container as containers, piv_types, Pin, Puk};
|
||||
pub use crate::{
|
||||
container::{
|
||||
self as containers, AuthenticateKeyReference, ChangeReferenceKeyReference,
|
||||
GenerateAsymmetricKeyReference, VerifyKeyReference,
|
||||
},
|
||||
piv_types, Pin, Puk,
|
||||
};
|
||||
|
||||
// https://developers.yubico.com/PIV/Introduction/Yubico_extensions.html
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
@@ -111,32 +117,6 @@ impl TryFrom<&[u8]> for GetData {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
#[repr(u8)]
|
||||
pub enum VerifyKeyReference {
|
||||
GlobalPin = 0x00,
|
||||
PivPin = 0x80,
|
||||
PrimaryFingerOcc = 0x96,
|
||||
SecondaryFingerOcc = 0x97,
|
||||
PairingCode = 0x98,
|
||||
}
|
||||
|
||||
impl TryFrom<u8> for VerifyKeyReference {
|
||||
type Error = Status;
|
||||
fn try_from(p2: u8) -> Result<Self, Self::Error> {
|
||||
// If the PIV Card Application does not contain the Discovery Object as described in Part 1,
|
||||
// then no other key reference shall be able to be verified by the PIV Card Application VERIFY command.
|
||||
match p2 {
|
||||
0x00 => Ok(Self::GlobalPin),
|
||||
0x80 => Ok(Self::PivPin),
|
||||
0x96 => Ok(Self::PrimaryFingerOcc),
|
||||
0x97 => Ok(Self::SecondaryFingerOcc),
|
||||
0x98 => Ok(Self::PairingCode),
|
||||
_ => Err(Status::KeyReferenceNotFound),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub struct VerifyLogout(bool);
|
||||
|
||||
@@ -179,7 +159,7 @@ impl TryFrom<VerifyArguments<'_>> for Verify {
|
||||
logout,
|
||||
data,
|
||||
} = arguments;
|
||||
if key_reference != VerifyKeyReference::PivPin {
|
||||
if key_reference != VerifyKeyReference::ApplicationPin {
|
||||
return Err(Status::FunctionNotSupported);
|
||||
}
|
||||
Ok(match (logout.0, data.len()) {
|
||||
@@ -195,26 +175,6 @@ impl TryFrom<VerifyArguments<'_>> for Verify {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
#[repr(u8)]
|
||||
pub enum ChangeReferenceKeyReference {
|
||||
GlobalPin = 0x00,
|
||||
PivPin = 0x80,
|
||||
Puk = 0x81,
|
||||
}
|
||||
|
||||
impl TryFrom<u8> for ChangeReferenceKeyReference {
|
||||
type Error = Status;
|
||||
fn try_from(p2: u8) -> Result<Self, Self::Error> {
|
||||
match p2 {
|
||||
0x00 => Ok(Self::GlobalPin),
|
||||
0x80 => Ok(Self::PivPin),
|
||||
0x81 => Ok(Self::Puk),
|
||||
_ => Err(Status::KeyReferenceNotFound),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub struct ChangeReferenceArguments<'l> {
|
||||
pub key_reference: ChangeReferenceKeyReference,
|
||||
@@ -238,21 +198,18 @@ impl TryFrom<ChangeReferenceArguments<'_>> for ChangeReference {
|
||||
use ChangeReferenceKeyReference::*;
|
||||
Ok(match (key_reference, data) {
|
||||
(GlobalPin, _) => return Err(Status::FunctionNotSupported),
|
||||
(PivPin, data) => ChangeReference::ChangePin {
|
||||
(ApplicationPin, data) => ChangeReference::ChangePin {
|
||||
old_pin: Pin::try_from(&data[..8]).map_err(|_| Status::IncorrectDataParameter)?,
|
||||
new_pin: Pin::try_from(&data[8..]).map_err(|_| Status::IncorrectDataParameter)?,
|
||||
},
|
||||
(Puk, data) => {
|
||||
use crate::commands::Puk;
|
||||
ChangeReference::ChangePuk {
|
||||
old_puk: Puk(data[..8]
|
||||
.try_into()
|
||||
.map_err(|_| Status::IncorrectDataParameter)?),
|
||||
new_puk: Puk(data[8..]
|
||||
.try_into()
|
||||
.map_err(|_| Status::IncorrectDataParameter)?),
|
||||
}
|
||||
}
|
||||
(PinUnblockingKey, data) => ChangeReference::ChangePuk {
|
||||
old_puk: Puk(data[..8]
|
||||
.try_into()
|
||||
.map_err(|_| Status::IncorrectDataParameter)?),
|
||||
new_puk: Puk(data[8..]
|
||||
.try_into()
|
||||
.map_err(|_| Status::IncorrectDataParameter)?),
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -276,72 +233,6 @@ impl TryFrom<&[u8]> for ResetPinRetries {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
#[repr(u8)]
|
||||
pub enum AuthenticateKeyReference {
|
||||
SecureMessaging = 0x04,
|
||||
Authentication = 0x9a,
|
||||
Administration = 0x9b,
|
||||
Signature = 0x9c,
|
||||
Management = 0x9d,
|
||||
CardAuthentication = 0x9e,
|
||||
Retired01 = 0x82,
|
||||
Retired02 = 0x83,
|
||||
Retired03 = 0x84,
|
||||
Retired04 = 0x85,
|
||||
Retired05 = 0x86,
|
||||
Retired06 = 0x87,
|
||||
Retired07 = 0x88,
|
||||
Retired08 = 0x89,
|
||||
Retired09 = 0x8A,
|
||||
Retired10 = 0x8B,
|
||||
Retired11 = 0x8C,
|
||||
Retired12 = 0x8D,
|
||||
Retired13 = 0x8E,
|
||||
Retired14 = 0x8F,
|
||||
Retired15 = 0x90,
|
||||
Retired16 = 0x91,
|
||||
Retired17 = 0x92,
|
||||
Retired18 = 0x93,
|
||||
Retired19 = 0x94,
|
||||
Retired20 = 0x95,
|
||||
}
|
||||
|
||||
impl TryFrom<u8> for AuthenticateKeyReference {
|
||||
type Error = Status;
|
||||
fn try_from(p2: u8) -> Result<Self, Self::Error> {
|
||||
match p2 {
|
||||
0x04 => Ok(Self::SecureMessaging),
|
||||
0x9a => Ok(Self::Authentication),
|
||||
0x9b => Ok(Self::Administration),
|
||||
0x9c => Ok(Self::Signature),
|
||||
0x9d => Ok(Self::Management),
|
||||
0x9e => Ok(Self::CardAuthentication),
|
||||
0x82 => Ok(Self::Retired01),
|
||||
0x83 => Ok(Self::Retired02),
|
||||
0x84 => Ok(Self::Retired03),
|
||||
0x85 => Ok(Self::Retired04),
|
||||
0x86 => Ok(Self::Retired05),
|
||||
0x87 => Ok(Self::Retired06),
|
||||
0x88 => Ok(Self::Retired07),
|
||||
0x89 => Ok(Self::Retired08),
|
||||
0x8A => Ok(Self::Retired09),
|
||||
0x8B => Ok(Self::Retired10),
|
||||
0x8C => Ok(Self::Retired11),
|
||||
0x8D => Ok(Self::Retired12),
|
||||
0x8E => Ok(Self::Retired13),
|
||||
0x8F => Ok(Self::Retired14),
|
||||
0x90 => Ok(Self::Retired15),
|
||||
0x91 => Ok(Self::Retired16),
|
||||
0x92 => Ok(Self::Retired17),
|
||||
0x93 => Ok(Self::Retired18),
|
||||
0x94 => Ok(Self::Retired19),
|
||||
0x95 => Ok(Self::Retired20),
|
||||
_ => Err(Status::KeyReferenceNotFound),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub struct AuthenticateArguments<'l> {
|
||||
/// To allow the authenticator to have additional algorithms beyond NIST SP 800-78-4,
|
||||
@@ -361,30 +252,6 @@ impl TryFrom<&[u8]> for PutData {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
#[repr(u8)]
|
||||
pub enum GenerateAsymmetricKeyReference {
|
||||
SecureMessaging = 0x04,
|
||||
Authentication = 0x9a,
|
||||
Signature = 0x9c,
|
||||
Management = 0x9d,
|
||||
CardAuthentication = 0x9e,
|
||||
}
|
||||
|
||||
impl TryFrom<u8> for GenerateAsymmetricKeyReference {
|
||||
type Error = Status;
|
||||
fn try_from(p2: u8) -> Result<Self, Self::Error> {
|
||||
match p2 {
|
||||
0x04 => Err(Status::FunctionNotSupported),
|
||||
0x9a => Ok(Self::Authentication),
|
||||
0x9c => Ok(Self::Signature),
|
||||
0x9d => Ok(Self::Management),
|
||||
0x9e => Ok(Self::CardAuthentication),
|
||||
_ => Err(Status::KeyReferenceNotFound),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub struct GenerateAsymmetricArguments<'l> {
|
||||
pub key_reference: GenerateAsymmetricKeyReference,
|
||||
|
||||
+151
-33
@@ -2,6 +2,61 @@ use core::convert::TryFrom;
|
||||
|
||||
use hex_literal::hex;
|
||||
|
||||
macro_rules! enum_subset {
|
||||
(
|
||||
$(#[$outer:meta])*
|
||||
$vis:vis enum $name:ident: $sup:ident {
|
||||
$($var:ident),+
|
||||
$(,)*
|
||||
}
|
||||
) => {
|
||||
$(#[$outer])*
|
||||
#[repr(u8)]
|
||||
$vis enum $name {
|
||||
$(
|
||||
$var,
|
||||
)*
|
||||
}
|
||||
|
||||
impl TryFrom<$sup> for $name
|
||||
{
|
||||
type Error = ::iso7816::Status;
|
||||
fn try_from(val: $sup) -> ::core::result::Result<Self, Self::Error> {
|
||||
match val {
|
||||
$(
|
||||
$sup::$var => Ok($name::$var),
|
||||
)*
|
||||
_ => Err(::iso7816::Status::KeyReferenceNotFound)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<$name> for $sup
|
||||
{
|
||||
fn from(v: $name) -> $sup {
|
||||
match v {
|
||||
$(
|
||||
$name::$var => $sup::$var,
|
||||
)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<u8> for $name {
|
||||
type Error = ::iso7816::Status;
|
||||
fn try_from(tag: u8) -> ::core::result::Result<Self, Self::Error> {
|
||||
let v: $sup = tag.try_into()?;
|
||||
match v {
|
||||
$(
|
||||
$sup::$var => Ok($name::$var),
|
||||
)*
|
||||
_ => Err(::iso7816::Status::KeyReferenceNotFound)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Tag<'a>(&'a [u8]);
|
||||
impl<'a> Tag<'a> {
|
||||
pub fn new(slice: &'a [u8]) -> Self {
|
||||
@@ -12,45 +67,108 @@ impl<'a> Tag<'a> {
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub struct RetiredIndex(u8);
|
||||
|
||||
// #[repr(u8)]
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum KeyReference {
|
||||
GlobalPin,
|
||||
ApplicationPin,
|
||||
PinUnblockingKey,
|
||||
PrimaryFinger,
|
||||
SecondaryFinger,
|
||||
PairingCode,
|
||||
crate::enum_u8! {
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum KeyReference {
|
||||
GlobalPin = 0x00,
|
||||
SecureMessaging = 0x04,
|
||||
ApplicationPin = 0x80,
|
||||
PinUnblockingKey = 0x81,
|
||||
PrimaryFinger = 0x96,
|
||||
SecondaryFinger = 0x97,
|
||||
PairingCode = 0x98,
|
||||
|
||||
PivAuthentication,
|
||||
PivCardApplicationAdministration,
|
||||
DigitalSignature,
|
||||
KeyManagement,
|
||||
CardAuthentication,
|
||||
PivAuthentication = 0x9A,
|
||||
PivCardApplicationAdministration = 0x9B,
|
||||
DigitalSignature = 0x9C,
|
||||
KeyManagement = 0x9D,
|
||||
CardAuthentication = 0x9E,
|
||||
|
||||
// 20x
|
||||
RetiredKeyManagement(RetiredIndex),
|
||||
Retired01 = 0x82,
|
||||
Retired02 = 0x83,
|
||||
Retired03 = 0x84,
|
||||
Retired04 = 0x85,
|
||||
Retired05 = 0x86,
|
||||
Retired06 = 0x87,
|
||||
Retired07 = 0x88,
|
||||
Retired08 = 0x89,
|
||||
Retired09 = 0x8A,
|
||||
Retired10 = 0x8B,
|
||||
Retired11 = 0x8C,
|
||||
Retired12 = 0x8D,
|
||||
Retired13 = 0x8E,
|
||||
Retired14 = 0x8F,
|
||||
Retired15 = 0x90,
|
||||
Retired16 = 0x91,
|
||||
Retired17 = 0x92,
|
||||
Retired18 = 0x93,
|
||||
Retired19 = 0x94,
|
||||
Retired20 = 0x95,
|
||||
}
|
||||
}
|
||||
|
||||
impl From<KeyReference> for u8 {
|
||||
fn from(reference: KeyReference) -> Self {
|
||||
use KeyReference::*;
|
||||
match reference {
|
||||
GlobalPin => 0x00,
|
||||
ApplicationPin => 0x80,
|
||||
PinUnblockingKey => 0x81,
|
||||
PrimaryFinger => 0x96,
|
||||
SecondaryFinger => 0x97,
|
||||
PairingCode => 0x98,
|
||||
enum_subset! {
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum GenerateAsymmetricKeyReference: KeyReference {
|
||||
SecureMessaging,
|
||||
PivAuthentication,
|
||||
DigitalSignature,
|
||||
KeyManagement,
|
||||
CardAuthentication,
|
||||
}
|
||||
}
|
||||
|
||||
PivAuthentication => 0x9A,
|
||||
PivCardApplicationAdministration => 0x9B,
|
||||
DigitalSignature => 0x9C,
|
||||
KeyManagement => 0x9D,
|
||||
CardAuthentication => 0x9E,
|
||||
enum_subset! {
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum ChangeReferenceKeyReference: KeyReference {
|
||||
GlobalPin,
|
||||
ApplicationPin,
|
||||
PinUnblockingKey,
|
||||
}
|
||||
}
|
||||
|
||||
RetiredKeyManagement(RetiredIndex(i)) => (0x82 - 1) + i,
|
||||
}
|
||||
enum_subset! {
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum VerifyKeyReference: KeyReference {
|
||||
GlobalPin,
|
||||
ApplicationPin,
|
||||
PrimaryFinger,
|
||||
SecondaryFinger,
|
||||
PairingCode,
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
enum_subset! {
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum AuthenticateKeyReference: KeyReference {
|
||||
SecureMessaging,
|
||||
PivAuthentication,
|
||||
PivCardApplicationAdministration,
|
||||
DigitalSignature,
|
||||
KeyManagement,
|
||||
CardAuthentication,
|
||||
Retired01,
|
||||
Retired02,
|
||||
Retired03,
|
||||
Retired04,
|
||||
Retired05,
|
||||
Retired06,
|
||||
Retired07,
|
||||
Retired08,
|
||||
Retired09,
|
||||
Retired10,
|
||||
Retired11,
|
||||
Retired12,
|
||||
Retired13,
|
||||
Retired14,
|
||||
Retired15,
|
||||
Retired16,
|
||||
Retired17,
|
||||
Retired18,
|
||||
Retired19,
|
||||
Retired20,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -148,7 +148,7 @@ where
|
||||
}
|
||||
|
||||
Verify::Status(key_reference) => {
|
||||
if key_reference != commands::VerifyKeyReference::PivPin {
|
||||
if key_reference != commands::VerifyKeyReference::ApplicationPin {
|
||||
return Err(Status::FunctionNotSupported);
|
||||
}
|
||||
if self.state.runtime.app_security_status.pin_verified {
|
||||
|
||||
+3
-3
@@ -2,9 +2,9 @@ use core::convert::{TryFrom, TryInto};
|
||||
|
||||
use flexiber::Encodable;
|
||||
use hex_literal::hex;
|
||||
use iso7816::Status;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! enum_u8 {
|
||||
(
|
||||
$(#[$outer:meta])*
|
||||
@@ -22,13 +22,13 @@ macro_rules! enum_u8 {
|
||||
}
|
||||
|
||||
impl TryFrom<u8> for $name {
|
||||
type Error = Status;
|
||||
type Error = ::iso7816::Status;
|
||||
fn try_from(val: u8) -> Result<Self, Self::Error> {
|
||||
match val {
|
||||
$(
|
||||
$num => Ok($name::$var),
|
||||
)*
|
||||
_ => Err(Status::KeyReferenceNotFound)
|
||||
_ => Err(::iso7816::Status::KeyReferenceNotFound)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user