-
Notifications
You must be signed in to change notification settings - Fork 91
Expand file tree
/
Copy pathtypes.rs
More file actions
136 lines (122 loc) · 4.45 KB
/
Copy pathtypes.rs
File metadata and controls
136 lines (122 loc) · 4.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// SPDX-FileCopyrightText: © 2024-2025 Phala Network <dstack@phala.network>
//
// SPDX-License-Identifier: Apache-2.0
use dstack_types::KeyProviderInfo;
use ra_tls::attestation::{AppInfo, AttestationMode};
use serde::{Deserialize, Serialize};
use serde_human_bytes as serde_bytes;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VerificationRequest {
#[serde(with = "serde_bytes", default)]
pub quote: Option<Vec<u8>>,
#[serde(default)]
pub event_log: Option<String>,
#[serde(default)]
pub vm_config: Option<String>,
#[serde(with = "serde_bytes", default)]
pub attestation: Option<Vec<u8>>,
#[serde(default)]
pub debug: Option<bool>,
}
#[derive(Debug, Clone, Serialize)]
pub struct VerificationResponse {
pub is_valid: bool,
pub details: VerificationDetails,
pub reason: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct VerificationDetails {
pub quote_verified: bool,
/// Indicates that the event log was verified against the quote.
///
/// For RTMR3 (runtime measurements), both the digest and payload integrity are verified
/// by replaying the event log and comparing against the quote. For RTMR 0-2 (boot-time
/// measurements), only the digests are verified through replay comparison with the quote;
/// the payload content is not validated. dstack does not define semantics for RTMR 0-2
/// event log payloads.
pub event_log_verified: bool,
pub os_image_hash_verified: bool,
/// dev vs prod OS image, from metadata.json (bound to os_image_hash). None if not exposed.
pub os_image_is_dev: Option<bool>,
/// dstack OS version, from the same metadata.json.
pub os_image_version: Option<String>,
/// Attestation mode that produced the verified quote.
pub attestation_mode: Option<AttestationMode>,
pub report_data: Option<String>,
pub tcb_status: Option<String>,
pub advisory_ids: Vec<String>,
/// decoded app_info.key_provider_info; name is e.g. "kms" or "local".
pub key_provider: Option<KeyProviderInfo>,
pub app_info: Option<AppInfo>,
#[serde(skip_serializing_if = "Option::is_none")]
pub acpi_tables: Option<AcpiTables>,
#[serde(skip_serializing_if = "Option::is_none")]
pub rtmr_debug: Option<Vec<RtmrMismatch>>,
}
#[derive(Debug, Clone, Serialize)]
pub struct AcpiTables {
pub tables: String,
pub rsdp: String,
pub loader: String,
}
#[derive(Debug, Clone, Serialize)]
pub struct RtmrMismatch {
pub rtmr: String,
pub expected: String,
pub actual: String,
pub events: Vec<RtmrEventEntry>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub missing_expected_digests: Vec<String>,
}
#[derive(Debug, Clone, Serialize)]
pub struct RtmrEventEntry {
pub index: usize,
pub event_type: u32,
pub event_name: String,
pub actual_digest: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub expected_digest: Option<String>,
pub payload_len: usize,
pub status: RtmrEventStatus,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum RtmrEventStatus {
Match,
Mismatch,
Extra,
Missing,
}
#[cfg(test)]
mod tests {
use super::*;
// the README documents sending either `attestation` or
// (`quote` + `event_log` + `vm_config`); every field is optional, so any
// documented subset must deserialize without a "missing field" error.
#[test]
fn deserializes_quote_subset_without_attestation() {
let json = r#"{"quote":"00","event_log":"[]","vm_config":"{}"}"#;
let req: VerificationRequest = serde_json::from_str(json).unwrap();
assert_eq!(req.quote, Some(vec![0u8]));
assert_eq!(req.event_log.as_deref(), Some("[]"));
assert_eq!(req.vm_config.as_deref(), Some("{}"));
assert_eq!(req.attestation, None);
assert_eq!(req.debug, None);
}
#[test]
fn deserializes_attestation_subset_without_quote() {
let json = r#"{"attestation":"00"}"#;
let req: VerificationRequest = serde_json::from_str(json).unwrap();
assert_eq!(req.attestation, Some(vec![0u8]));
assert_eq!(req.quote, None);
assert_eq!(req.event_log, None);
assert_eq!(req.vm_config, None);
}
#[test]
fn deserializes_empty_object() {
let req: VerificationRequest = serde_json::from_str("{}").unwrap();
assert_eq!(req.quote, None);
assert_eq!(req.attestation, None);
assert_eq!(req.debug, None);
}
}