yubikey 0.7.0

Pure Rust cross-platform host-side driver for YubiKey devices from Yubico with support for hardware-backed public-key decryption and digital signatures using the Personal Identity Verification (PIV) application. Supports RSA (1024/2048) or ECC (NIST P-256/P-384) algorithms e.g, PKCS#1v1.5, ECDSA
Documentation
//! Enums representing key policies.

use crate::{serialization::Tlv, Error, Result};

/// Specifies how often the PIN needs to be entered for access to the credential in a
/// given slot.
///
/// This policy must be set when keys are generated or imported, and cannot be changed later.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum PinPolicy {
    /// Use the default PIN policy for the slot. See the slot's documentation for details.
    Default,

    /// The end user PIN is **NOT** required to perform private key operations.
    Never,

    /// The end user PIN is required to perform any private key operations. Once the
    /// correct PIN has been provided, multiple private key operations may be performed
    /// without additional cardholder consent.
    Once,

    /// The end user PIN is required to perform any private key operations. The PIN must
    /// be submitted immediately before each operation to ensure cardholder participation.
    Always,
}

impl From<PinPolicy> for u8 {
    fn from(policy: PinPolicy) -> u8 {
        match policy {
            PinPolicy::Default => 0,
            PinPolicy::Never => 1,
            PinPolicy::Once => 2,
            PinPolicy::Always => 3,
        }
    }
}

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

    fn try_from(value: u8) -> Result<Self> {
        match value {
            0 => Ok(PinPolicy::Default),
            1 => Ok(PinPolicy::Never),
            2 => Ok(PinPolicy::Once),
            3 => Ok(PinPolicy::Always),
            _ => Err(Error::GenericError),
        }
    }
}

impl PinPolicy {
    /// Writes the `PinPolicy` in the format the YubiKey expects during key generation or
    /// importation.
    pub(crate) fn write(self, buf: &mut [u8]) -> Result<usize> {
        match self {
            PinPolicy::Default => Ok(0),
            _ => Tlv::write(buf, 0xaa, &[self.into()]),
        }
    }
}

/// Specifies under what conditions a physical touch on the metal contact is required, in
/// addition to the [`PinPolicy`].
///
/// This policy must be set when keys are generated or imported, and cannot be changed later.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum TouchPolicy {
    /// Use the default touch policy for the slot.
    Default,

    /// A physical touch is **NOT** required to perform private key operations.
    Never,

    /// A physical touch is required to perform any private key operations. The metal
    /// contact must be touched during each operation to ensure cardholder participation.
    Always,

    /// A physical touch is required to perform any private key operations. Each touch
    /// is cached for 15 seconds, during which time multiple private key operations may be
    /// performed without additional cardholder interaction. After 15 seconds the cached
    /// touch is cleared, and further operations require another physical touch.
    Cached,
}

impl From<TouchPolicy> for u8 {
    fn from(policy: TouchPolicy) -> u8 {
        match policy {
            TouchPolicy::Default => 0,
            TouchPolicy::Never => 1,
            TouchPolicy::Always => 2,
            TouchPolicy::Cached => 3,
        }
    }
}

impl TouchPolicy {
    /// Writes the `TouchPolicy` in the format the YubiKey expects during key generation
    /// or importation.
    pub(crate) fn write(self, buf: &mut [u8]) -> Result<usize> {
        match self {
            TouchPolicy::Default => Ok(0),
            _ => Tlv::write(buf, 0xab, &[self.into()]),
        }
    }
}

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

    fn try_from(value: u8) -> Result<Self> {
        match value {
            0 => Ok(TouchPolicy::Default),
            1 => Ok(TouchPolicy::Never),
            2 => Ok(TouchPolicy::Always),
            3 => Ok(TouchPolicy::Cached),
            _ => Err(Error::GenericError),
        }
    }
}