Test Config::get

Tests reading configuration from a live device:

    Config { protected_data_available: false, puk_blocked: false, puk_noblock_on_upgrade: false, pin_last_changed: 0, mgm_type: Manual }
This commit is contained in:
Tony Arcieri
2019-12-07 11:40:25 -08:00
parent 509c438330
commit cdecfd92dd
7 changed files with 69 additions and 19 deletions
+14 -6
View File
@@ -32,10 +32,13 @@
use crate::{consts::*, error::Error, metadata, mgm::MgmType, yubikey::YubiKey};
use log::error;
use std::convert::TryInto;
use std::{
convert::TryInto,
time::{Duration, SystemTime, UNIX_EPOCH},
};
/// Config
#[derive(Copy, Clone)]
#[derive(Copy, Clone, Debug)]
pub struct Config {
/// Protected data available
protected_data_available: bool,
@@ -47,7 +50,7 @@ pub struct Config {
puk_noblock_on_upgrade: bool,
/// PIN last changed
pin_last_changed: u32,
pin_last_changed: Option<SystemTime>,
/// MGM type
mgm_type: MgmType,
@@ -60,7 +63,7 @@ impl Config {
protected_data_available: false,
puk_blocked: false,
puk_noblock_on_upgrade: false,
pin_last_changed: 0,
pin_last_changed: None,
mgm_type: MgmType::Manual,
};
@@ -93,8 +96,13 @@ impl Config {
if item.len() != CB_ADMIN_TIMESTAMP {
error!("pin timestamp in admin metadata is an invalid size");
} else {
// TODO(tarcieri): double check this is little endian
config.pin_last_changed = u32::from_le_bytes(item.try_into().unwrap());
// TODO(tarcieri): double-check endianness is correct
let pin_last_changed = u32::from_le_bytes(item.try_into().unwrap());
if pin_last_changed != 0 {
config.pin_last_changed =
Some(UNIX_EPOCH + Duration::from_secs(pin_last_changed as u64));
}
}
}
}
-3
View File
@@ -141,16 +141,13 @@ pub mod cccid;
pub mod certificate;
#[cfg(feature = "untested")]
pub mod chuid;
#[cfg(feature = "untested")]
pub mod config;
pub mod consts;
#[cfg(feature = "untested")]
pub mod container;
pub mod error;
pub mod key;
#[cfg(feature = "untested")]
mod metadata;
#[cfg(feature = "untested")]
pub mod mgm;
#[cfg(feature = "untested")]
pub mod msroots;
+5
View File
@@ -31,6 +31,8 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
use crate::{consts::*, error::Error, serialization::*, transaction::Transaction, Buffer};
#[cfg(feature = "untested")]
use zeroize::Zeroizing;
/// Get metadata item
@@ -64,6 +66,7 @@ pub(crate) fn get_item(data: &[u8], tag: u8) -> Result<&[u8], Error> {
}
/// Set metadata item
#[cfg(feature = "untested")]
pub(crate) fn set_item(
data: &mut [u8],
pcb_data: &mut usize,
@@ -191,6 +194,7 @@ pub(crate) fn read(txn: &Transaction<'_>, tag: u8) -> Result<Buffer, Error> {
}
/// Write metadata
#[cfg(feature = "untested")]
pub(crate) fn write(txn: &Transaction<'_>, tag: u8, data: &[u8]) -> Result<(), Error> {
let mut buf = Zeroizing::new(vec![0u8; CB_OBJ_MAX]);
@@ -218,6 +222,7 @@ pub(crate) fn write(txn: &Transaction<'_>, tag: u8, data: &[u8]) -> Result<(), E
}
/// Get the size of a length tag for the given length
#[cfg(feature = "untested")]
fn get_length_size(length: usize) -> usize {
if length < 0x80 {
1
+18 -6
View File
@@ -30,18 +30,25 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
use crate::{consts::*, error::Error, metadata, yubikey::YubiKey};
use crate::{consts::*, error::Error};
use getrandom::getrandom;
use log::error;
use std::convert::{TryFrom, TryInto};
use zeroize::{Zeroize, Zeroizing};
#[cfg(feature = "untested")]
use crate::{metadata, yubikey::YubiKey};
#[cfg(feature = "untested")]
use des::{
block_cipher_trait::{generic_array::GenericArray, BlockCipher},
TdesEde3,
};
use getrandom::getrandom;
#[cfg(feature = "untested")]
use hmac::Hmac;
use log::error;
#[cfg(feature = "untested")]
use pbkdf2::pbkdf2;
#[cfg(feature = "untested")]
use sha1::Sha1;
use std::convert::{TryFrom, TryInto};
use zeroize::{Zeroize, Zeroizing};
/// Default MGM key configured on all YubiKeys
const DEFAULT_MGM_KEY: [u8; DES_LEN_3DES] = [
@@ -50,7 +57,6 @@ const DEFAULT_MGM_KEY: [u8; DES_LEN_3DES] = [
/// Management Key (MGM) key types (manual/derived/protected)
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[allow(non_camel_case_types)]
pub enum MgmType {
/// Manual
Manual = 0,
@@ -107,6 +113,7 @@ impl MgmKey {
}
/// Get derived management key (MGM)
#[cfg(feature = "untested")]
pub fn get_derived(yubikey: &mut YubiKey, pin: &[u8]) -> Result<Self, Error> {
let txn = yubikey.begin_transaction()?;
@@ -131,6 +138,7 @@ impl MgmKey {
}
/// Get protected management key (MGM)
#[cfg(feature = "untested")]
pub fn get_protected(yubikey: &mut YubiKey) -> Result<Self, Error> {
let txn = yubikey.begin_transaction()?;
@@ -158,12 +166,14 @@ impl MgmKey {
}
/// Set the management key (MGM)
#[cfg(feature = "untested")]
pub fn set(&self, yubikey: &mut YubiKey, touch: Option<u8>) -> Result<(), Error> {
let txn = yubikey.begin_transaction()?;
txn.set_mgm_key(&self, touch)
}
/// Set protected management key (MGM)
#[cfg(feature = "untested")]
pub fn set_protected(&self, yubikey: &mut YubiKey) -> Result<(), Error> {
let mut data = Zeroizing::new(vec![0u8; CB_BUF_MAX]);
@@ -254,6 +264,7 @@ impl MgmKey {
}
/// Encrypt with 3DES key
#[cfg(feature = "untested")]
#[allow(clippy::trivially_copy_pass_by_ref)]
pub(crate) fn encrypt(&self, input: &[u8; DES_LEN_DES]) -> [u8; DES_LEN_DES] {
let mut output = input.to_owned();
@@ -263,6 +274,7 @@ impl MgmKey {
}
/// Decrypt with 3DES key
#[cfg(feature = "untested")]
#[allow(clippy::trivially_copy_pass_by_ref)]
pub(crate) fn decrypt(&self, input: &[u8; DES_LEN_DES]) -> [u8; DES_LEN_DES] {
let mut output = input.to_owned();
+6
View File
@@ -31,6 +31,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
use crate::{
config::Config,
error::Error,
readers::{Reader, Readers},
transaction::Transaction,
@@ -200,6 +201,11 @@ impl YubiKey {
self.serial
}
/// Get device configuration.
pub fn config(&mut self) -> Result<Config, Error> {
Config::get(self)
}
/// Authenticate to the card using the provided management key (MGM).
#[cfg(feature = "untested")]
pub fn authenticate(&mut self, mgm_key: MgmKey) -> Result<(), Error> {