intel_dcap_api/client/tcb_info.rs
1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 Matter Labs
3
4//! TCB Info
5
6use super::ApiClient; // Import from parent module
7use crate::{
8 error::IntelApiError,
9 responses::TcbInfoResponse,
10 types::{ApiVersion, UpdateType},
11};
12
13impl ApiClient {
14 /// GET /sgx/certification/{v3,v4}/tcb
15 /// Retrieves SGX TCB information for a given FMSPC.
16 ///
17 /// Returns TCB Info JSON string (Appendix A) and Issuer Chain header.
18 /// This function supports both API v3 and v4. The `update` and `tcbEvaluationDataNumber`
19 /// parameters are only supported by API v4. If both are provided at the same time (for v4),
20 /// a conflict error is returned.
21 ///
22 /// # Arguments
23 ///
24 /// * `fmspc` - Hex-encoded FMSPC value.
25 /// * `update` - Optional [`UpdateType`] for API v4.
26 /// * `tcb_evaluation_data_number` - Optional TCB Evaluation Data Number (v4 only).
27 ///
28 /// # Returns
29 ///
30 /// A [`TcbInfoResponse`] containing the TCB info JSON and the issuer chain.
31 ///
32 /// # Errors
33 ///
34 /// Returns an `IntelApiError` if the API request fails, if conflicting parameters are used,
35 /// or if the requested TCB data is not found.
36 pub async fn get_sgx_tcb_info(
37 &self,
38 fmspc: &str,
39 update: Option<UpdateType>,
40 tcb_evaluation_data_number: Option<u64>,
41 ) -> Result<TcbInfoResponse, IntelApiError> {
42 // V3 does not support 'update' or 'tcbEvaluationDataNumber'
43 if self.api_version == ApiVersion::V3 && update.is_some() {
44 return Err(IntelApiError::UnsupportedApiVersion(
45 "'update' parameter requires API v4".to_string(),
46 ));
47 }
48 if self.api_version == ApiVersion::V3 && tcb_evaluation_data_number.is_some() {
49 return Err(IntelApiError::UnsupportedApiVersion(
50 "'tcbEvaluationDataNumber' parameter requires API v4".to_string(),
51 ));
52 }
53 if self.api_version == ApiVersion::V4
54 && update.is_some()
55 && tcb_evaluation_data_number.is_some()
56 {
57 return Err(IntelApiError::ConflictingParameters(
58 "'update' and 'tcbEvaluationDataNumber'",
59 ));
60 }
61
62 let path = self.build_api_path("sgx", "", "tcb")?;
63 let mut url = self.base_url.join(&path)?;
64 url.query_pairs_mut().append_pair("fmspc", fmspc);
65
66 // Add V4-specific parameters
67 if self.api_version == ApiVersion::V4 {
68 if let Some(upd) = update {
69 url.query_pairs_mut()
70 .append_pair("update", &upd.to_string());
71 }
72 if let Some(tedn) = tcb_evaluation_data_number {
73 url.query_pairs_mut()
74 .append_pair("tcbEvaluationDataNumber", &tedn.to_string());
75 }
76 }
77
78 let request_builder = self.client.get(url);
79
80 // Special handling for 404/410 when tcbEvaluationDataNumber is specified (V4 only)
81 if self.api_version == ApiVersion::V4 {
82 if let Some(tedn_val) = tcb_evaluation_data_number {
83 // Use the helper function to check status before proceeding
84 self.check_tcb_evaluation_status(&request_builder, tedn_val, "SGX TCB Info")
85 .await?;
86 // If the check passes (doesn't return Err), continue to fetch_json_with_issuer_chain
87 }
88 }
89
90 // Fetch JSON and header (header name seems same for v3/v4)
91 let (tcb_info_json, issuer_chain) = self
92 .fetch_json_with_issuer_chain(
93 request_builder,
94 "TCB-Info-Issuer-Chain",
95 Some("SGX-TCB-Info-Issuer-Chain"),
96 )
97 .await?;
98
99 Ok(TcbInfoResponse {
100 tcb_info_json,
101 issuer_chain,
102 })
103 }
104
105 /// GET /tdx/certification/v4/tcb
106 /// Retrieves TDX TCB information for a given FMSPC (API v4 only).
107 ///
108 /// # Arguments
109 ///
110 /// * `fmspc` - Hex-encoded FMSPC value.
111 /// * `update` - An optional [`UpdateType`] (v4 only).
112 /// * `tcb_evaluation_data_number` - An optional TCB Evaluation Data Number (v4 only).
113 ///
114 /// # Returns
115 ///
116 /// A [`TcbInfoResponse`] containing TDX TCB info JSON and the issuer chain.
117 ///
118 /// # Errors
119 ///
120 /// Returns an `IntelApiError` if an unsupported API version is used,
121 /// if there are conflicting parameters, or if the TDX TCB data is not found.
122 /// Returns TCB Info JSON string (Appendix A) and Issuer Chain header.
123 pub async fn get_tdx_tcb_info(
124 &self,
125 fmspc: &str,
126 update: Option<UpdateType>,
127 tcb_evaluation_data_number: Option<u64>,
128 ) -> Result<TcbInfoResponse, IntelApiError> {
129 // Ensure V4 API
130 self.ensure_v4_api("get_tdx_tcb_info")?;
131 // Check conflicting parameters (only relevant for V4, checked inside helper)
132 self.check_conflicting_update_params(update, tcb_evaluation_data_number)?;
133
134 let path = self.build_api_path("tdx", "", "tcb")?;
135 let mut url = self.base_url.join(&path)?;
136 url.query_pairs_mut().append_pair("fmspc", fmspc);
137
138 if let Some(upd) = update {
139 url.query_pairs_mut()
140 .append_pair("update", &upd.to_string());
141 }
142 if let Some(tedn) = tcb_evaluation_data_number {
143 url.query_pairs_mut()
144 .append_pair("tcbEvaluationDataNumber", &tedn.to_string());
145 }
146
147 let request_builder = self.client.get(url);
148
149 // Special handling for 404/410 when tcbEvaluationDataNumber is specified
150 if let Some(tedn_val) = tcb_evaluation_data_number {
151 // Use the helper function to check status before proceeding
152 self.check_tcb_evaluation_status(&request_builder, tedn_val, "TDX TCB Info")
153 .await?;
154 // If the check passes (doesn't return Err), continue to fetch_json_with_issuer_chain
155 }
156
157 // Fetch JSON and header (TDX only exists in V4)
158 let (tcb_info_json, issuer_chain) = self
159 .fetch_json_with_issuer_chain(request_builder, "TCB-Info-Issuer-Chain", None)
160 .await?;
161
162 Ok(TcbInfoResponse {
163 tcb_info_json,
164 issuer_chain,
165 })
166 }
167}