yubikey-cli 0.7.0

Command-line interface for performing encryption and signing using RSA/ECC keys stored on YubiKey devices.
Documentation
//! Print device status

use crate::terminal::{print_cert_info, STDOUT};
use clap::Parser;
use std::io::{self, Write};
use termcolor::{ColorSpec, StandardStreamLock, WriteColor};
use yubikey::{piv::*, YubiKey};

// String to use for `None`
const NONE_STR: &str = "<none>";

/// The `status` subcommand
#[derive(Debug, Parser)]
pub struct StatusCmd {}

impl StatusCmd {
    /// Run the `status` subcommand
    pub fn run(&self, mut yk: YubiKey) {
        let mut s = STDOUT.lock();
        s.reset().unwrap();

        self.attr(&mut s, "name", yk.name()).unwrap();
        self.attr(&mut s, "version", yk.version()).unwrap();
        self.attr(&mut s, "serial", yk.serial()).unwrap();

        if let Ok(chuid) = yk.chuid() {
            self.attr(&mut s, "CHUID", chuid).unwrap();
        } else {
            self.attr(&mut s, "CHUID", NONE_STR).unwrap();
        }

        if let Ok(chuid) = yk.cccid() {
            self.attr(&mut s, "CCC", chuid).unwrap();
        } else {
            self.attr(&mut s, "CCC", NONE_STR).unwrap();
        }

        self.attr(&mut s, "PIN retries", yk.get_pin_retries().unwrap())
            .unwrap();

        for slot in SLOTS.iter().cloned() {
            print_cert_info(&mut yk, slot, &mut s).unwrap();
        }
    }

    /// Print a status attribute
    fn attr(
        &self,
        stream: &mut StandardStreamLock<'_>,
        name: &str,
        value: impl ToString,
    ) -> io::Result<()> {
        stream.set_color(ColorSpec::new().set_bold(true))?;
        write!(stream, "{:>12}:", name)?;
        stream.reset()?;
        writeln!(stream, " {}", value.to_string())?;
        stream.flush()?;
        Ok(())
    }
}