use crate::cbor::value::Value;
use crate::nostd_prelude::*;
use crate::profile::{MatchContext, Profile};
use crate::types::corim::ProfileChoice;
use crate::types::measurement::MeasurementMap;
pub const PSA_PROFILE_URI: &str = "tag:arm.com,2025:psa#1.0.0";
pub const MVAL_PSA_CERT_NUM: i64 = 100;
pub fn is_valid_cert_num(s: &str) -> bool {
let b = s.as_bytes();
if b.len() != 21 {
return false;
}
let all_digits = |slice: &[u8]| slice.iter().all(u8::is_ascii_digit);
all_digits(&b[0..13]) && &b[13..16] == b" - " && all_digits(&b[16..21])
}
#[derive(Debug)]
pub struct PsaProfile {
id: ProfileChoice,
}
impl PsaProfile {
pub fn new() -> Self {
Self {
id: ProfileChoice::Uri(PSA_PROFILE_URI.into()),
}
}
}
impl Default for PsaProfile {
fn default() -> Self {
Self::new()
}
}
fn cert_num(value: &Value) -> Option<&str> {
match value {
Value::Text(s) if is_valid_cert_num(s) => Some(s),
_ => None,
}
}
impl Profile for PsaProfile {
fn identifier(&self) -> &ProfileChoice {
&self.id
}
fn match_measurement(
&self,
reference: &MeasurementMap,
evidence: &MeasurementMap,
_ctx: &MatchContext,
) -> Option<bool> {
let ref_val = reference.mval.extra_entries.get(&MVAL_PSA_CERT_NUM)?;
let ev_val = match evidence.mval.extra_entries.get(&MVAL_PSA_CERT_NUM) {
Some(v) => v,
None => return Some(false),
};
let ref_num = match cert_num(ref_val) {
Some(s) => s,
None => return Some(false),
};
let ev_num = match cert_num(ev_val) {
Some(s) => s,
None => return Some(false),
};
if ref_num != ev_num {
return Some(false);
}
Some(crate::validate::core_fields_match(reference, evidence))
}
fn diagnose_mval_entry(&self, key: i64, value: &Value) -> Option<String> {
if key != MVAL_PSA_CERT_NUM {
return None;
}
match cert_num(value) {
Some(s) => Some(format!("psa-cert-num = {s}")),
None => Some("psa-cert-num = <invalid>".into()),
}
}
fn mval_json_alias(&self, name: &str) -> Option<i64> {
match name {
"psa-cert-num" => Some(MVAL_PSA_CERT_NUM),
_ => None,
}
}
fn mval_json_name(&self, key: i64) -> Option<&'static str> {
match key {
MVAL_PSA_CERT_NUM => Some("psa-cert-num"),
_ => None,
}
}
}