#[derive(Debug, Clone, PartialEq, Default)]
pub struct ResolutionTrace {
pub unlock: Vec<UnlockStep>,
pub keys: Vec<KeyStep>,
}
impl ResolutionTrace {
pub fn new() -> Self {
Self::default()
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct UnlockStep {
pub who: String,
pub outcome: UnlockOutcome,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum UnlockOutcome {
Unlocked,
FirmwareNotUnlockable,
NoUsableHostCert { mkb: Option<u32> },
CertRevoked { mkb: Option<u32> },
HandshakeRejected,
VidUnavailable,
}
#[derive(Debug, Clone, PartialEq)]
pub struct KeyStep {
pub who: String,
pub path: Vec<KeyNode>,
pub outcome: KeyOutcome,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum KeyNode {
MatchedDisc,
NoEntry,
FoundUnitKeys,
FoundVuk,
FoundMediaKey,
NeedVid,
VidFromUnlock,
VidFromKeydb,
NoVid,
DerivedVuk,
DerivedUnitKeys,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum KeyOutcome {
Resolved,
MissingVid,
NoKey,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn trace_is_constructible_and_comparable() {
let t = ResolutionTrace {
unlock: vec![UnlockStep {
who: "AACS cert".to_string(),
outcome: UnlockOutcome::NoUsableHostCert { mkb: Some(68) },
}],
keys: vec![KeyStep {
who: "keydb".to_string(),
path: vec![
KeyNode::MatchedDisc,
KeyNode::FoundVuk,
KeyNode::DerivedUnitKeys,
],
outcome: KeyOutcome::Resolved,
}],
};
assert_eq!(t.clone(), t);
assert_eq!(t.keys[0].who, "keydb");
assert_eq!(t.unlock[0].who, "AACS cert");
assert_eq!(ResolutionTrace::new(), ResolutionTrace::default());
assert!(ResolutionTrace::new().unlock.is_empty());
assert!(ResolutionTrace::new().keys.is_empty());
}
}