1use serde::{Deserialize, Serialize};
4use subtle::ConstantTimeEq;
5
6pub const CBOR_TAG_EVIDENCE_PACKET: u64 = 1129336656;
8pub const CBOR_TAG_ATTESTATION_RESULT: u64 = 1129791826;
10
11pub const IANA_PEN: u32 = 65074;
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
16#[repr(u64)]
17pub enum HashAlgorithm {
18 Sha256 = 1,
20 Sha384 = 2,
22 Sha512 = 3,
24}
25
26#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
28#[repr(u64)]
29pub enum AttestationTier {
30 SoftwareOnly = 1,
32 AttestedSoftware = 2,
34 HardwareBound = 3,
36 HardwareHardened = 4,
38}
39
40#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
41#[repr(u64)]
42pub enum ContentTier {
43 Core = 1,
45 Enhanced = 2,
47 Maximum = 3,
49}
50
51#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
52#[repr(u64)]
53pub enum ProofAlgorithm {
54 SwfSha256 = 10,
55 SwfArgon2id = 20,
56 SwfArgon2idEntangled = 21,
58}
59
60#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
61#[repr(u64)]
62pub enum Verdict {
63 Authentic = 1,
65 Inconclusive = 2,
67 Suspicious = 3,
69 Invalid = 4,
71}
72
73#[derive(Debug, Clone, Serialize, Deserialize)]
74pub struct HashValue {
75 #[serde(rename = "1")]
76 pub algorithm: HashAlgorithm,
77 #[serde(rename = "2", with = "serde_bytes")]
78 pub digest: Vec<u8>,
79}
80
81impl HashValue {
82 pub fn ct_eq(&self, other: &Self) -> bool {
84 self.algorithm == other.algorithm && self.digest.ct_eq(&other.digest).into()
85 }
86
87 pub fn expected_digest_len(&self) -> usize {
88 match self.algorithm {
89 HashAlgorithm::Sha256 => 32,
90 HashAlgorithm::Sha384 => 48,
91 HashAlgorithm::Sha512 => 64,
92 }
93 }
94
95 pub fn validate(&self) -> bool {
96 self.digest.len() == self.expected_digest_len()
97 }
98}
99
100impl PartialEq for HashValue {
103 fn eq(&self, other: &Self) -> bool {
104 self.algorithm == other.algorithm && self.digest == other.digest
105 }
106}
107
108impl Eq for HashValue {}
109
110#[derive(Debug, Clone, Serialize, Deserialize)]
111pub struct DocumentRef {
112 #[serde(rename = "1")]
113 pub content_hash: HashValue,
114 #[serde(rename = "2", skip_serializing_if = "Option::is_none")]
115 pub filename: Option<String>,
116 #[serde(rename = "3")]
117 pub byte_length: u64,
118 #[serde(rename = "4")]
119 pub char_count: u64,
120}
121
122#[derive(Debug, Clone, Serialize, Deserialize)]
124pub struct Checkpoint {
125 #[serde(rename = "1")]
126 pub sequence: u64,
127 #[serde(rename = "2", with = "serde_bytes")]
128 pub checkpoint_id: Vec<u8>,
129 #[serde(rename = "3")]
130 pub timestamp: u64,
131 #[serde(rename = "4")]
132 pub content_hash: HashValue,
133 #[serde(rename = "5")]
134 pub char_count: u64,
135 #[serde(rename = "7")]
136 pub prev_hash: HashValue,
137 #[serde(rename = "8")]
138 pub checkpoint_hash: HashValue,
139 #[serde(rename = "9", skip_serializing_if = "Option::is_none")]
140 pub jitter_hash: Option<HashValue>,
141}
142
143#[derive(Debug, Clone, Serialize, Deserialize)]
144pub struct EvidencePacket {
145 #[serde(rename = "1")]
146 pub version: u32,
147 #[serde(rename = "2")]
148 pub profile_uri: String,
149 #[serde(rename = "3", with = "serde_bytes")]
150 pub packet_id: Vec<u8>,
151 #[serde(rename = "4")]
152 pub created: u64,
153 #[serde(rename = "5")]
154 pub document: DocumentRef,
155 #[serde(rename = "6")]
156 pub checkpoints: Vec<Checkpoint>,
157 #[serde(rename = "7", skip_serializing_if = "Option::is_none")]
158 pub attestation_tier: Option<AttestationTier>,
159 #[serde(rename = "19", skip_serializing_if = "Option::is_none")]
160 pub baseline_verification: Option<crate::baseline::BaselineVerification>,
161}
162
163#[derive(Debug, Clone, Serialize, Deserialize)]
164pub struct AttestationResult {
165 #[serde(rename = "1")]
166 pub version: u32,
167 #[serde(rename = "2")]
168 pub evidence_ref: HashValue,
169 #[serde(rename = "3")]
170 pub verdict: Verdict,
171 #[serde(rename = "4")]
172 pub attestation_tier: AttestationTier,
173 #[serde(rename = "5")]
174 pub chain_length: u64,
175 #[serde(rename = "6")]
176 pub chain_duration: u64,
177 #[serde(rename = "12")]
178 pub created: u64,
179 #[serde(rename = "14", skip_serializing_if = "Option::is_none")]
181 pub confidence_tier: Option<crate::baseline::ConfidenceTier>,
182}