use ciborium::value::Value;
#[allow(dead_code)]
#[repr(i64)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum EatClaimKey {
Iat = 6,
Nonce = 10,
Ueid = 256,
Sueids = 257,
OemId = 258,
HwModel = 259,
HwVersion = 260,
Uptime = 261,
OemBoot = 262,
DbgStat = 263,
Location = 264,
EatProfile = 265,
Submods = 266,
BootCount = 267,
BootSeed = 268,
Dloas = 269,
SwName = 270,
SwVersion = 271,
Manifests = 272,
Measurements = 273,
MeasRes = 274,
IntUse = 275,
}
impl From<EatClaimKey> for i64 {
fn from(k: EatClaimKey) -> i64 {
k as i64
}
}
#[derive(Clone, Debug, Default)]
pub struct EatClaimsSet {
pub iat: Option<i64>,
pub nonce: Option<Value>,
pub ueid: Option<Vec<u8>>,
pub sueids: Option<Value>,
pub oem_id: Option<Value>,
pub hw_model: Option<Vec<u8>>,
pub hw_version: Option<Value>,
pub uptime: Option<u64>,
pub oem_boot: Option<bool>,
pub dbg_stat: Option<u64>,
pub location: Option<Value>,
pub eat_profile: Option<String>,
pub submods: Option<Value>,
pub boot_count: Option<u64>,
pub boot_seed: Option<Vec<u8>>,
pub dloas: Option<Value>,
pub sw_name: Option<String>,
pub sw_version: Option<Value>,
pub manifests: Option<Value>,
pub measurements: Option<Value>,
pub meas_res: Option<Value>,
pub int_use: Option<u64>,
}
impl EatClaimsSet {
pub fn to_cbor_value(&self) -> Value {
let mut map: Vec<(Value, Value)> = Vec::new();
macro_rules! push_int {
($key:expr, $val:expr) => {
if let Some(v) = $val {
map.push((
Value::Integer(($key as i64).into()),
Value::Integer((v as i64).into()),
));
}
};
}
macro_rules! push_bool {
($key:expr, $val:expr) => {
if let Some(v) = $val {
map.push((Value::Integer(($key as i64).into()), Value::Bool(v)));
}
};
}
macro_rules! push_bytes {
($key:expr, $val:expr) => {
if let Some(ref v) = $val {
map.push((
Value::Integer(($key as i64).into()),
Value::Bytes(v.clone()),
));
}
};
}
macro_rules! push_text {
($key:expr, $val:expr) => {
if let Some(ref v) = $val {
map.push((Value::Integer(($key as i64).into()), Value::Text(v.clone())));
}
};
}
macro_rules! push_raw {
($key:expr, $val:expr) => {
if let Some(ref v) = $val {
map.push((Value::Integer(($key as i64).into()), v.clone()));
}
};
}
push_int!(EatClaimKey::Iat, self.iat);
push_raw!(EatClaimKey::Nonce, self.nonce);
push_bytes!(EatClaimKey::Ueid, self.ueid);
push_raw!(EatClaimKey::Sueids, self.sueids);
push_raw!(EatClaimKey::OemId, self.oem_id);
push_bytes!(EatClaimKey::HwModel, self.hw_model);
push_raw!(EatClaimKey::HwVersion, self.hw_version);
push_int!(EatClaimKey::Uptime, self.uptime);
push_bool!(EatClaimKey::OemBoot, self.oem_boot);
push_int!(EatClaimKey::DbgStat, self.dbg_stat);
push_raw!(EatClaimKey::Location, self.location);
push_text!(EatClaimKey::EatProfile, self.eat_profile);
push_raw!(EatClaimKey::Submods, self.submods);
push_int!(EatClaimKey::BootCount, self.boot_count);
push_bytes!(EatClaimKey::BootSeed, self.boot_seed);
push_raw!(EatClaimKey::Dloas, self.dloas);
push_text!(EatClaimKey::SwName, self.sw_name);
push_raw!(EatClaimKey::SwVersion, self.sw_version);
push_raw!(EatClaimKey::Manifests, self.manifests);
push_raw!(EatClaimKey::Measurements, self.measurements);
push_raw!(EatClaimKey::MeasRes, self.meas_res);
push_int!(EatClaimKey::IntUse, self.int_use);
Value::Map(map)
}
pub fn to_cbor_bytes(&self) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
let mut out = Vec::new();
ciborium::ser::into_writer(&self.to_cbor_value(), &mut out)?;
Ok(out)
}
pub fn from_cbor_value(value: &Value) -> Result<Self, Box<dyn std::error::Error>> {
let map = match value {
Value::Map(m) => m,
_ => return Err("Expected CBOR Map for EatClaimsSet".into()),
};
let mut claims = EatClaimsSet::default();
for (k, v) in map {
let key_int = match k {
Value::Integer(i) => i128::from(*i) as i64,
_ => continue,
};
match key_int {
x if x == EatClaimKey::Iat as i64 => {
if let Value::Integer(i) = v {
claims.iat = Some(i128::from(*i) as i64);
}
}
x if x == EatClaimKey::Nonce as i64 => {
claims.nonce = Some(v.clone());
}
x if x == EatClaimKey::Ueid as i64 => {
if let Value::Bytes(b) = v {
claims.ueid = Some(b.clone());
}
}
x if x == EatClaimKey::Sueids as i64 => {
claims.sueids = Some(v.clone());
}
x if x == EatClaimKey::OemId as i64 => {
claims.oem_id = Some(v.clone());
}
x if x == EatClaimKey::HwModel as i64 => {
if let Value::Bytes(b) = v {
claims.hw_model = Some(b.clone());
}
}
x if x == EatClaimKey::HwVersion as i64 => {
claims.hw_version = Some(v.clone());
}
x if x == EatClaimKey::Uptime as i64 => {
if let Value::Integer(i) = v {
claims.uptime = Some(i128::from(*i) as u64);
}
}
x if x == EatClaimKey::OemBoot as i64 => {
if let Value::Bool(b) = v {
claims.oem_boot = Some(*b);
}
}
x if x == EatClaimKey::DbgStat as i64 => {
if let Value::Integer(i) = v {
claims.dbg_stat = Some(i128::from(*i) as u64);
}
}
x if x == EatClaimKey::Location as i64 => {
claims.location = Some(v.clone());
}
x if x == EatClaimKey::EatProfile as i64 => {
if let Value::Text(s) = v {
claims.eat_profile = Some(s.clone());
}
}
x if x == EatClaimKey::Submods as i64 => {
claims.submods = Some(v.clone());
}
x if x == EatClaimKey::BootCount as i64 => {
if let Value::Integer(i) = v {
claims.boot_count = Some(i128::from(*i) as u64);
}
}
x if x == EatClaimKey::BootSeed as i64 => {
if let Value::Bytes(b) = v {
claims.boot_seed = Some(b.clone());
}
}
x if x == EatClaimKey::Dloas as i64 => {
claims.dloas = Some(v.clone());
}
x if x == EatClaimKey::SwName as i64 => {
if let Value::Text(s) = v {
claims.sw_name = Some(s.clone());
}
}
x if x == EatClaimKey::SwVersion as i64 => {
claims.sw_version = Some(v.clone());
}
x if x == EatClaimKey::Manifests as i64 => {
claims.manifests = Some(v.clone());
}
x if x == EatClaimKey::Measurements as i64 => {
claims.measurements = Some(v.clone());
}
x if x == EatClaimKey::MeasRes as i64 => {
claims.meas_res = Some(v.clone());
}
x if x == EatClaimKey::IntUse as i64 => {
if let Value::Integer(i) = v {
claims.int_use = Some(i128::from(*i) as u64);
}
}
_ => {}
}
}
Ok(claims)
}
pub fn from_cbor_bytes(bytes: &[u8]) -> Result<Self, Box<dyn std::error::Error>> {
let value: Value = ciborium::de::from_reader(bytes)?;
Self::from_cbor_value(&value)
}
pub fn from_bytes(bytes: &[u8]) -> Result<Self, Box<dyn std::error::Error>> {
Self::from_cbor_bytes(bytes)
}
}