use std::{fmt, str};
use std::ops::{Deref, DerefMut};
use failure::Error;
use serde::ser::{Serialize, Serializer};
use serde::de::{self, Deserialize, Deserializer, SeqAccess, Visitor};
pub const LABEL_SIZE: usize = 40;
pub type Id = u16;
pub type SequenceId = u8;
pub struct Label(pub [u8; LABEL_SIZE]);
impl Label {
pub fn new(label_slice: &[u8]) -> Result<Self, Error> {
if label_slice.len() > LABEL_SIZE {
bail!(
"label too long: {}-bytes (max {})",
label_slice.len(),
LABEL_SIZE
);
}
let mut bytes = [0u8; LABEL_SIZE];
bytes[..label_slice.len()].copy_from_slice(label_slice);
Ok(Label(bytes))
}
pub fn to_string(&self) -> Result<String, Error> {
let mut string = str::from_utf8(&self.0)?.to_owned();
if let Some(pos) = string.find('\0') {
string.truncate(pos);
}
Ok(string)
}
}
impl AsRef<[u8]> for Label {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
impl Clone for Label {
fn clone(&self) -> Self {
Self::new(self.as_ref()).unwrap()
}
}
impl fmt::Debug for Label {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let string = self.to_string()
.unwrap_or_else(|_| "[INVALID UTF-8 CHARACTER IN LABEL]".to_owned());
write!(f, "{:?}", string)
}
}
impl<'a> From<&'a str> for Label {
fn from(string: &'a str) -> Self {
Self::new(string.as_bytes()).unwrap()
}
}
impl PartialEq for Label {
fn eq(&self, other: &Self) -> bool {
self.0.as_ref() == other.0.as_ref()
}
}
impl Deref for Label {
type Target = [u8; LABEL_SIZE];
fn deref(&self) -> &[u8; LABEL_SIZE] {
&self.0
}
}
impl DerefMut for Label {
fn deref_mut(&mut self) -> &mut [u8; LABEL_SIZE] {
&mut self.0
}
}
impl Serialize for Label {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.0.serialize(serializer)
}
}
impl<'de> Deserialize<'de> for Label {
fn deserialize<D>(deserializer: D) -> Result<Label, D::Error>
where
D: Deserializer<'de>,
{
struct LabelVisitor;
impl<'de> Visitor<'de> for LabelVisitor {
type Value = Label;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("40-byte string of arbitrary bytes")
}
fn visit_seq<S>(self, mut seq: S) -> Result<Label, S::Error>
where
S: SeqAccess<'de>,
{
let mut label = [0; LABEL_SIZE];
for elem in label.iter_mut().take(LABEL_SIZE) {
match seq.next_element()? {
Some(val) => *elem = val,
None => return Err(de::Error::custom("end of stream")),
};
}
Ok(Label(label))
}
}
deserializer.deserialize_seq(LabelVisitor)
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Origin {
Generated = 0x01,
Imported = 0x02,
WrappedGenerated = 0x11,
WrappedImported = 0x12,
}
impl Origin {
pub fn from_u8(byte: u8) -> Result<Self, Error> {
Ok(match byte {
0x01 => Origin::Generated,
0x02 => Origin::Imported,
0x11 => Origin::WrappedGenerated,
0x12 => Origin::WrappedImported,
_ => bail!("invalid object origin: {}", byte),
})
}
pub fn to_u8(&self) -> u8 {
*self as u8
}
}
impl Serialize for Origin {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_u8(self.to_u8())
}
}
impl<'de> Deserialize<'de> for Origin {
fn deserialize<D>(deserializer: D) -> Result<Origin, D::Error>
where
D: Deserializer<'de>,
{
struct OriginVisitor;
impl<'de> Visitor<'de> for OriginVisitor {
type Value = Origin;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("an unsigned byte between 0x01 and 0x07")
}
fn visit_u8<E>(self, value: u8) -> Result<Origin, E>
where
E: de::Error,
{
Origin::from_u8(value).or_else(|e| Err(E::custom(format!("{}", e))))
}
}
deserializer.deserialize_u8(OriginVisitor)
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Type {
Opaque = 0x01,
AuthKey = 0x02,
Asymmetric = 0x03,
WrapKey = 0x04,
HMACKey = 0x05,
Template = 0x06,
OTPAEADKey = 0x07,
}
impl Type {
pub fn from_u8(byte: u8) -> Result<Self, Error> {
Ok(match byte {
0x01 => Type::Opaque,
0x02 => Type::AuthKey,
0x03 => Type::Asymmetric,
0x04 => Type::WrapKey,
0x05 => Type::HMACKey,
0x06 => Type::Template,
0x07 => Type::OTPAEADKey,
_ => bail!("invalid object type: {}", byte),
})
}
pub fn to_u8(&self) -> u8 {
*self as u8
}
}
impl Serialize for Type {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_u8(self.to_u8())
}
}
impl<'de> Deserialize<'de> for Type {
fn deserialize<D>(deserializer: D) -> Result<Type, D::Error>
where
D: Deserializer<'de>,
{
struct TypeVisitor;
impl<'de> Visitor<'de> for TypeVisitor {
type Value = Type;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("an unsigned byte between 0x01 and 0x07")
}
fn visit_u8<E>(self, value: u8) -> Result<Type, E>
where
E: de::Error,
{
Type::from_u8(value).or_else(|e| Err(E::custom(format!("{}", e))))
}
}
deserializer.deserialize_u8(TypeVisitor)
}
}