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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2025 Matter Labs
//! Enclave Identity
use super::ApiClient; // Import from parent module
use crate::{
error::IntelApiError,
responses::EnclaveIdentityResponse,
types::{ApiVersion, UpdateType},
};
impl ApiClient {
/// Retrieves the SGX QE Identity from the Intel API.
///
/// Returns Enclave Identity JSON string (Appendix B) and Issuer Chain header.
/// Supports both v3 and v4. The `update` and `tcb_evaluation_data_number`
/// parameters are only valid in API v4. Returns the enclave identity JSON
/// and an issuer chain header.
///
/// # Arguments
///
/// * `update` - Optional [`UpdateType`] (v4 only).
/// * `tcb_evaluation_data_number` - Optional TCB Evaluation Data Number (v4 only).
///
/// # Returns
///
/// An [`EnclaveIdentityResponse`] containing the JSON identity and issuer chain.
///
/// # Errors
///
/// Returns an `IntelApiError` if the request fails, if conflicting v4 parameters are used,
/// or if the desired identity resource is not found.
pub async fn get_sgx_qe_identity(
&self,
update: Option<UpdateType>,
tcb_evaluation_data_number: Option<u64>,
) -> Result<EnclaveIdentityResponse, IntelApiError> {
self.get_sgx_enclave_identity("qe", update, tcb_evaluation_data_number)
.await
}
/// Retrieves the TDX QE Identity from the Intel API (API v4 only).
///
/// # Arguments
///
/// * `update` - Optional [`UpdateType`] (v4 only).
/// * `tcb_evaluation_data_number` - Optional TCB Evaluation Data Number (v4 only).
///
/// # Returns
///
/// An [`EnclaveIdentityResponse`] containing the JSON identity and issuer chain.
///
/// # Errors
///
/// Returns an `IntelApiError` if an unsupported API version is used,
/// if conflicting parameters are provided, or if the identity resource is not found.
/// GET /tdx/certification/v4/qe/identity - V4 ONLY
pub async fn get_tdx_qe_identity(
&self,
update: Option<UpdateType>,
tcb_evaluation_data_number: Option<u64>,
) -> Result<EnclaveIdentityResponse, IntelApiError> {
// Ensure V4 API
self.ensure_v4_api("get_tdx_qe_identity")?;
// Check conflicting parameters (only relevant for V4, checked inside helper)
self.check_conflicting_update_params(update, tcb_evaluation_data_number)?;
let path = self.build_api_path("tdx", "qe", "identity")?;
let mut url = self.base_url.join(&path)?;
if let Some(upd) = update {
url.query_pairs_mut()
.append_pair("update", &upd.to_string());
}
if let Some(tedn) = tcb_evaluation_data_number {
url.query_pairs_mut()
.append_pair("tcbEvaluationDataNumber", &tedn.to_string());
}
let request_builder = self.client.get(url);
// Special handling for 404/410 when tcbEvaluationDataNumber is specified
if let Some(tedn_val) = tcb_evaluation_data_number {
// Use the helper function to check status before proceeding
self.check_tcb_evaluation_status(&request_builder, tedn_val, "TDX QE Identity")
.await?;
// If the check passes (doesn't return Err), continue to fetch_json_with_issuer_chain
}
// Fetch JSON and header (TDX only exists in V4)
let (enclave_identity_json, issuer_chain) = self
.fetch_json_with_issuer_chain(
request_builder,
"SGX-Enclave-Identity-Issuer-Chain",
None,
)
.await?;
Ok(EnclaveIdentityResponse {
enclave_identity_json,
issuer_chain,
})
}
/// Retrieves the SGX QVE Identity from the Intel API.
///
/// Supports API v3 and v4. The `update` and `tcb_evaluation_data_number` parameters
/// are v4 only. Returns the QVE identity JSON and issuer chain.
///
/// # Arguments
///
/// * `update` - Optional [`UpdateType`] (v4 only).
/// * `tcb_evaluation_data_number` - Optional TCB Evaluation Data Number (v4 only).
///
/// # Returns
///
/// An [`EnclaveIdentityResponse`] containing the QVE identity JSON and issuer chain.
///
/// # Errors
///
/// Returns an `IntelApiError` if the request fails, if conflicting parameters are used,
/// or if the identity resource is not found.
/// GET /sgx/certification/{v3,v4}/qve/identity
pub async fn get_sgx_qve_identity(
&self,
update: Option<UpdateType>,
tcb_evaluation_data_number: Option<u64>,
) -> Result<EnclaveIdentityResponse, IntelApiError> {
self.get_sgx_enclave_identity("qve", update, tcb_evaluation_data_number)
.await
}
/// Retrieves the SGX QAE Identity from the Intel API (API v4 only).
///
/// # Arguments
///
/// * `update` - Optional [`UpdateType`] (v4 only).
/// * `tcb_evaluation_data_number` - Optional TCB Evaluation Data Number (v4 only).
///
/// # Returns
///
/// An [`EnclaveIdentityResponse`] containing the QAE identity JSON and issuer chain.
///
/// # Errors
///
/// Returns an `IntelApiError` if an unsupported API version is used,
/// if conflicting parameters are provided, or if the QAE identity is not found.
/// GET /sgx/certification/v4/qae/identity - V4 ONLY
pub async fn get_sgx_qae_identity(
&self,
update: Option<UpdateType>,
tcb_evaluation_data_number: Option<u64>,
) -> Result<EnclaveIdentityResponse, IntelApiError> {
// QAE endpoint requires V4
if self.api_version != ApiVersion::V4 {
return Err(IntelApiError::UnsupportedApiVersion(
"QAE Identity endpoint requires API v4".to_string(),
));
}
// Call the generic helper, it will handle V4 params and 404/410 checks
self.get_sgx_enclave_identity("qae", update, tcb_evaluation_data_number)
.await
}
/// Retrieves generic SGX enclave identity (QE, QVE, QAE) data.
///
/// # Arguments
///
/// * `identity_path_segment` - String slice representing the identity path segment (e.g., "qe", "qve", "qae").
/// * `update` - Optional [`UpdateType`] for API v4.
/// * `tcb_evaluation_data_number` - Optional TCB Evaluation Data Number for API v4.
///
/// # Returns
///
/// An [`EnclaveIdentityResponse`] containing the JSON identity data and issuer chain.
///
/// # Errors
///
/// Returns an `IntelApiError` if the request fails or the specified resource
/// is unavailable.
async fn get_sgx_enclave_identity(
&self,
identity_path_segment: &str,
update: Option<UpdateType>,
tcb_evaluation_data_number: Option<u64>,
) -> Result<EnclaveIdentityResponse, IntelApiError> {
self.check_v4_only_param(update, "update")?;
self.check_v4_only_param(tcb_evaluation_data_number, "tcbEvaluationDataNumber")?;
self.check_conflicting_update_params(update, tcb_evaluation_data_number)?;
let path = self.build_api_path("sgx", identity_path_segment, "identity")?;
let mut url = self.base_url.join(&path)?;
if self.api_version == ApiVersion::V4 {
if let Some(upd) = update {
url.query_pairs_mut()
.append_pair("update", &upd.to_string());
}
if let Some(tedn) = tcb_evaluation_data_number {
url.query_pairs_mut()
.append_pair("tcbEvaluationDataNumber", &tedn.to_string());
}
}
let request_builder = self.client.get(url);
if self.api_version == ApiVersion::V4 {
if let Some(tedn_val) = tcb_evaluation_data_number {
let description = format!("SGX {} Identity", identity_path_segment.to_uppercase());
self.check_tcb_evaluation_status(&request_builder, tedn_val, &description)
.await?;
}
}
let (enclave_identity_json, issuer_chain) = self
.fetch_json_with_issuer_chain(
request_builder,
"SGX-Enclave-Identity-Issuer-Chain",
Some("SGX-Enclave-Identity-Issuer-Chain"),
)
.await?;
Ok(EnclaveIdentityResponse {
enclave_identity_json,
issuer_chain,
})
}
}