Flatten API (#274)

Re-exports types from the toplevel instead of placing them in individual
modules (often which only contain one type).

This makes the API easier for users to navigate, while still retaining
the same module structure internally.

Additionally, this commit uses the `uuid` crate for modeling UUIDs.
This commit is contained in:
Tony Arcieri (iqlusion)
2021-07-12 08:40:31 -07:00
committed by GitHub
parent 1228d16439
commit 1765e11bc0
18 changed files with 263 additions and 283 deletions
+31 -59
View File
@@ -31,21 +31,13 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
use crate::{Error, Result, YubiKey};
use getrandom::getrandom;
use std::fmt::{self, Debug, Display};
use std::{
convert::TryInto,
fmt::{self, Debug, Display},
str,
};
use subtle_encoding::hex;
/// CHUID size
pub const CHUID_SIZE: usize = 59;
/// CARDID size
pub const CARDID_SIZE: usize = 16;
/// FASC-N component size
pub const FASCN_SIZE: usize = 25;
/// Expiration size
pub const EXPIRATION_SIZE: usize = 8;
use uuid::Uuid;
/// FASC-N offset
const CHUID_FASCN_OFFS: usize = 2;
@@ -81,46 +73,38 @@ const CHUID_TMPL: &[u8] = &[
0x30, 0x33, 0x30, 0x30, 0x31, 0x30, 0x31, 0x3e, 0x00, 0xfe, 0x00,
];
/// Cardholder Unique Identifier (CHUID) Card UUID/GUID value
/// Cardholder Unique Identifier (CHUID).
#[derive(Copy, Clone, Debug)]
pub struct Uuid(pub [u8; CARDID_SIZE]);
impl Uuid {
/// Generate a random Cardholder Unique Identifier (CHUID) UUID
pub fn generate() -> Result<Self> {
let mut id = [0u8; CARDID_SIZE];
getrandom(&mut id).map_err(|_| Error::RandomnessError)?;
Ok(Self(id))
}
}
/// Cardholder Unique Identifier (CHUID)
#[derive(Copy, Clone)]
pub struct ChuId(pub [u8; CHUID_SIZE]);
pub struct ChuId(pub [u8; Self::BYTE_SIZE]);
impl ChuId {
/// CHUID size in bytes
pub const BYTE_SIZE: usize = 59;
/// FASC-N component size
pub const FASCN_SIZE: usize = 25;
/// Expiration size
pub const EXPIRATION_SIZE: usize = 8;
/// Return FASC-N component of CHUID
pub fn fascn(&self) -> Result<[u8; FASCN_SIZE]> {
let mut fascn = [0u8; FASCN_SIZE];
fascn.copy_from_slice(&self.0[CHUID_FASCN_OFFS..(CHUID_FASCN_OFFS + FASCN_SIZE)]);
Ok(fascn)
pub fn fascn(&self) -> [u8; Self::FASCN_SIZE] {
self.0[CHUID_FASCN_OFFS..(CHUID_FASCN_OFFS + Self::FASCN_SIZE)]
.try_into()
.unwrap()
}
/// Return Card UUID/GUID component of CHUID
pub fn uuid(&self) -> Result<[u8; CARDID_SIZE]> {
let mut uuid = [0u8; CARDID_SIZE];
uuid.copy_from_slice(&self.0[CHUID_GUID_OFFS..(CHUID_GUID_OFFS + CARDID_SIZE)]);
Ok(uuid)
pub fn uuid(&self) -> Uuid {
Uuid::from_slice(&self.0[CHUID_GUID_OFFS..(CHUID_GUID_OFFS + 16)]).unwrap()
}
/// Return expiration date component of CHUID
// TODO(tarcieri): parse expiration?
pub fn expiration(&self) -> Result<[u8; EXPIRATION_SIZE]> {
let mut expiration = [0u8; EXPIRATION_SIZE];
expiration.copy_from_slice(
&self.0[CHUID_EXPIRATION_OFFS..(CHUID_EXPIRATION_OFFS + EXPIRATION_SIZE)],
);
Ok(expiration)
pub fn expiration(&self) -> [u8; Self::EXPIRATION_SIZE] {
self.0[CHUID_EXPIRATION_OFFS..(CHUID_EXPIRATION_OFFS + Self::EXPIRATION_SIZE)]
.try_into()
.unwrap()
}
/// Get Cardholder Unique Identifier (CHUID)
@@ -132,17 +116,15 @@ impl ChuId {
return Err(Error::GenericError);
}
let mut chuid = [0u8; CHUID_SIZE];
chuid.copy_from_slice(&response[0..CHUID_SIZE]);
let retval = ChuId { 0: chuid };
Ok(retval)
Ok(ChuId(response[..Self::BYTE_SIZE].try_into().unwrap()))
}
/// Set Cardholder Unique Identifier (CHUID)
#[cfg(feature = "untested")]
#[cfg_attr(docsrs, doc(cfg(feature = "untested")))]
pub fn set(&self, yubikey: &mut YubiKey) -> Result<()> {
let mut buf = CHUID_TMPL.to_vec();
buf[0..self.0.len()].copy_from_slice(&self.0);
buf[..Self::BYTE_SIZE].copy_from_slice(&self.0);
let txn = yubikey.begin_transaction()?;
txn.save_object(OBJ_CHUID, &buf)
@@ -151,16 +133,6 @@ impl ChuId {
impl Display for ChuId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}",
String::from_utf8(hex::encode(&self.0[..])).unwrap()
)
}
}
impl Debug for ChuId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "CHUID({:?})", &self.0[..])
write!(f, "{}", str::from_utf8(&hex::encode(&self.0[..])).unwrap())
}
}