intel_dcap_api/client/
enclave_identity.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 Matter Labs
3
4//! Enclave Identity
5
6use super::ApiClient; // Import from parent module
7use crate::{
8    error::IntelApiError,
9    responses::EnclaveIdentityResponse,
10    types::{ApiVersion, UpdateType},
11};
12
13impl ApiClient {
14    /// Retrieves the SGX QE Identity from the Intel API.
15    ///
16    /// Returns Enclave Identity JSON string (Appendix B) and Issuer Chain header.
17    /// Supports both v3 and v4. The `update` and `tcb_evaluation_data_number`
18    /// parameters are only valid in API v4. Returns the enclave identity JSON
19    /// and an issuer chain header.
20    ///
21    /// # Arguments
22    ///
23    /// * `update` - Optional [`UpdateType`] (v4 only).
24    /// * `tcb_evaluation_data_number` - Optional TCB Evaluation Data Number (v4 only).
25    ///
26    /// # Returns
27    ///
28    /// An [`EnclaveIdentityResponse`] containing the JSON identity and issuer chain.
29    ///
30    /// # Errors
31    ///
32    /// Returns an `IntelApiError` if the request fails, if conflicting v4 parameters are used,
33    /// or if the desired identity resource is not found.
34    pub async fn get_sgx_qe_identity(
35        &self,
36        update: Option<UpdateType>,
37        tcb_evaluation_data_number: Option<u64>,
38    ) -> Result<EnclaveIdentityResponse, IntelApiError> {
39        self.get_sgx_enclave_identity("qe", update, tcb_evaluation_data_number)
40            .await
41    }
42
43    /// Retrieves the TDX QE Identity from the Intel API (API v4 only).
44    ///
45    /// # Arguments
46    ///
47    /// * `update` - Optional [`UpdateType`] (v4 only).
48    /// * `tcb_evaluation_data_number` - Optional TCB Evaluation Data Number (v4 only).
49    ///
50    /// # Returns
51    ///
52    /// An [`EnclaveIdentityResponse`] containing the JSON identity and issuer chain.
53    ///
54    /// # Errors
55    ///
56    /// Returns an `IntelApiError` if an unsupported API version is used,
57    /// if conflicting parameters are provided, or if the identity resource is not found.
58    /// GET /tdx/certification/v4/qe/identity - V4 ONLY
59    pub async fn get_tdx_qe_identity(
60        &self,
61        update: Option<UpdateType>,
62        tcb_evaluation_data_number: Option<u64>,
63    ) -> Result<EnclaveIdentityResponse, IntelApiError> {
64        // Ensure V4 API
65        self.ensure_v4_api("get_tdx_qe_identity")?;
66        // Check conflicting parameters (only relevant for V4, checked inside helper)
67        self.check_conflicting_update_params(update, tcb_evaluation_data_number)?;
68
69        let path = self.build_api_path("tdx", "qe", "identity")?;
70        let mut url = self.base_url.join(&path)?;
71
72        if let Some(upd) = update {
73            url.query_pairs_mut()
74                .append_pair("update", &upd.to_string());
75        }
76        if let Some(tedn) = tcb_evaluation_data_number {
77            url.query_pairs_mut()
78                .append_pair("tcbEvaluationDataNumber", &tedn.to_string());
79        }
80
81        let request_builder = self.client.get(url);
82
83        // Special handling for 404/410 when tcbEvaluationDataNumber is specified
84        if let Some(tedn_val) = tcb_evaluation_data_number {
85            // Use the helper function to check status before proceeding
86            self.check_tcb_evaluation_status(&request_builder, tedn_val, "TDX QE Identity")
87                .await?;
88            // If the check passes (doesn't return Err), continue to fetch_json_with_issuer_chain
89        }
90
91        // Fetch JSON and header (TDX only exists in V4)
92        let (enclave_identity_json, issuer_chain) = self
93            .fetch_json_with_issuer_chain(
94                request_builder,
95                "SGX-Enclave-Identity-Issuer-Chain",
96                None,
97            )
98            .await?;
99
100        Ok(EnclaveIdentityResponse {
101            enclave_identity_json,
102            issuer_chain,
103        })
104    }
105
106    /// Retrieves the SGX QVE Identity from the Intel API.
107    ///
108    /// Supports API v3 and v4. The `update` and `tcb_evaluation_data_number` parameters
109    /// are v4 only. Returns the QVE identity JSON and issuer chain.
110    ///
111    /// # Arguments
112    ///
113    /// * `update` - Optional [`UpdateType`] (v4 only).
114    /// * `tcb_evaluation_data_number` - Optional TCB Evaluation Data Number (v4 only).
115    ///
116    /// # Returns
117    ///
118    /// An [`EnclaveIdentityResponse`] containing the QVE identity JSON and issuer chain.
119    ///
120    /// # Errors
121    ///
122    /// Returns an `IntelApiError` if the request fails, if conflicting parameters are used,
123    /// or if the identity resource is not found.
124    /// GET /sgx/certification/{v3,v4}/qve/identity
125    pub async fn get_sgx_qve_identity(
126        &self,
127        update: Option<UpdateType>,
128        tcb_evaluation_data_number: Option<u64>,
129    ) -> Result<EnclaveIdentityResponse, IntelApiError> {
130        self.get_sgx_enclave_identity("qve", update, tcb_evaluation_data_number)
131            .await
132    }
133
134    /// Retrieves the SGX QAE Identity from the Intel API (API v4 only).
135    ///
136    /// # Arguments
137    ///
138    /// * `update` - Optional [`UpdateType`] (v4 only).
139    /// * `tcb_evaluation_data_number` - Optional TCB Evaluation Data Number (v4 only).
140    ///
141    /// # Returns
142    ///
143    /// An [`EnclaveIdentityResponse`] containing the QAE identity JSON and issuer chain.
144    ///
145    /// # Errors
146    ///
147    /// Returns an `IntelApiError` if an unsupported API version is used,
148    /// if conflicting parameters are provided, or if the QAE identity is not found.
149    /// GET /sgx/certification/v4/qae/identity - V4 ONLY
150    pub async fn get_sgx_qae_identity(
151        &self,
152        update: Option<UpdateType>,
153        tcb_evaluation_data_number: Option<u64>,
154    ) -> Result<EnclaveIdentityResponse, IntelApiError> {
155        // QAE endpoint requires V4
156        if self.api_version != ApiVersion::V4 {
157            return Err(IntelApiError::UnsupportedApiVersion(
158                "QAE Identity endpoint requires API v4".to_string(),
159            ));
160        }
161        // Call the generic helper, it will handle V4 params and 404/410 checks
162        self.get_sgx_enclave_identity("qae", update, tcb_evaluation_data_number)
163            .await
164    }
165
166    /// Retrieves generic SGX enclave identity (QE, QVE, QAE) data.
167    ///
168    /// # Arguments
169    ///
170    /// * `identity_path_segment` - String slice representing the identity path segment (e.g., "qe", "qve", "qae").
171    /// * `update` - Optional [`UpdateType`] for API v4.
172    /// * `tcb_evaluation_data_number` - Optional TCB Evaluation Data Number for API v4.
173    ///
174    /// # Returns
175    ///
176    /// An [`EnclaveIdentityResponse`] containing the JSON identity data and issuer chain.
177    ///
178    /// # Errors
179    ///
180    /// Returns an `IntelApiError` if the request fails or the specified resource
181    /// is unavailable.
182    async fn get_sgx_enclave_identity(
183        &self,
184        identity_path_segment: &str,
185        update: Option<UpdateType>,
186        tcb_evaluation_data_number: Option<u64>,
187    ) -> Result<EnclaveIdentityResponse, IntelApiError> {
188        self.check_v4_only_param(update, "update")?;
189        self.check_v4_only_param(tcb_evaluation_data_number, "tcbEvaluationDataNumber")?;
190        self.check_conflicting_update_params(update, tcb_evaluation_data_number)?;
191
192        let path = self.build_api_path("sgx", identity_path_segment, "identity")?;
193        let mut url = self.base_url.join(&path)?;
194
195        if self.api_version == ApiVersion::V4 {
196            if let Some(upd) = update {
197                url.query_pairs_mut()
198                    .append_pair("update", &upd.to_string());
199            }
200            if let Some(tedn) = tcb_evaluation_data_number {
201                url.query_pairs_mut()
202                    .append_pair("tcbEvaluationDataNumber", &tedn.to_string());
203            }
204        }
205
206        let request_builder = self.client.get(url);
207
208        if self.api_version == ApiVersion::V4 {
209            if let Some(tedn_val) = tcb_evaluation_data_number {
210                let description = format!("SGX {} Identity", identity_path_segment.to_uppercase());
211                self.check_tcb_evaluation_status(&request_builder, tedn_val, &description)
212                    .await?;
213            }
214        }
215
216        let (enclave_identity_json, issuer_chain) = self
217            .fetch_json_with_issuer_chain(
218                request_builder,
219                "SGX-Enclave-Identity-Issuer-Chain",
220                Some("SGX-Enclave-Identity-Issuer-Chain"),
221            )
222            .await?;
223
224        Ok(EnclaveIdentityResponse {
225            enclave_identity_json,
226            issuer_chain,
227        })
228    }
229}