From 6a16c59567efb63461e219558e1b6328d0c6b0b8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 30 Nov 2019 12:08:21 -0800 Subject: [PATCH] Use `secrecy` crate for storing `CachedPin` The `SecretVec` type automatically handles zeroing and may prevent accidental exposure of the cached PIN via `Debug`. --- Cargo.toml | 1 + src/yubikey.rs | 21 ++++++++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a94ceb0..c073861 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,7 @@ hmac = "0.7" log = "0.4" pbkdf2 = "0.3" pcsc = "2" +secrecy = "0.5" sha-1 = "0.8" subtle = "2" zeroize = "1" diff --git a/src/yubikey.rs b/src/yubikey.rs index cedfc80..2daf3c7 100644 --- a/src/yubikey.rs +++ b/src/yubikey.rs @@ -40,13 +40,15 @@ use crate::{ metadata, mgm::MgmKey, serialization::*, - ObjectId, + Buffer, ObjectId, }; -use crate::{consts::*, error::Error, transaction::Transaction, Buffer}; +use crate::{consts::*, error::Error, transaction::Transaction}; #[cfg(feature = "untested")] use getrandom::getrandom; use log::{error, info, warn}; use pcsc::{Card, Context}; +#[cfg(feature = "untested")] +use secrecy::ExposeSecret; use std::fmt::{self, Display}; #[cfg(feature = "untested")] use std::{ @@ -63,6 +65,9 @@ pub const AID: [u8; 5] = [0xa0, 0x00, 0x00, 0x03, 0x08]; /// pub const MGMT_AID: [u8; 8] = [0xa0, 0x00, 0x00, 0x05, 0x27, 0x47, 0x11, 0x17]; +/// Cached YubiKey PIN +pub type CachedPin = secrecy::SecretVec; + /// YubiKey Serial Number #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] pub struct Serial(pub u32); @@ -118,7 +123,7 @@ impl Version { #[cfg_attr(not(feature = "untested"), allow(dead_code))] pub struct YubiKey { pub(crate) card: Card, - pub(crate) pin: Option, + pub(crate) pin: Option, pub(crate) is_neo: bool, pub(crate) version: Version, pub(crate) serial: Serial, @@ -228,8 +233,10 @@ impl YubiKey { pcsc::Disposition::ResetCard, )?; - // TODO(tarcieri): zeroize pin! - let pin = self.pin.clone(); + let pin = self + .pin + .as_ref() + .map(|p| Buffer::new(p.expose_secret().clone())); let txn = Transaction::new(&mut self.card)?; txn.select_application()?; @@ -388,7 +395,7 @@ impl YubiKey { } if !pin.is_empty() { - self.pin = Some(Buffer::new(pin.into())) + self.pin = Some(CachedPin::new(pin.into())) } Ok(()) @@ -445,7 +452,7 @@ impl YubiKey { } if !new_pin.is_empty() { - self.pin = Some(Buffer::new(new_pin.into())); + self.pin = Some(CachedPin::new(new_pin.into())); } Ok(())