1use x509_parser::{certificate::X509Certificate, revocation_list::CertificateRevocationList};
2
3use super::enclave_identity::EnclaveIdentityV2;
4use super::tcbinfo::{TcbInfoV2, TcbInfoV3};
5
6use crate::utils::cert::{parse_crl_der, parse_x509_der, parse_x509_der_multi, pem_to_der};
7
8#[derive(Clone, Debug)]
9pub struct IntelCollateral {
10 pub tcbinfo_bytes: Option<Vec<u8>>,
11 pub qeidentity_bytes: Option<Vec<u8>>,
12 pub sgx_intel_root_ca_der: Option<Vec<u8>>,
13 pub sgx_tcb_signing_der: Option<Vec<u8>>,
14 pub sgx_pck_certchain_der: Option<Vec<u8>>,
15 pub sgx_intel_root_ca_crl_der: Option<Vec<u8>>,
16 pub sgx_pck_processor_crl_der: Option<Vec<u8>>,
17 pub sgx_pck_platform_crl_der: Option<Vec<u8>>,
18}
19
20impl IntelCollateral {
22 pub fn new() -> IntelCollateral {
23 IntelCollateral {
24 tcbinfo_bytes: None,
25 qeidentity_bytes: None,
26 sgx_intel_root_ca_der: None,
27 sgx_tcb_signing_der: None,
28 sgx_pck_certchain_der: None,
29 sgx_intel_root_ca_crl_der: None,
30 sgx_pck_processor_crl_der: None,
31 sgx_pck_platform_crl_der: None,
32 }
33 }
34
35 pub fn to_bytes(&self) -> Vec<u8> {
36 let tcbinfo_bytes = match self.tcbinfo_bytes {
42 Some(ref tcbinfo) => tcbinfo.as_slice(),
43 None => &[],
44 };
45
46 let qeidentity_bytes = match self.qeidentity_bytes {
47 Some(ref qeidentity) => qeidentity.as_slice(),
48 None => &[],
49 };
50
51 let sgx_intel_root_ca_der_bytes = match &self.sgx_intel_root_ca_der {
52 Some(der) => der.as_slice(),
53 None => &[],
54 };
55
56 let sgx_tcb_signing_der_bytes = match &self.sgx_tcb_signing_der {
57 Some(der) => der.as_slice(),
58 None => &[],
59 };
60
61 let sgx_pck_certchain_der_bytes = match &self.sgx_pck_certchain_der {
62 Some(der) => der.as_slice(),
63 None => &[],
64 };
65
66 let sgx_intel_root_ca_crl_der_bytes = match &self.sgx_intel_root_ca_crl_der {
67 Some(der) => der.as_slice(),
68 None => &[],
69 };
70
71 let sgx_pck_processor_crl_der_bytes = match &self.sgx_pck_processor_crl_der {
72 Some(der) => der.as_slice(),
73 None => &[],
74 };
75
76 let sgx_pck_platform_crl_der_bytes = match &self.sgx_pck_platform_crl_der {
77 Some(der) => der.as_slice(),
78 None => &[],
79 };
80
81 let total_length = 4 * 8 + tcbinfo_bytes.len() + qeidentity_bytes.len() + sgx_intel_root_ca_der_bytes.len() + sgx_tcb_signing_der_bytes.len() + sgx_pck_certchain_der_bytes.len() + sgx_intel_root_ca_crl_der_bytes.len() + sgx_pck_processor_crl_der_bytes.len() + sgx_pck_platform_crl_der_bytes.len();
83
84 let mut data = Vec::with_capacity(total_length);
86 data.extend_from_slice(&(tcbinfo_bytes.len() as u32).to_le_bytes());
87 data.extend_from_slice(&(qeidentity_bytes.len() as u32).to_le_bytes());
88 data.extend_from_slice(&(sgx_intel_root_ca_der_bytes.len() as u32).to_le_bytes());
89 data.extend_from_slice(&(sgx_tcb_signing_der_bytes.len() as u32).to_le_bytes());
90 data.extend_from_slice(&(sgx_pck_certchain_der_bytes.len() as u32).to_le_bytes());
91 data.extend_from_slice(&(sgx_intel_root_ca_crl_der_bytes.len() as u32).to_le_bytes());
92 data.extend_from_slice(&(sgx_pck_processor_crl_der_bytes.len() as u32).to_le_bytes());
93 data.extend_from_slice(&(sgx_pck_platform_crl_der_bytes.len() as u32).to_le_bytes());
94
95 data.extend_from_slice(&tcbinfo_bytes);
96 data.extend_from_slice(&qeidentity_bytes);
97 data.extend_from_slice(&sgx_intel_root_ca_der_bytes);
98 data.extend_from_slice(&sgx_tcb_signing_der_bytes);
99 data.extend_from_slice(&sgx_pck_certchain_der_bytes);
100 data.extend_from_slice(&sgx_intel_root_ca_crl_der_bytes);
101 data.extend_from_slice(&sgx_pck_processor_crl_der_bytes);
102 data.extend_from_slice(&sgx_pck_platform_crl_der_bytes);
103
104 data
105 }
106
107 pub fn from_bytes(slice: &[u8]) -> Self {
108 let tcbinfo_bytes_len = u32::from_le_bytes(slice[0..4].try_into().unwrap()) as usize;
111 let qeidentity_bytes_len = u32::from_le_bytes(slice[4..8].try_into().unwrap()) as usize;
112 let sgx_intel_root_ca_der_len = u32::from_le_bytes(slice[8..12].try_into().unwrap()) as usize;
113 let sgx_tcb_signing_der_len = u32::from_le_bytes(slice[12..16].try_into().unwrap()) as usize;
114 let sgx_pck_certchain_der_len = u32::from_le_bytes(slice[16..20].try_into().unwrap()) as usize;
115 let sgx_intel_root_ca_crl_der_len = u32::from_le_bytes(slice[20..24].try_into().unwrap()) as usize;
116 let sgx_pck_processor_crl_der_len = u32::from_le_bytes(slice[24..28].try_into().unwrap()) as usize;
117 let sgx_pck_platform_crl_der_len = u32::from_le_bytes(slice[28..32].try_into().unwrap()) as usize;
118
119 let mut offset = 4 * 8 as usize;
120 let tcbinfo_bytes: Option<Vec<u8>> = match tcbinfo_bytes_len {
121 0 => None,
122 len => Some(slice[offset..offset + len].to_vec())
123 };
124 offset += tcbinfo_bytes_len;
125
126 let qeidentity_bytes: Option<Vec<u8>> = match qeidentity_bytes_len {
127 0 => None,
128 len => Some(slice[offset..offset + len].to_vec())
129 };
130 offset += qeidentity_bytes_len;
131
132 let sgx_intel_root_ca_der: Option<Vec<u8>> = match sgx_intel_root_ca_der_len {
133 0 => None,
134 len => Some(slice[offset..offset + len].to_vec())
135 };
136 offset += sgx_intel_root_ca_der_len;
137
138 let sgx_tcb_signing_der: Option<Vec<u8>> = match sgx_tcb_signing_der_len {
139 0 => None,
140 len => Some(slice[offset..offset + len].to_vec())
141 };
142 offset += sgx_tcb_signing_der_len;
143
144 let sgx_pck_certchain_der: Option<Vec<u8>> = match sgx_pck_certchain_der_len {
145 0 => None,
146 len => Some(slice[offset..offset + len].to_vec())
147 };
148 offset += sgx_pck_certchain_der_len;
149
150 let sgx_intel_root_ca_crl_der: Option<Vec<u8>> = match sgx_intel_root_ca_crl_der_len {
151 0 => None,
152 len => Some(slice[offset..offset + len].to_vec())
153 };
154 offset += sgx_intel_root_ca_crl_der_len;
155
156 let sgx_pck_processor_crl_der: Option<Vec<u8>> = match sgx_pck_processor_crl_der_len {
157 0 => None,
158 len => Some(slice[offset..offset + len].to_vec())
159 };
160 offset += sgx_pck_processor_crl_der_len;
161
162 let sgx_pck_platform_crl_der: Option<Vec<u8>> = match sgx_pck_platform_crl_der_len {
163 0 => None,
164 len => Some(slice[offset..offset + len].to_vec())
165 };
166 offset += sgx_pck_platform_crl_der_len;
167
168 assert!(offset == slice.len());
169
170 IntelCollateral {
171 tcbinfo_bytes: tcbinfo_bytes,
172 qeidentity_bytes: qeidentity_bytes,
173 sgx_intel_root_ca_der,
174 sgx_tcb_signing_der,
175 sgx_pck_certchain_der,
176 sgx_intel_root_ca_crl_der,
177 sgx_pck_processor_crl_der,
178 sgx_pck_platform_crl_der,
179 }
180 }
181
182 pub fn get_tcbinfov2(&self) -> TcbInfoV2 {
183 match &self.tcbinfo_bytes {
184 Some(tcbinfov2) => {
185 let tcbinfo: TcbInfoV2 = serde_json::from_slice(tcbinfov2).unwrap();
186 assert_eq!(tcbinfo.tcb_info.version, 2);
187 tcbinfo
188 },
189 None => panic!("TCB Info V2 not set"),
190 }
191 }
192
193 pub fn get_tcbinfov3(&self) -> TcbInfoV3 {
194 match &self.tcbinfo_bytes {
195 Some(tcbinfov3) => {
196 let tcbinfo: TcbInfoV3 = serde_json::from_slice(tcbinfov3).unwrap();
197 assert_eq!(tcbinfo.tcb_info.version, 3);
198 tcbinfo
199 },
200 None => panic!("TCB Info V3 not set"),
201 }
202 }
203
204 pub fn set_tcbinfo_bytes(&mut self, tcbinfo_slice: &[u8]) {
205 self.tcbinfo_bytes = Some(tcbinfo_slice.to_vec());
206 }
207
208 pub fn get_qeidentityv2(&self) -> EnclaveIdentityV2 {
209 match &self.qeidentity_bytes {
210 Some(qeidentityv2) => {
211 let qeidentity = serde_json::from_slice(qeidentityv2).unwrap();
212 qeidentity
213 },
214 None => panic!("QE Identity V2 not set"),
215 }
216 }
217
218 pub fn set_qeidentity_bytes(&mut self, qeidentity_slice: &[u8]) {
219 self.qeidentity_bytes = Some(qeidentity_slice.to_vec());
220 }
221
222 pub fn get_sgx_intel_root_ca<'a>(&'a self) -> X509Certificate<'a> {
223 match self.sgx_intel_root_ca_der {
224 Some(ref der) => {
225 let cert = parse_x509_der(der);
226 cert
227 },
228 None => panic!("Intel Root CA not set"),
229 }
230 }
231
232 pub fn set_intel_root_ca_der(&mut self, intel_root_ca_der: &[u8]) {
233 self.sgx_intel_root_ca_der = Some(intel_root_ca_der.to_vec());
234 }
235
236 pub fn get_sgx_tcb_signing<'a>(&'a self) -> X509Certificate<'a> {
237 match self.sgx_tcb_signing_der {
238 Some(ref der) => {
239 let cert = parse_x509_der(der);
240 cert
241 },
242 None => panic!("SGX TCB Signing Cert not set"),
243 }
244 }
245
246 pub fn set_sgx_tcb_signing_der(&mut self, sgx_tcb_signing_der: &[u8]) {
247 self.sgx_tcb_signing_der = Some(sgx_tcb_signing_der.to_vec());
248 }
249
250 pub fn set_sgx_tcb_signing_pem(&mut self, sgx_tcb_signing_pem: &[u8]) {
251 let sgx_tcb_signing_der = pem_to_der(sgx_tcb_signing_pem);
253 self.sgx_tcb_signing_der = Some(sgx_tcb_signing_der);
254 }
255
256 pub fn get_sgx_pck_certchain<'a>(&'a self) -> Option<Vec<X509Certificate<'a>>> {
257 match &self.sgx_pck_certchain_der {
258 Some(certchain_der) => {
259 let certchain = parse_x509_der_multi(certchain_der);
260 Some(certchain)
261 },
262 None => None,
263 }
264 }
265
266 pub fn set_sgx_pck_certchain_der(&mut self, sgx_pck_certchain_der: Option<&[u8]>) {
267 match sgx_pck_certchain_der {
268 Some(certchain_der) => {
269 self.sgx_pck_certchain_der = Some(certchain_der.to_vec());
270 },
271 None => {
272 self.sgx_pck_certchain_der = None;
273 },
274 }
275 }
276
277 pub fn set_sgx_pck_certchain_pem(&mut self, sgx_pck_certchain_pem: Option<&[u8]>) {
278 match sgx_pck_certchain_pem {
279 Some(certchain_pem) => {
280 let sgx_pck_certchain_der = pem_to_der(certchain_pem);
282 self.sgx_pck_certchain_der = Some(sgx_pck_certchain_der);
283 },
284 None => {
285 self.sgx_pck_certchain_der = None;
286 },
287 }
288 }
289
290 pub fn get_sgx_intel_root_ca_crl<'a>(&'a self) -> Option<CertificateRevocationList<'a>> {
291 match &self.sgx_intel_root_ca_crl_der {
292 Some(crl_der) => {
293 let crl = parse_crl_der(crl_der);
294 Some(crl)
295 },
296 None => None,
297 }
298 }
299
300 pub fn set_sgx_intel_root_ca_crl_der(&mut self, sgx_intel_root_ca_crl_der: &[u8]) {
301 self.sgx_intel_root_ca_crl_der = Some(sgx_intel_root_ca_crl_der.to_vec());
302 }
303
304 pub fn set_sgx_intel_root_ca_crl_pem(&mut self, sgx_intel_root_ca_crl_pem: &[u8]) {
305 let sgx_intel_root_ca_crl_der = pem_to_der(sgx_intel_root_ca_crl_pem);
307 self.sgx_intel_root_ca_crl_der = Some(sgx_intel_root_ca_crl_der);
308 }
309
310 pub fn get_sgx_pck_processor_crl<'a>(&'a self) -> Option<CertificateRevocationList<'a>> {
311 match &self.sgx_pck_processor_crl_der {
312 Some(crl_der) => {
313 let crl = parse_crl_der(crl_der);
314 Some(crl)
315 },
316 None => None,
317 }
318 }
319
320 pub fn set_sgx_processor_crl_der(&mut self, sgx_pck_processor_crl_der: &[u8]) {
321 self.sgx_pck_processor_crl_der = Some(sgx_pck_processor_crl_der.to_vec());
322 }
323
324 pub fn set_sgx_processor_crl_der_pem(&mut self, sgx_pck_processor_crl_pem: &[u8]) {
325 let sgx_pck_processor_crl_der = pem_to_der(sgx_pck_processor_crl_pem);
327 self.sgx_pck_processor_crl_der = Some(sgx_pck_processor_crl_der);
328 }
329
330 pub fn get_sgx_pck_platform_crl<'a>(&'a self) -> Option<CertificateRevocationList<'a>> {
331 match &self.sgx_pck_platform_crl_der {
332 Some(crl_der) => {
333 let crl = parse_crl_der(crl_der);
334 Some(crl)
335 },
336 None => None,
337 }
338 }
339
340 pub fn set_sgx_platform_crl_der(&mut self, sgx_pck_platform_crl_der: &[u8]) {
341 self.sgx_pck_platform_crl_der = Some(sgx_pck_platform_crl_der.to_vec());
342 }
343
344 pub fn set_sgx_platform_crl_der_pem(&mut self, sgx_pck_platform_crl_pem: &[u8]) {
345 let sgx_pck_platform_crl_der = pem_to_der(sgx_pck_platform_crl_pem);
347 self.sgx_pck_platform_crl_der = Some(sgx_pck_platform_crl_der);
348 }
349}