From 205113ecfaa8ae0a0a0e4a40f14e63e4b5e17611 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Wed, 28 May 2025 08:42:44 +0200 Subject: [PATCH 1/3] feat(intel-dcap-api): add comprehensive testing infrastructure and examples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add mock tests using real Intel API response data (25 tests) - Create fetch_test_data tool to retrieve real API responses for testing - Add integration_test example covering 17 API endpoints - Add common_usage example demonstrating attestation verification patterns - Add issuer chain validation checks to ensure signature verification is possible - Add comprehensive documentation in CLAUDE.md The test suite now covers all major Intel DCAP API functionality including TCB info, enclave identities, PCK CRLs, FMSPCs, and evaluation data numbers for both SGX and TDX platforms across API v3 and v4. ๐Ÿค– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude Signed-off-by: Harald Hoyer --- Cargo.lock | 51 + crates/intel-dcap-api/CLAUDE.md | 128 +++ crates/intel-dcap-api/Cargo.toml | 7 + .../intel-dcap-api/examples/common_usage.rs | 182 ++++ .../examples/fetch_test_data.rs | 515 ++++++++++ .../examples/integration_test.rs | 495 ++++++++++ crates/intel-dcap-api/specs/API spec V3.md | 694 ++++++++++++++ crates/intel-dcap-api/specs/API spec V4.md | 664 +++++++++++++ crates/intel-dcap-api/tests/mock_api_tests.rs | 312 ++++++ .../tests/real_data_mock_tests.rs | 901 ++++++++++++++++++ .../tests/test_data/fmspcs.json | 3 + .../tests/test_data/fmspcs_all_platforms.json | 3 + .../tests/test_data/fmspcs_no_filter.json | 3 + .../tests/test_data/pck_crl_platform.json | 4 + .../tests/test_data/pck_crl_processor.json | 4 + .../test_data/pck_crl_processor_der.json | 4 + .../tests/test_data/sgx_qae_identity.json | 4 + .../tests/test_data/sgx_qe_identity.json | 4 + .../tests/test_data/sgx_qe_identity_v3.json | 4 + .../tests/test_data/sgx_qve_identity.json | 4 + .../tests/test_data/sgx_tcb_eval_nums.json | 4 + .../test_data/sgx_tcb_info_00906ED50000.json | 4 + .../tests/test_data/sgx_tcb_info_alt.json | 4 + .../tests/test_data/sgx_tcb_info_early.json | 4 + .../tests/test_data/sgx_tcb_info_v3.json | 4 + .../tests/test_data/tdx_qe_identity.json | 4 + .../tests/test_data/tdx_tcb_eval_nums.json | 4 + .../tests/test_data/tdx_tcb_info.json | 4 + .../test_data/tdx_tcb_info_00806F050000.json | 4 + .../tests/test_data/tdx_tcb_info_eval17.json | 4 + packages/teepotCrate/default.nix | 1 + 31 files changed, 4027 insertions(+) create mode 100644 crates/intel-dcap-api/CLAUDE.md create mode 100644 crates/intel-dcap-api/examples/common_usage.rs create mode 100644 crates/intel-dcap-api/examples/fetch_test_data.rs create mode 100644 crates/intel-dcap-api/examples/integration_test.rs create mode 100644 crates/intel-dcap-api/specs/API spec V3.md create mode 100644 crates/intel-dcap-api/specs/API spec V4.md create mode 100644 crates/intel-dcap-api/tests/mock_api_tests.rs create mode 100644 crates/intel-dcap-api/tests/real_data_mock_tests.rs create mode 100644 crates/intel-dcap-api/tests/test_data/fmspcs.json create mode 100644 crates/intel-dcap-api/tests/test_data/fmspcs_all_platforms.json create mode 100644 crates/intel-dcap-api/tests/test_data/fmspcs_no_filter.json create mode 100644 crates/intel-dcap-api/tests/test_data/pck_crl_platform.json create mode 100644 crates/intel-dcap-api/tests/test_data/pck_crl_processor.json create mode 100644 crates/intel-dcap-api/tests/test_data/pck_crl_processor_der.json create mode 100644 crates/intel-dcap-api/tests/test_data/sgx_qae_identity.json create mode 100644 crates/intel-dcap-api/tests/test_data/sgx_qe_identity.json create mode 100644 crates/intel-dcap-api/tests/test_data/sgx_qe_identity_v3.json create mode 100644 crates/intel-dcap-api/tests/test_data/sgx_qve_identity.json create mode 100644 crates/intel-dcap-api/tests/test_data/sgx_tcb_eval_nums.json create mode 100644 crates/intel-dcap-api/tests/test_data/sgx_tcb_info_00906ED50000.json create mode 100644 crates/intel-dcap-api/tests/test_data/sgx_tcb_info_alt.json create mode 100644 crates/intel-dcap-api/tests/test_data/sgx_tcb_info_early.json create mode 100644 crates/intel-dcap-api/tests/test_data/sgx_tcb_info_v3.json create mode 100644 crates/intel-dcap-api/tests/test_data/tdx_qe_identity.json create mode 100644 crates/intel-dcap-api/tests/test_data/tdx_tcb_eval_nums.json create mode 100644 crates/intel-dcap-api/tests/test_data/tdx_tcb_info.json create mode 100644 crates/intel-dcap-api/tests/test_data/tdx_tcb_info_00806F050000.json create mode 100644 crates/intel-dcap-api/tests/test_data/tdx_tcb_info_eval17.json diff --git a/Cargo.lock b/Cargo.lock index ce4e04e..565b002 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -372,6 +372,16 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "155a5a185e42c6b77ac7b88a15143d930a9e9727a5b7b77eed417404ab15c247" +[[package]] +name = "assert-json-diff" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e4f2b81832e72834d7518d8487a0396a28cc408186a2e8854c0f98011faf12" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "async-stream" version = "0.3.6" @@ -1000,6 +1010,15 @@ dependencies = [ "x509-cert", ] +[[package]] +name = "colored" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e" +dependencies = [ + "windows-sys 0.59.0", +] + [[package]] name = "combine" version = "4.6.7" @@ -2607,7 +2626,9 @@ dependencies = [ name = "intel-dcap-api" version = "0.3.0" dependencies = [ + "base64", "hex", + "mockito", "percent-encoding", "reqwest", "serde", @@ -3044,6 +3065,30 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "mockito" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7760e0e418d9b7e5777c0374009ca4c93861b9066f18cb334a20ce50ab63aa48" +dependencies = [ + "assert-json-diff", + "bytes", + "colored", + "futures-util", + "http 1.2.0", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "log", + "rand 0.9.0", + "regex", + "serde_json", + "serde_urlencoded", + "similar", + "tokio", +] + [[package]] name = "mutually_exclusive_features" version = "0.1.0" @@ -4616,6 +4661,12 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "similar" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" + [[package]] name = "simple-bytes" version = "0.2.14" diff --git a/crates/intel-dcap-api/CLAUDE.md b/crates/intel-dcap-api/CLAUDE.md new file mode 100644 index 0000000..d2a01b3 --- /dev/null +++ b/crates/intel-dcap-api/CLAUDE.md @@ -0,0 +1,128 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Overview + +This crate (`intel-dcap-api`) is a Rust client library for Intel's Data Center Attestation Primitives (DCAP) API. It +provides access to Intel's Trusted Services API for SGX and TDX attestation, including TCB info, PCK certificates, CRLs, +and enclave identity verification. + +## Features + +- Support for both API v3 and v4 +- Async/await API using tokio +- Comprehensive error handling with Intel-specific error codes +- Type-safe request/response structures +- Support for SGX and TDX platforms +- Real data integration tests + +## Development Commands + +```bash +# Build +cargo build +cargo build --no-default-features --features rustls # Use rustls instead of default TLS + +# Test +cargo test + +# Lint +cargo clippy + +# Examples +cargo run --example example # Basic usage example +cargo run --example get_pck_crl # Fetch certificate revocation lists +cargo run --example common_usage # Common attestation verification patterns +cargo run --example integration_test # Comprehensive test of most API endpoints +cargo run --example fetch_test_data # Fetch real data from Intel API for tests +``` + +## Architecture + +### Client Structure + +- **ApiClient** (`src/client/mod.rs`): Main entry point supporting API v3/v4 + - Base URL: https://api.trustedservices.intel.com + - Manages HTTP client and API version selection + +### Key Modules + +- **client/**: API endpoint implementations + - `tcb_info`: SGX/TDX TCB information retrieval + - `get_sgx_tcb_info()`, `get_tdx_tcb_info()` + - `pck_cert`: PCK certificate operations + - `get_pck_certificate_by_ppid()`, `get_pck_certificate_by_manifest()` + - `get_pck_certificates_by_ppid()`, `get_pck_certificates_by_manifest()` + - `get_pck_certificates_config_by_ppid()`, `get_pck_certificates_config_by_manifest()` + - `pck_crl`: Certificate revocation lists + - `get_pck_crl()` - supports PEM and DER encoding + - `enclave_identity`: SGX QE/QVE/QAE/TDQE identity + - `get_sgx_qe_identity()`, `get_sgx_qve_identity()`, `get_sgx_qae_identity()`, `get_tdx_qe_identity()` + - `fmspc`: FMSPC-related operations (V4 only) + - `get_fmspcs()` - with optional platform filter + - `get_sgx_tcb_evaluation_data_numbers()`, `get_tdx_tcb_evaluation_data_numbers()` + - `registration`: Platform registration + - `register_platform()`, `add_package()` + +### Core Types + +- **error.rs**: `IntelApiError` for comprehensive error handling + - Extracts error details from Error-Code and Error-Message headers +- **types.rs**: Enums (CaType, ApiVersion, UpdateType, etc.) +- **requests.rs**: Request structures +- **responses.rs**: Response structures with JSON and certificate data + +### API Pattern + +All client methods follow this pattern: + +1. Build request with query parameters +2. Send HTTP request with proper headers +3. Parse response (JSON + certificate chains) +4. Return typed response or error + +### Testing Strategy + +- **Mock Tests**: Two test suites using mockito for HTTP mocking + - `tests/mock_api_tests.rs`: Basic API functionality tests with simple data (11 tests) + - `tests/real_data_mock_tests.rs`: Tests using real Intel API responses (25 tests) +- **Test Data**: Real responses stored in `tests/test_data/` (JSON format) + - Fetched using `cargo run --example fetch_test_data` + - Includes TCB info, CRLs, enclave identities for both SGX and TDX + - Covers V3 and V4 API variations, different update types, and evaluation data numbers +- **Key Testing Considerations**: + - Headers with newlines must be URL-encoded for mockito (use `percent_encode` with `NON_ALPHANUMERIC`) + - V3 vs V4 API use different header names: + - V3: `SGX-TCB-Info-Issuer-Chain` + - V4: `TCB-Info-Issuer-Chain` + - Error responses include Error-Code and Error-Message headers + - Examples use real Intel API endpoints + - Test data (FMSPC, PPID) from Intel documentation + - Async tests require tokio runtime + +## API Version Differences + +### V4-Only Features + +- FMSPC listing (`get_fmspcs()`) +- TCB Evaluation Data Numbers endpoints +- PPID encryption key type parameter +- TDX QE identity endpoint + +## Common Pitfalls + +1. **Mockito Header Encoding**: Always URL-encode headers containing newlines/special characters +2. **API Version Selection**: Some endpoints are V4-only and will return errors on V3 +4. **Platform Filters**: Only certain values are valid (All, Client, E3, E5) +5. **Test Data**: PCK certificate endpoints require valid platform data and often need subscription keys +6. **Issuer Chain Validation**: Always check that `issuer_chain` is non-empty - it's critical for signature verification + +## Security Considerations + +- **Certificate Chain Verification**: The `issuer_chain` field contains the certificates needed to verify the signature + of the response data +- **Signature Validation**: All JSON responses (TCB info, enclave identities) should have their signatures verified + using the issuer chain +- **CRL Verification**: PCK CRLs must be signature-verified before being used for certificate revocation checking +- **Empty Issuer Chains**: Always validate that issuer chains are present and non-empty before trusting response data diff --git a/crates/intel-dcap-api/Cargo.toml b/crates/intel-dcap-api/Cargo.toml index d51993f..310daf7 100644 --- a/crates/intel-dcap-api/Cargo.toml +++ b/crates/intel-dcap-api/Cargo.toml @@ -11,6 +11,7 @@ keywords = ["sgx", "tdx", "intel", "attestation", "confidential"] categories = ["api-bindings", "cryptography", "authentication"] [dependencies] +base64.workspace = true percent-encoding = "2.3.1" reqwest = { workspace = true, features = ["json"] } serde.workspace = true @@ -20,9 +21,15 @@ tokio.workspace = true url.workspace = true [dev-dependencies] +base64.workspace = true hex.workspace = true +mockito = "1.4" x509-cert.workspace = true +[[example]] +name = "integration_test" +required-features = ["default"] + [features] default = ["reqwest/default-tls"] rustls = ["reqwest/rustls-tls"] diff --git a/crates/intel-dcap-api/examples/common_usage.rs b/crates/intel-dcap-api/examples/common_usage.rs new file mode 100644 index 0000000..e276787 --- /dev/null +++ b/crates/intel-dcap-api/examples/common_usage.rs @@ -0,0 +1,182 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright (c) 2025 Matter Labs + +use intel_dcap_api::{ApiClient, CaType, IntelApiError, UpdateType}; + +/// Common usage patterns for the Intel DCAP API client +/// +/// This example demonstrates typical use cases for attestation verification. +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a client (defaults to V4 API) + let client = ApiClient::new()?; + + // Example 1: Get TCB info for quote verification + println!("Example 1: Getting TCB info for SGX quote verification"); + println!("======================================================"); + + let fmspc = "00906ED50000"; // From SGX quote + + match client.get_sgx_tcb_info(fmspc, None, None).await { + Ok(response) => { + // Critical: Check that issuer chain is present for signature verification + if response.issuer_chain.is_empty() { + println!("โœ— Error: Empty issuer chain - cannot verify TCB info signature!"); + return Ok(()); + } + + println!("โœ“ Retrieved TCB info for FMSPC: {}", fmspc); + + // Parse the TCB info + let tcb_info: serde_json::Value = serde_json::from_str(&response.tcb_info_json)?; + + // Extract useful information + if let Some(tcb_levels) = tcb_info["tcbInfo"]["tcbLevels"].as_array() { + println!(" Found {} TCB levels", tcb_levels.len()); + + // Show the latest TCB level + if let Some(latest) = tcb_levels.first() { + println!(" Latest TCB level:"); + if let Some(status) = latest["tcbStatus"].as_str() { + println!(" Status: {}", status); + } + if let Some(date) = latest["tcbDate"].as_str() { + println!(" Date: {}", date); + } + } + } + + // The issuer chain is needed to verify the signature + println!( + " Issuer chain length: {} bytes", + response.issuer_chain.len() + ); + // Verify we have certificate chain for signature verification + let cert_count = response.issuer_chain.matches("BEGIN CERTIFICATE").count(); + println!(" Certificate chain contains {} certificates", cert_count); + } + Err(IntelApiError::ApiError { + status, + error_message, + .. + }) => { + println!( + "โœ— API Error {}: {}", + status, + error_message.unwrap_or_default() + ); + } + Err(e) => { + println!("โœ— Error: {:?}", e); + } + } + + println!(); + + // Example 2: Get QE identity for enclave verification + println!("Example 2: Getting QE identity for enclave verification"); + println!("======================================================"); + + match client.get_sgx_qe_identity(None, None).await { + Ok(response) => { + // Critical: Check that issuer chain is present for signature verification + if response.issuer_chain.is_empty() { + println!("โœ— Error: Empty issuer chain - cannot verify QE identity signature!"); + return Ok(()); + } + + println!("โœ“ Retrieved QE identity"); + println!( + " Issuer chain length: {} bytes", + response.issuer_chain.len() + ); + + let identity: serde_json::Value = + serde_json::from_str(&response.enclave_identity_json)?; + + if let Some(enclave_id) = identity["enclaveIdentity"]["id"].as_str() { + println!(" Enclave ID: {}", enclave_id); + } + + if let Some(version) = identity["enclaveIdentity"]["version"].as_u64() { + println!(" Version: {}", version); + } + + if let Some(mrsigner) = identity["enclaveIdentity"]["mrsigner"].as_str() { + println!(" MRSIGNER: {}...", &mrsigner[..16]); + } + } + Err(e) => { + println!("โœ— Failed to get QE identity: {:?}", e); + } + } + + println!(); + + // Example 3: Check certificate revocation + println!("Example 3: Checking certificate revocation status"); + println!("================================================"); + + match client.get_pck_crl(CaType::Processor, None).await { + Ok(response) => { + // Critical: Check that issuer chain is present for CRL verification + if response.issuer_chain.is_empty() { + println!("โœ— Error: Empty issuer chain - cannot verify CRL signature!"); + return Ok(()); + } + + println!("โœ“ Retrieved PCK CRL"); + println!( + " Issuer chain length: {} bytes", + response.issuer_chain.len() + ); + + let crl_pem = String::from_utf8_lossy(&response.crl_data); + + // In real usage, you would parse this CRL and check if a certificate is revoked + if crl_pem.contains("BEGIN X509 CRL") { + println!(" CRL format: PEM"); + println!(" CRL size: {} bytes", crl_pem.len()); + + // Count the revoked certificates (naive approach) + let revoked_count = crl_pem.matches("Serial Number:").count(); + println!(" Approximate revoked certificates: {}", revoked_count); + } + } + Err(e) => { + println!("โœ— Failed to get CRL: {:?}", e); + } + } + + println!(); + + // Example 4: Early update for testing + println!("Example 4: Getting early TCB update (for testing)"); + println!("================================================"); + + match client + .get_sgx_tcb_info(fmspc, Some(UpdateType::Early), None) + .await + { + Ok(response) => { + println!("โœ“ Retrieved early TCB update"); + + let tcb_info: serde_json::Value = serde_json::from_str(&response.tcb_info_json)?; + + if let Some(next_update) = tcb_info["tcbInfo"]["nextUpdate"].as_str() { + println!(" Next update: {}", next_update); + } + } + Err(IntelApiError::ApiError { status, .. }) if status.as_u16() == 404 => { + println!(" No early update available (this is normal)"); + } + Err(e) => { + println!("โœ— Error: {:?}", e); + } + } + + println!(); + println!("Done! These examples show common patterns for attestation verification."); + + Ok(()) +} diff --git a/crates/intel-dcap-api/examples/fetch_test_data.rs b/crates/intel-dcap-api/examples/fetch_test_data.rs new file mode 100644 index 0000000..be32fdf --- /dev/null +++ b/crates/intel-dcap-api/examples/fetch_test_data.rs @@ -0,0 +1,515 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright (c) 2025 Matter Labs + +use base64::{engine::general_purpose, Engine as _}; +use intel_dcap_api::{ApiClient, ApiVersion, CaType, CrlEncoding, PlatformFilter, UpdateType}; +use std::{fs, path::Path}; + +/// Fetch real data from Intel API and save it as JSON files +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create test data directory + let test_data_dir = Path::new("tests/test_data"); + fs::create_dir_all(test_data_dir)?; + + let client = ApiClient::new()?; + + println!("Fetching real test data from Intel API..."); + + // Keep track of successful fetches + let mut successes: Vec = Vec::new(); + let mut failures: Vec = Vec::new(); + + // 1. Fetch SGX TCB info + println!("\n1. Fetching SGX TCB info..."); + match client + .get_sgx_tcb_info("00606A6A0000", Some(UpdateType::Standard), None) + .await + { + Ok(response) => { + let data = serde_json::json!({ + "tcb_info_json": response.tcb_info_json, + "issuer_chain": response.issuer_chain, + }); + fs::write( + test_data_dir.join("sgx_tcb_info.json"), + serde_json::to_string_pretty(&data)?, + )?; + successes.push("SGX TCB info".to_string()); + } + Err(e) => { + failures.push(format!("SGX TCB info: {}", e)); + } + } + + // 2. Fetch TDX TCB info + println!("\n2. Fetching TDX TCB info..."); + match client + .get_tdx_tcb_info("00806F050000", Some(UpdateType::Standard), None) + .await + { + Ok(response) => { + let data = serde_json::json!({ + "tcb_info_json": response.tcb_info_json, + "issuer_chain": response.issuer_chain, + }); + fs::write( + test_data_dir.join("tdx_tcb_info.json"), + serde_json::to_string_pretty(&data)?, + )?; + successes.push("TDX TCB info".to_string()); + } + Err(e) => { + failures.push(format!("TDX TCB info: {}", e)); + } + } + + // 3. Fetch PCK CRL for processor + println!("\n3. Fetching PCK CRL (processor)..."); + match client.get_pck_crl(CaType::Processor, None).await { + Ok(response) => { + let crl_string = String::from_utf8_lossy(&response.crl_data); + let data = serde_json::json!({ + "crl_data": crl_string, + "issuer_chain": response.issuer_chain, + }); + fs::write( + test_data_dir.join("pck_crl_processor.json"), + serde_json::to_string_pretty(&data)?, + )?; + successes.push("PCK CRL (processor)".to_string()); + } + Err(e) => { + failures.push(format!("PCK CRL (processor): {}", e)); + } + } + + // 4. Fetch PCK CRL for platform + println!("\n4. Fetching PCK CRL (platform)..."); + match client.get_pck_crl(CaType::Platform, None).await { + Ok(response) => { + let crl_string = String::from_utf8_lossy(&response.crl_data); + let data = serde_json::json!({ + "crl_data": crl_string, + "issuer_chain": response.issuer_chain, + }); + fs::write( + test_data_dir.join("pck_crl_platform.json"), + serde_json::to_string_pretty(&data)?, + )?; + successes.push("PCK CRL (platform)".to_string()); + } + Err(e) => { + failures.push(format!("PCK CRL (platform): {}", e)); + } + } + + // 5. Fetch SGX QE identity + println!("\n5. Fetching SGX QE identity..."); + match client.get_sgx_qe_identity(None, None).await { + Ok(response) => { + let data = serde_json::json!({ + "enclave_identity_json": response.enclave_identity_json, + "issuer_chain": response.issuer_chain, + }); + fs::write( + test_data_dir.join("sgx_qe_identity.json"), + serde_json::to_string_pretty(&data)?, + )?; + successes.push("SGX QE identity".to_string()); + } + Err(e) => { + failures.push(format!("SGX QE identity: {}", e)); + } + } + + // 6. Fetch SGX QVE identity + println!("\n6. Fetching SGX QVE identity..."); + match client.get_sgx_qve_identity(None, None).await { + Ok(response) => { + let data = serde_json::json!({ + "enclave_identity_json": response.enclave_identity_json, + "issuer_chain": response.issuer_chain, + }); + fs::write( + test_data_dir.join("sgx_qve_identity.json"), + serde_json::to_string_pretty(&data)?, + )?; + successes.push("SGX QVE identity".to_string()); + } + Err(e) => { + failures.push(format!("SGX QVE identity: {}", e)); + } + } + + // 7. Fetch TDX QE identity + println!("\n7. Fetching TDX QE identity..."); + match client.get_tdx_qe_identity(None, None).await { + Ok(response) => { + let data = serde_json::json!({ + "enclave_identity_json": response.enclave_identity_json, + "issuer_chain": response.issuer_chain, + }); + fs::write( + test_data_dir.join("tdx_qe_identity.json"), + serde_json::to_string_pretty(&data)?, + )?; + successes.push("TDX QE identity".to_string()); + } + Err(e) => { + failures.push(format!("TDX QE identity: {}", e)); + } + } + + // 8. Try an alternative FMSPC + println!("\n8. Fetching alternative SGX TCB info..."); + match client.get_sgx_tcb_info("00906ED50000", None, None).await { + Ok(response) => { + let data = serde_json::json!({ + "tcb_info_json": response.tcb_info_json, + "issuer_chain": response.issuer_chain, + }); + fs::write( + test_data_dir.join("sgx_tcb_info_alt.json"), + serde_json::to_string_pretty(&data)?, + )?; + successes.push("Alternative SGX TCB info".to_string()); + } + Err(e) => { + failures.push(format!("Alternative SGX TCB info: {}", e)); + } + } + + // 9. Fetch PCK certificate + println!("\n9. Attempting to fetch PCK certificate..."); + let ppid = "3d6dd97e96f84536a2267e727dd860e4fdd3ffa3e319db41e8f69c9a43399e7b7ce97d7eb3bd05b0a58bdb5b90a0e218"; + let cpusvn = "0606060606060606060606060606060606060606060606060606060606060606"; + let pcesvn = "0a00"; + let pceid = "0000"; + + match client + .get_pck_certificate_by_ppid(ppid, cpusvn, pcesvn, pceid, None, None) + .await + { + Ok(response) => { + let data = serde_json::json!({ + "pck_cert_pem": response.pck_cert_pem, + "issuer_chain": response.issuer_chain, + "tcbm": response.tcbm, + "fmspc": response.fmspc, + }); + fs::write( + test_data_dir.join("pck_cert.json"), + serde_json::to_string_pretty(&data)?, + )?; + successes.push("PCK certificate".to_string()); + } + Err(e) => { + failures.push(format!("PCK certificate: {}", e)); + } + } + + // 10. Fetch SGX QAE identity + println!("\n10. Fetching SGX QAE identity..."); + match client.get_sgx_qae_identity(None, None).await { + Ok(response) => { + let data = serde_json::json!({ + "enclave_identity_json": response.enclave_identity_json, + "issuer_chain": response.issuer_chain, + }); + fs::write( + test_data_dir.join("sgx_qae_identity.json"), + serde_json::to_string_pretty(&data)?, + )?; + successes.push("SGX QAE identity".to_string()); + } + Err(e) => { + failures.push(format!("SGX QAE identity: {}", e)); + } + } + + // 11. Fetch FMSPCs + println!("\n11. Fetching FMSPCs..."); + match client.get_fmspcs(Some(PlatformFilter::All)).await { + Ok(fmspcs_json) => { + let data = serde_json::json!({ + "fmspcs_json": fmspcs_json, + }); + fs::write( + test_data_dir.join("fmspcs.json"), + serde_json::to_string_pretty(&data)?, + )?; + successes.push("FMSPCs".to_string()); + } + Err(e) => { + failures.push(format!("FMSPCs: {}", e)); + } + } + + // 12. Fetch SGX TCB evaluation data numbers + println!("\n12. Fetching SGX TCB evaluation data numbers..."); + match client.get_sgx_tcb_evaluation_data_numbers().await { + Ok(response) => { + let data = serde_json::json!({ + "tcb_evaluation_data_numbers_json": response.tcb_evaluation_data_numbers_json, + "issuer_chain": response.issuer_chain, + }); + fs::write( + test_data_dir.join("sgx_tcb_eval_nums.json"), + serde_json::to_string_pretty(&data)?, + )?; + successes.push("SGX TCB evaluation data numbers".to_string()); + } + Err(e) => { + failures.push(format!("SGX TCB evaluation data numbers: {}", e)); + } + } + + // 13. Fetch TDX TCB evaluation data numbers + println!("\n13. Fetching TDX TCB evaluation data numbers..."); + match client.get_tdx_tcb_evaluation_data_numbers().await { + Ok(response) => { + let data = serde_json::json!({ + "tcb_evaluation_data_numbers_json": response.tcb_evaluation_data_numbers_json, + "issuer_chain": response.issuer_chain, + }); + fs::write( + test_data_dir.join("tdx_tcb_eval_nums.json"), + serde_json::to_string_pretty(&data)?, + )?; + successes.push("TDX TCB evaluation data numbers".to_string()); + } + Err(e) => { + failures.push(format!("TDX TCB evaluation data numbers: {}", e)); + } + } + + // 14. Fetch PCK CRL with DER encoding + println!("\n14. Fetching PCK CRL (processor, DER encoding)..."); + match client + .get_pck_crl(CaType::Processor, Some(CrlEncoding::Der)) + .await + { + Ok(response) => { + // For DER, save as base64 + let crl_base64 = general_purpose::STANDARD.encode(&response.crl_data); + let data = serde_json::json!({ + "crl_data_base64": crl_base64, + "issuer_chain": response.issuer_chain, + }); + fs::write( + test_data_dir.join("pck_crl_processor_der.json"), + serde_json::to_string_pretty(&data)?, + )?; + successes.push("PCK CRL (processor, DER)".to_string()); + } + Err(e) => { + failures.push(format!("PCK CRL (processor, DER): {}", e)); + } + } + + // 15. Try different update types + println!("\n15. Fetching SGX TCB info with Early update..."); + match client + .get_sgx_tcb_info("00906ED50000", Some(UpdateType::Early), None) + .await + { + Ok(response) => { + let data = serde_json::json!({ + "tcb_info_json": response.tcb_info_json, + "issuer_chain": response.issuer_chain, + }); + fs::write( + test_data_dir.join("sgx_tcb_info_early.json"), + serde_json::to_string_pretty(&data)?, + )?; + successes.push("SGX TCB info (Early update)".to_string()); + } + Err(e) => { + failures.push(format!("SGX TCB info (Early update): {}", e)); + } + } + + // 16. Try with specific TCB evaluation data number + println!("\n16. Fetching TDX TCB info with specific evaluation number..."); + match client + .get_tdx_tcb_info("00806F050000", None, Some(17)) + .await + { + Ok(response) => { + let data = serde_json::json!({ + "tcb_info_json": response.tcb_info_json, + "issuer_chain": response.issuer_chain, + }); + fs::write( + test_data_dir.join("tdx_tcb_info_eval17.json"), + serde_json::to_string_pretty(&data)?, + )?; + successes.push("TDX TCB info (eval number 17)".to_string()); + } + Err(e) => { + failures.push(format!("TDX TCB info (eval number 17): {}", e)); + } + } + + // 17. Try different FMSPCs + println!("\n17. Fetching more SGX TCB info variations..."); + let test_fmspcs = vec!["00906ED50000", "00906C0F0000", "00A06F050000"]; + for fmspc in test_fmspcs { + match client.get_sgx_tcb_info(fmspc, None, None).await { + Ok(response) => { + let data = serde_json::json!({ + "tcb_info_json": response.tcb_info_json, + "issuer_chain": response.issuer_chain, + }); + fs::write( + test_data_dir.join(format!("sgx_tcb_info_{}.json", fmspc)), + serde_json::to_string_pretty(&data)?, + )?; + successes.push(format!("SGX TCB info (FMSPC: {})", fmspc)); + } + Err(e) => { + failures.push(format!("SGX TCB info (FMSPC: {}): {}", fmspc, e)); + } + } + } + + // 18. Try FMSPCs with different platform filters + println!("\n18. Fetching FMSPCs with different platform filters..."); + match client.get_fmspcs(None).await { + Ok(fmspcs_json) => { + let data = serde_json::json!({ + "fmspcs_json": fmspcs_json, + }); + fs::write( + test_data_dir.join("fmspcs_no_filter.json"), + serde_json::to_string_pretty(&data)?, + )?; + successes.push("FMSPCs (no filter)".to_string()); + } + Err(e) => { + failures.push(format!("FMSPCs (no filter): {}", e)); + } + } + + match client.get_fmspcs(Some(PlatformFilter::All)).await { + Ok(fmspcs_json) => { + let data = serde_json::json!({ + "fmspcs_json": fmspcs_json, + }); + fs::write( + test_data_dir.join("fmspcs_all_platforms.json"), + serde_json::to_string_pretty(&data)?, + )?; + successes.push("FMSPCs (all platforms)".to_string()); + } + Err(e) => { + failures.push(format!("FMSPCs (all platforms): {}", e)); + } + } + + // 19. Try PCK certificates with different parameters (encrypted PPID) + println!("\n19. Attempting to fetch PCK certificates with different params..."); + // Try with a different encrypted PPID format + let encrypted_ppid = "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + let pceid = "0000"; + + match client + .get_pck_certificates_by_ppid(encrypted_ppid, pceid, None, None) + .await + { + Ok(response) => { + let data = serde_json::json!({ + "pck_certificates_json": response.pck_certs_json, + "issuer_chain": response.issuer_chain, + "fmspc": response.fmspc, + }); + fs::write( + test_data_dir.join("pck_certificates.json"), + serde_json::to_string_pretty(&data)?, + )?; + successes.push("PCK certificates (by PPID)".to_string()); + } + Err(e) => { + failures.push(format!("PCK certificates (by PPID): {}", e)); + } + } + + // 20. Try TDX TCB info with different FMSPCs + println!("\n20. Fetching TDX TCB info variations..."); + let tdx_fmspcs = vec!["00806F050000", "00A06F050000", "00606A0000000"]; + for fmspc in tdx_fmspcs { + match client.get_tdx_tcb_info(fmspc, None, None).await { + Ok(response) => { + let data = serde_json::json!({ + "tcb_info_json": response.tcb_info_json, + "issuer_chain": response.issuer_chain, + }); + fs::write( + test_data_dir.join(format!("tdx_tcb_info_{}.json", fmspc)), + serde_json::to_string_pretty(&data)?, + )?; + successes.push(format!("TDX TCB info (FMSPC: {})", fmspc)); + } + Err(e) => { + failures.push(format!("TDX TCB info (FMSPC: {}): {}", fmspc, e)); + } + } + } + + // 21. Try with V3 API for some endpoints + println!("\n21. Testing V3 API endpoints..."); + let v3_client = + ApiClient::new_with_options("https://api.trustedservices.intel.com", ApiVersion::V3)?; + + match v3_client.get_sgx_tcb_info("00906ED50000", None, None).await { + Ok(response) => { + let data = serde_json::json!({ + "tcb_info_json": response.tcb_info_json, + "issuer_chain": response.issuer_chain, + }); + fs::write( + test_data_dir.join("sgx_tcb_info_v3.json"), + serde_json::to_string_pretty(&data)?, + )?; + successes.push("SGX TCB info (V3 API)".to_string()); + } + Err(e) => { + failures.push(format!("SGX TCB info (V3 API): {}", e)); + } + } + + match v3_client.get_sgx_qe_identity(None, None).await { + Ok(response) => { + let data = serde_json::json!({ + "enclave_identity_json": response.enclave_identity_json, + "issuer_chain": response.issuer_chain, + }); + fs::write( + test_data_dir.join("sgx_qe_identity_v3.json"), + serde_json::to_string_pretty(&data)?, + )?; + successes.push("SGX QE identity (V3 API)".to_string()); + } + Err(e) => { + failures.push(format!("SGX QE identity (V3 API): {}", e)); + } + } + + println!("\n\nTest data fetching complete!"); + println!("\nSuccessful fetches:"); + for s in &successes { + println!(" โœ“ {}", s); + } + + if !failures.is_empty() { + println!("\nFailed fetches:"); + for f in &failures { + println!(" โœ— {}", f); + } + } + + println!("\nData saved in: {}", test_data_dir.display()); + + Ok(()) +} diff --git a/crates/intel-dcap-api/examples/integration_test.rs b/crates/intel-dcap-api/examples/integration_test.rs new file mode 100644 index 0000000..b88088f --- /dev/null +++ b/crates/intel-dcap-api/examples/integration_test.rs @@ -0,0 +1,495 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright (c) 2025 Matter Labs + +use intel_dcap_api::{ + ApiClient, ApiVersion, CaType, CrlEncoding, IntelApiError, PlatformFilter, UpdateType, +}; +use std::time::Duration; +use tokio::time::sleep; + +/// Comprehensive integration test example demonstrating most Intel DCAP API client functions +/// +/// This example shows how to use various endpoints of the Intel Trusted Services API. +/// Note: Some operations may fail with 404 or 400 errors if the data doesn't exist on Intel's servers. +#[tokio::main] +async fn main() -> Result<(), Box> { + println!("=== Intel DCAP API Integration Test Example ===\n"); + + // Create clients for both V3 and V4 APIs + let v4_client = ApiClient::new()?; + let v3_client = + ApiClient::new_with_options("https://api.trustedservices.intel.com", ApiVersion::V3)?; + + // Track successes and failures + let mut results = Vec::new(); + + // Test FMSPC - commonly used for TCB lookups + let test_fmspc = "00906ED50000"; + let test_fmspc_tdx = "00806F050000"; + + println!("1. Testing TCB Info Endpoints..."); + println!("================================"); + + // 1.1 SGX TCB Info (V4) + print!(" - SGX TCB Info (V4): "); + match v4_client.get_sgx_tcb_info(test_fmspc, None, None).await { + Ok(response) => { + if response.issuer_chain.is_empty() { + println!("โœ— Failed: Empty issuer chain"); + results.push(("SGX TCB Info (V4)", false)); + } else { + println!("โœ“ Success"); + println!(" FMSPC: {}", test_fmspc); + println!(" Issuer chain: {} bytes", response.issuer_chain.len()); + let tcb_info: serde_json::Value = serde_json::from_str(&response.tcb_info_json)?; + if let Some(version) = tcb_info["tcbInfo"]["version"].as_u64() { + println!(" TCB Info Version: {}", version); + } + results.push(("SGX TCB Info (V4)", true)); + } + } + Err(e) => { + println!("โœ— Failed: {:?}", e); + results.push(("SGX TCB Info (V4)", false)); + } + } + + // Add small delay between requests to be nice to the API + sleep(Duration::from_millis(100)).await; + + // 1.2 SGX TCB Info (V3) + print!(" - SGX TCB Info (V3): "); + match v3_client.get_sgx_tcb_info(test_fmspc, None, None).await { + Ok(response) => { + if response.issuer_chain.is_empty() { + println!("โœ— Failed: Empty issuer chain"); + results.push(("SGX TCB Info (V3)", false)); + } else { + println!("โœ“ Success"); + println!(" Issuer chain: {} bytes", response.issuer_chain.len()); + results.push(("SGX TCB Info (V3)", true)); + } + } + Err(e) => { + println!("โœ— Failed: {:?}", e); + results.push(("SGX TCB Info (V3)", false)); + } + } + + sleep(Duration::from_millis(100)).await; + + // 1.3 TDX TCB Info + print!(" - TDX TCB Info: "); + match v4_client.get_tdx_tcb_info(test_fmspc_tdx, None, None).await { + Ok(response) => { + if response.issuer_chain.is_empty() { + println!("โœ— Failed: Empty issuer chain"); + results.push(("TDX TCB Info", false)); + } else { + println!("โœ“ Success"); + println!(" Issuer chain: {} bytes", response.issuer_chain.len()); + let tcb_info: serde_json::Value = serde_json::from_str(&response.tcb_info_json)?; + if let Some(id) = tcb_info["tcbInfo"]["id"].as_str() { + println!(" Platform: {}", id); + } + results.push(("TDX TCB Info", true)); + } + } + Err(e) => { + println!("โœ— Failed: {:?}", e); + results.push(("TDX TCB Info", false)); + } + } + + sleep(Duration::from_millis(100)).await; + + // 1.4 SGX TCB Info with Early Update + print!(" - SGX TCB Info (Early Update): "); + match v4_client + .get_sgx_tcb_info(test_fmspc, Some(UpdateType::Early), None) + .await + { + Ok(response) => { + if response.issuer_chain.is_empty() { + println!("โœ— Failed: Empty issuer chain"); + results.push(("SGX TCB Info (Early)", false)); + } else { + println!("โœ“ Success"); + println!(" Issuer chain: {} bytes", response.issuer_chain.len()); + results.push(("SGX TCB Info (Early)", true)); + } + } + Err(e) => { + println!("โœ— Failed: {:?}", e); + results.push(("SGX TCB Info (Early)", false)); + } + } + + sleep(Duration::from_millis(100)).await; + + println!("\n2. Testing Enclave Identity Endpoints..."); + println!("========================================"); + + // 2.1 SGX QE Identity + print!(" - SGX QE Identity: "); + match v4_client.get_sgx_qe_identity(None, None).await { + Ok(response) => { + if response.issuer_chain.is_empty() { + println!("โœ— Failed: Empty issuer chain"); + results.push(("SGX QE Identity", false)); + } else { + println!("โœ“ Success"); + println!(" Issuer chain: {} bytes", response.issuer_chain.len()); + let identity: serde_json::Value = + serde_json::from_str(&response.enclave_identity_json)?; + if let Some(id) = identity["enclaveIdentity"]["id"].as_str() { + println!(" Enclave ID: {}", id); + } + results.push(("SGX QE Identity", true)); + } + } + Err(e) => { + println!("โœ— Failed: {:?}", e); + results.push(("SGX QE Identity", false)); + } + } + + sleep(Duration::from_millis(100)).await; + + // 2.2 SGX QVE Identity + print!(" - SGX QVE Identity: "); + match v4_client.get_sgx_qve_identity(None, None).await { + Ok(response) => { + if response.issuer_chain.is_empty() { + println!("โœ— Failed: Empty issuer chain"); + results.push(("SGX QVE Identity", false)); + } else { + println!("โœ“ Success"); + println!(" Issuer chain: {} bytes", response.issuer_chain.len()); + results.push(("SGX QVE Identity", true)); + } + } + Err(e) => { + println!("โœ— Failed: {:?}", e); + results.push(("SGX QVE Identity", false)); + } + } + + sleep(Duration::from_millis(100)).await; + + // 2.3 SGX QAE Identity + print!(" - SGX QAE Identity: "); + match v4_client.get_sgx_qae_identity(None, None).await { + Ok(response) => { + if response.issuer_chain.is_empty() { + println!("โœ— Failed: Empty issuer chain"); + results.push(("SGX QAE Identity", false)); + } else { + println!("โœ“ Success"); + println!(" Issuer chain: {} bytes", response.issuer_chain.len()); + results.push(("SGX QAE Identity", true)); + } + } + Err(e) => { + println!("โœ— Failed: {:?}", e); + results.push(("SGX QAE Identity", false)); + } + } + + sleep(Duration::from_millis(100)).await; + + // 2.4 TDX QE Identity (V4 only) + print!(" - TDX QE Identity: "); + match v4_client.get_tdx_qe_identity(None, None).await { + Ok(response) => { + if response.issuer_chain.is_empty() { + println!("โœ— Failed: Empty issuer chain"); + results.push(("TDX QE Identity", false)); + } else { + println!("โœ“ Success"); + println!(" Issuer chain: {} bytes", response.issuer_chain.len()); + results.push(("TDX QE Identity", true)); + } + } + Err(e) => { + println!("โœ— Failed: {:?}", e); + results.push(("TDX QE Identity", false)); + } + } + + sleep(Duration::from_millis(100)).await; + + println!("\n3. Testing PCK CRL Endpoints..."); + println!("================================"); + + // 3.1 PCK CRL - Processor (PEM) + print!(" - PCK CRL (Processor, PEM): "); + match v4_client.get_pck_crl(CaType::Processor, None).await { + Ok(response) => { + if response.issuer_chain.is_empty() { + println!("โœ— Failed: Empty issuer chain"); + results.push(("PCK CRL (Processor)", false)); + } else { + println!("โœ“ Success"); + println!(" Issuer chain: {} bytes", response.issuer_chain.len()); + let crl_str = String::from_utf8_lossy(&response.crl_data); + if crl_str.contains("BEGIN X509 CRL") { + println!(" Format: PEM"); + } + results.push(("PCK CRL (Processor)", true)); + } + } + Err(e) => { + println!("โœ— Failed: {:?}", e); + results.push(("PCK CRL (Processor)", false)); + } + } + + sleep(Duration::from_millis(100)).await; + + // 3.2 PCK CRL - Platform (DER) + print!(" - PCK CRL (Platform, DER): "); + match v4_client + .get_pck_crl(CaType::Platform, Some(CrlEncoding::Der)) + .await + { + Ok(response) => { + if response.issuer_chain.is_empty() { + println!("โœ— Failed: Empty issuer chain"); + results.push(("PCK CRL (Platform, DER)", false)); + } else { + println!("โœ“ Success"); + println!(" Issuer chain: {} bytes", response.issuer_chain.len()); + println!(" CRL size: {} bytes", response.crl_data.len()); + results.push(("PCK CRL (Platform, DER)", true)); + } + } + Err(e) => { + println!("โœ— Failed: {:?}", e); + results.push(("PCK CRL (Platform, DER)", false)); + } + } + + sleep(Duration::from_millis(100)).await; + + println!("\n4. Testing FMSPC Endpoints (V4 only)..."); + println!("======================================="); + + // 4.1 Get FMSPCs (no filter) + print!(" - Get FMSPCs (no filter): "); + match v4_client.get_fmspcs(None).await { + Ok(fmspcs_json) => { + println!("โœ“ Success"); + let fmspcs: serde_json::Value = serde_json::from_str(&fmspcs_json)?; + if let Some(arr) = fmspcs.as_array() { + println!(" Total FMSPCs: {}", arr.len()); + // Show first few FMSPCs + for (i, fmspc) in arr.iter().take(3).enumerate() { + if let (Some(fmspc_val), Some(platform)) = + (fmspc["fmspc"].as_str(), fmspc["platform"].as_str()) + { + println!(" [{}] {} - {}", i + 1, fmspc_val, platform); + } + } + if arr.len() > 3 { + println!(" ... and {} more", arr.len() - 3); + } + } + results.push(("Get FMSPCs", true)); + } + Err(e) => { + println!("โœ— Failed: {:?}", e); + results.push(("Get FMSPCs", false)); + } + } + + sleep(Duration::from_millis(100)).await; + + // 4.2 Get FMSPCs with platform filter + print!(" - Get FMSPCs (All platforms): "); + match v4_client.get_fmspcs(Some(PlatformFilter::All)).await { + Ok(_) => { + println!("โœ“ Success"); + results.push(("Get FMSPCs (filtered)", true)); + } + Err(e) => { + println!("โœ— Failed: {:?}", e); + results.push(("Get FMSPCs (filtered)", false)); + } + } + + sleep(Duration::from_millis(100)).await; + + println!("\n5. Testing TCB Evaluation Data Numbers (V4 only)..."); + println!("==================================================="); + + // 5.1 SGX TCB Evaluation Data Numbers + print!(" - SGX TCB Evaluation Data Numbers: "); + match v4_client.get_sgx_tcb_evaluation_data_numbers().await { + Ok(response) => { + if response.issuer_chain.is_empty() { + println!("โœ— Failed: Empty issuer chain"); + results.push(("SGX TCB Eval Numbers", false)); + } else { + println!("โœ“ Success"); + println!(" Issuer chain: {} bytes", response.issuer_chain.len()); + let data: serde_json::Value = + serde_json::from_str(&response.tcb_evaluation_data_numbers_json)?; + if let Some(sgx_data) = data.get("sgx") { + println!( + " SGX entries: {}", + sgx_data.as_array().map(|a| a.len()).unwrap_or(0) + ); + } + results.push(("SGX TCB Eval Numbers", true)); + } + } + Err(e) => { + println!("โœ— Failed: {:?}", e); + results.push(("SGX TCB Eval Numbers", false)); + } + } + + sleep(Duration::from_millis(100)).await; + + // 5.2 TDX TCB Evaluation Data Numbers + print!(" - TDX TCB Evaluation Data Numbers: "); + match v4_client.get_tdx_tcb_evaluation_data_numbers().await { + Ok(response) => { + if response.issuer_chain.is_empty() { + println!("โœ— Failed: Empty issuer chain"); + results.push(("TDX TCB Eval Numbers", false)); + } else { + println!("โœ“ Success"); + println!(" Issuer chain: {} bytes", response.issuer_chain.len()); + let data: serde_json::Value = + serde_json::from_str(&response.tcb_evaluation_data_numbers_json)?; + if let Some(tdx_data) = data.get("tdx") { + println!( + " TDX entries: {}", + tdx_data.as_array().map(|a| a.len()).unwrap_or(0) + ); + } + results.push(("TDX TCB Eval Numbers", true)); + } + } + Err(e) => { + println!("โœ— Failed: {:?}", e); + results.push(("TDX TCB Eval Numbers", false)); + } + } + + sleep(Duration::from_millis(100)).await; + + println!("\n6. Testing PCK Certificate Endpoints..."); + println!("======================================="); + + /* // 6.1 PCK Certificate by PPID (usually requires valid data) + print!(" - PCK Certificate by PPID: "); + let test_ppid = "0000000000000000000000000000000000000000000000000000000000000000"; + let test_cpusvn = "00000000000000000000000000000000"; + let test_pcesvn = "0000"; + let test_pceid = "0000"; + + match v4_client + .get_pck_certificate_by_ppid(test_ppid, test_cpusvn, test_pcesvn, test_pceid, None, None) + .await + { + Ok(_) => { + println!("โœ“ Success"); + results.push(("PCK Certificate", true)); + } + Err(e) => { + // Expected to fail with test data + match &e { + IntelApiError::ApiError { status, .. } => { + println!("โœ— Failed (Expected): HTTP {}", status); + } + _ => println!("โœ— Failed: {:?}", e), + } + results.push(("PCK Certificate", false)); + } + } + + sleep(Duration::from_millis(100)).await; + */ + println!("\n7. Testing API Version Compatibility..."); + println!("======================================="); + + // 7.1 Try V4-only endpoint on V3 + print!(" - V4-only endpoint on V3 (should fail): "); + match v3_client.get_fmspcs(None).await { + Ok(_) => { + println!("โœ— Unexpected success!"); + results.push(("V3/V4 compatibility check", false)); + } + Err(IntelApiError::UnsupportedApiVersion(_)) => { + println!("โœ“ Correctly rejected"); + results.push(("V3/V4 compatibility check", true)); + } + Err(e) => { + println!("โœ— Wrong error: {:?}", e); + results.push(("V3/V4 compatibility check", false)); + } + } + + println!("\n8. Testing Error Handling..."); + println!("============================"); + + // 8.1 Invalid FMSPC + print!(" - Invalid FMSPC format: "); + match v4_client.get_sgx_tcb_info("invalid", None, None).await { + Ok(_) => { + println!("โœ— Unexpected success!"); + results.push(("Error handling", false)); + } + Err(IntelApiError::ApiError { + status, + error_code, + error_message, + .. + }) => { + println!("โœ“ Correctly handled"); + println!(" Status: {}", status); + if let Some(code) = error_code { + println!(" Error Code: {}", code); + } + if let Some(msg) = error_message { + println!(" Error Message: {}", msg); + } + results.push(("Error handling", true)); + } + Err(e) => { + println!("โœ— Unexpected error: {:?}", e); + results.push(("Error handling", false)); + } + } + + // Summary + println!("\n\n=== Summary ==="); + println!("==============="); + + let total = results.len(); + let successful = results.iter().filter(|(_, success)| *success).count(); + let failed = total - successful; + + println!("Total tests: {}", total); + println!( + "Successful: {} ({}%)", + successful, + (successful * 100) / total + ); + println!("Failed: {} ({}%)", failed, (failed * 100) / total); + + println!("\nDetailed Results:"); + for (test, success) in &results { + println!(" {} {}", if *success { "โœ“" } else { "โœ—" }, test); + } + + println!("\nNote: Some failures are expected due to:"); + println!("- Test data not existing on Intel servers"); + println!("- PCK operations requiring valid platform data"); + println!("- Subscription key requirements for certain endpoints"); + + Ok(()) +} diff --git a/crates/intel-dcap-api/specs/API spec V3.md b/crates/intel-dcap-api/specs/API spec V3.md new file mode 100644 index 0000000..59667cd --- /dev/null +++ b/crates/intel-dcap-api/specs/API spec V3.md @@ -0,0 +1,694 @@ +# Intelยฎ SGX and Intelยฎ TDX services - V3 API Documentation + +## Intelยฎ SGX and Intelยฎ TDX Registration Service for Scalable Platforms + +The API exposed by the Intel SGX registration service allows registering an Intelยฎ SGX platform with multiple processor +packages as a single platform instance, which can be remotely attested as a single entity later on[cite: 1]. The minimum +version of the TLS protocol supported by the service is 1.2; any connection attempts with previous versions of TLS/SSL +will be dropped by the server[cite: 2]. + +### Register Platform + +This API allows registering a multi-package SGX platform, covering initial registration and TCB Recovery[cite: 2]. +During registration, the platform manifest is authenticated by the Registration Service to verify it originates from a +genuine, non-revoked SGX platform[cite: 2]. If the platform configuration is successfully verified, platform +provisioning root keys are stored in the backend[cite: 2]. + +Stored platform provisioning root keys are later used to derive the public parts of Provisioning Certification Keys ( +PCKs)[cite: 2]. These PCKs are distributed as x.509 certificates by the Provisioning Certification Service for Intel SGX +and are used during the remote attestation of the platform[cite: 3]. + +#### POST `https://api.trustedservices.intel.com/sgx/registration/v1/platform` + +**Request** + +**Headers** + +Besides the headers explicitly mentioned below, the HTTP request may contain standard HTTP headers (e.g., +Content-Length)[cite: 3]. + +| Name | Required | Value | Description | +|:-------------|:---------|:---------------------------|:----------------------------------------| +| Content-Type | True | `application/octet-stream` | MIME type of the request body[cite: 4]. | + +**Body** + +The body is a binary representation of the Platform Manifest structure โ€“ an opaque blob representing a registration +manifest for a multi-package platform[cite: 5]. It contains platform provisioning root keys established by the platform +instance and data required to authenticate the platform as genuine and non-revoked[cite: 5]. + +**Example Request** + +```bash +curl -H "Content-Type: application/octet-stream" --data-binary @platform_manifest POST "[https://api.trustedservices.intel.com/sgx/registration/v1/platform](https://api.trustedservices.intel.com/sgx/registration/v1/platform)" +```` + +**Response** + +**Model** + +The response is a Hex-encoded representation of the PPID for the registered platform instance (only if the HTTP Status +Code is 201; otherwise, the body is empty). + +**Example Response** + +``` +001122334455667788AABBCCDDEEFF +``` + +**Status Codes** + +| Code | Headers | Body | Description | +|:-----|:--------------------------------------------------------------------------------------------------------------------------------------|:------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 201 | Request-ID: Randomly generated identifier for each request (for troubleshooting purposes). | Hex-encoded representation of PPID. | Operation successful (new platform instance registered). A new platform instance has been registered[cite: 5]. | +| 400 | Request-ID: Randomly generated identifier[cite: 6]. \ Error-Code and Error-Message: Additional details about the error[cite: 9]. | | Invalid Platform Manifest[cite: 8]. The request might be malformed[cite: 6], intended for a different server[cite: 7], contain an invalid/revoked package[cite: 7], an unrecognized package[cite: 7], an incompatible package[cite: 7], an invalid manifest[cite: 7], or violate a key caching policy[cite: 8]. The client should not repeat the request without modifications[cite: 9]. | +| 415 | Request-ID: Randomly generated identifier[cite: 10]. | | MIME type specified in the request is not supported[cite: 10]. | +| 500 | Request-ID: Randomly generated identifier[cite: 10]. | | Internal server error occurred[cite: 10]. | +| 503 | Request-ID: Randomly generated identifier[cite: 10]. | | Server is currently unable to process the request. The client should try again later[cite: 11]. | + +----- + +### Add Package + +This API adds new package(s) to an already registered platform instance[cite: 11]. A subscription is required[cite: 11]. +If successful, a Platform Membership Certificate is generated for each processor package in the Add Request[cite: 12]. + +#### POST `https://api.trustedservices.intel.com/sgx/registration/v1/package` + +**Request** + +**Headers** + +| Name | Required | Value | Description | +|:--------------------------|:---------|:---------------------------|:--------------------------------------------------------------------------------| +| Ocp-Apim-Subscription-Key | True | | Subscription key providing access to this API, found in your Profile[cite: 14]. | +| Content-Type | True | `application/octet-stream` | MIME type of the request body[cite: 14]. | + +**Body** + +Binary representation of the Add Request structure โ€“ an opaque blob for adding new processor packages to an existing +platform instance. + +**Example Request** + +```bash +curl -H "Content-Type: application/octet-stream" --data-binary @add_package POST "[https://api.trustedservices.intel.com/sgx/registration/v1/package](https://api.trustedservices.intel.com/sgx/registration/v1/package)" -H "Ocp-Apim-Subscription-Key: {subscription_key}" +``` + +**Response** + +**Model** + +For a 200 HTTP Status Code, the response is a fixed-size array (8 elements) containing binary representations of +Platform Membership Certificate structures[cite: 15]. Certificates are populated sequentially, starting at index 0, with +the rest of the elements zeroed[cite: 15]. + +**Example Response (hex-encoded)** + +``` +E4B0E8B80F8B49184488F77273550840984816854488B7CFRP... +``` + +**Status Codes** + +| Code | Headers | Body | Description | +|:-----|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 200 | Content-Type: `application/octet-stream`[cite: 17]. \ Request-ID: Random identifier[cite: 17]. \ CertificateCount: Number of certificates returned[cite: 17]. | Fixed-size array of Platform Membership Certificates[cite: 17]. | Operation successful. Packages added[cite: 17]. | +| 400 | Request-ID: Random identifier[cite: 17]. \ Error-Code and Error-Message: Details on the error[cite: 17]. | | Invalid Add Request Payload[cite: 17]. Can be due to malformed syntax, platform not found, invalid/revoked/unrecognized package, or invalid AddRequest[cite: 17]. | +| 401 | Request-ID: Random identifier[cite: 17]. | | Failed to authenticate or authorize the request[cite: 17]. | +| 415 | Request-ID: Random identifier[cite: 17]. | | MIME type specified is not supported[cite: 17]. | +| 500 | Request-ID: Random identifier[cite: 17]. | | Internal server error occurred[cite: 17]. | +| 503 | Request-ID: Random identifier[cite: 17]. | | Server is currently unable to process the request[cite: 17]. | + +----- + +## Intelยฎ SGX Provisioning Certification Service for ECDSA Attestation + +Download the Provisioning Certification Root CA Certificate (API v3) here: + +* [DER](https://www.google.com/search?q=https://certificates.trustedservices.intel.com/Intel_SGX_Provisioning_Certification_RootCA.cer) [cite: 18] +* [PEM](https://www.google.com/search?q=https://certificates.trustedservices.intel.com/intel_SGX_Provisioning_Certification_RootCA.perm) [cite: 18] + +### Get PCK Certificate V3 + +This API allows requesting a single PCK certificate by specifying PPID and SVNs or Platform Manifest and SVNs[cite: 18]. +A subscription is required[cite: 18]. + +* **Using PPID and SVNs**: + * Single-socket platforms: No prerequisites[cite: 18]. + * Multi-socket platforms: Requires previous registration via `Register Platform` API[cite: 18]. Platform root keys + must be persistently stored[cite: 19], and the `Keys Caching Policy` must be set to `true`[cite: 21]. The service + uses a PCK public key derived from stored keys[cite: 20]. +* **Using Platform Manifest and SVNs**: + * Multi-socket platforms: Does not require previous registration[cite: 21]. It doesn't require keys to be + persistently stored[cite: 22]. The service uses a PCK public key derived from the provided manifest[cite: 23]. + Depending on the `Keys Caching Policy`, keys might be stored[cite: 24]. + * **Direct Registration** (`Register Platform` first): Sets policy to always store keys[cite: 25]. Keys are + stored when the manifest is sent[cite: 26]. `CachedKeys` flag in PCK Certificates is set to `true`[cite: 27]. + * **Indirect Registration** (`Get PCK Certificate(s)` first): Sets policy to never store keys[cite: 27]. Keys + are discarded after use[cite: 28]. Standard metadata is stored, but `Register Platform` cannot be used + anymore[cite: 29]. `CachedKeys` flag is set to `false`[cite: 30]. + +The PCS returns the PCK Certificate representing the TCB level with the highest security posture based on CPUSVN and PCE +ISVSVN[cite: 30]. + +#### GET `https://api.trustedservices.intel.com/sgx/certification/v3/pckcert` + +**Request** + +| Name | Type | Type | Required | Pattern | Description | +|:--------------------------|:-------|:-------|:---------|:--------------------|:-----------------------------------------------------------------| +| Ocp-Apim-Subscription-Key | String | Header | True | | Subscription key[cite: 32]. | +| PPID-Encryption-Key | String | Header | False | | Type of key for PPID encryption (Default: `RSA-3072`)[cite: 32]. | +| encrypted\_ppid | String | Query | True | `[0-9a-fA-F]{768}$` | Base16-encoded PPID (encrypted with PPIDEK)[cite: 32]. | +| cpusvn | String | Query | True | `[0-9a-fA-F]{32}$` | Base16-encoded CPUSVN (16 bytes)[cite: 32]. | +| pcesvn | String | Query | True | `[0-9a-fA-F]{4}$` | Base16-encoded PCESVN (2 bytes, little endian)[cite: 32]. | +| pceid | String | Query | True | `[0-9a-fA-F]{4}$` | Base16-encoded PCE-ID (2 bytes, little endian)[cite: 32]. | + +**Example Request** + +```bash +curl -X GET "[https://api.trustedservices.intel.com/sgx/certification/v3/pckcert?encrypted_ppid=...&cpusvn=...&pcesvn=...&pceid=](https://api.trustedservices.intel.com/sgx/certification/v3/pckcert?encrypted_ppid=...&cpusvn=...&pcesvn=...&pceid=)..." -H "Ocp-Apim-Subscription-Key: {subscription_key}" +``` + +**Response**: Response description can be +found [here](https://www.google.com/search?q=%23response-get-and-post-1)[cite: 34]. + +#### POST `https://api.trustedservices.intel.com/sgx/certification/v3/pckcert` + +**Request** + +| Name | Type | Request Type | Required | Pattern | Description | +|:--------------------------|:-------|:-------------|:---------|:-----------------------------|:---------------------------------------------| +| Ocp-Apim-Subscription-Key | String | Header | True | | Subscription key[cite: 35]. | +| Content-Type | String | Header | True | | Content Type (`application/json`)[cite: 35]. | +| platformManifest | String | Body Field | True | `[0-9a-fA-F]{16882,112884}$` | Base16-encoded Platform Manifest[cite: 35]. | +| cpusvn | String | Body Field | True | `[0-9a-fA-F]{32}$` | Base16-encoded CPUSVN[cite: 35]. | +| pcesvn | String | Body Field | True | `[0-9a-fA-F]{4}$` | Base16-encoded PCESVN[cite: 35]. | +| pceid | String | Body Field | True | `[0-9a-fA-F]{4}$` | Base16-encoded PCE-ID[cite: 35]. | + +**Body** + +```json +{ + "platformManifest": "...", + "cpusvn": "...", + "pcesvn": "...", + "pceid": "..." +} +``` + +**Example Request** + +```bash +curl -X POST -d '{"platformManifest": "...", "cpusvn": "...", "pcesvn": "...", "pceid": "..."}' -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: {subscription_key}" "[https://api.trustedservices.intel.com/sgx/certification/v3/pckcert](https://api.trustedservices.intel.com/sgx/certification/v3/pckcert)" +``` + +**Response (GET and POST)** + +**Model**: PckCert (X-PEM-FILE) - PEM-encoded SGX PCK Certificate[cite: 36]. + +**Example Response** + +```pem +-----BEGIN CERTIFICATE----- +... +-----END CERTIFICATE----- +``` + +**Status Codes** + +| Code | Model | Headers | Description | +|:-----|:--------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------| +| 200 | PckCert | Content-Type: `application/x-pem-file`[cite: 36]. \ Request-ID[cite: 36]. \ SGX-PCK-Certificate-Issuer-Chain: URL-encoded issuer chain[cite: 36]. \ SGX-TCBm: Hex-encoded CPUSVN and PCESVN[cite: 37]. \ SGX-FMSPC: Hex-encoded FMSPC[cite: 37]. \ SGX-PCK-Certificate-CA-Type: 'processor' or 'platform'[cite: 39]. \ Warning: Optional message[cite: 39]. | Operation successful[cite: 36]. | +| 400 | | Request-ID[cite: 39]. \ Warning[cite: 39]. | Invalid request parameters[cite: 39]. | +| 401 | | Request-ID[cite: 40]. \ Warning[cite: 40]. | Failed to authenticate or authorize the request[cite: 40]. | +| 404 | | Request-ID[cite: 40]. \ Warning[cite: 40]. | PCK Certificate not found[cite: 40]. Reasons: unsupported PPID/PCE-ID, TCB level too low, or Platform Manifest not registered/updated[cite: 41]. | +| 500 | | Request-ID[cite: 41]. \ Warning[cite: 41]. | Internal server error occurred[cite: 41]. | +| 503 | | Request-ID[cite: 42]. \ Warning[cite: 42]. | Server is currently unable to process the request[cite: 42]. | + +----- + +### Get PCK Certificates V3 + +This API retrieves PCK certificates for all configured TCB levels using PPID or Platform Manifest[cite: 42]. +Subscription required[cite: 42]. + +* **Using PPID**: + * Single-socket platforms: No prerequisites[cite: 43]. + * Multi-socket platforms: Requires prior registration via `Register Platform` API[cite: 44]. Keys must be + persistently stored[cite: 45], and `Keys Caching Policy` must be `true`[cite: 47]. PCS uses stored keys[cite: 46]. +* **Using Platform Manifest**: + * Multi-socket platforms: Does not require prior registration[cite: 47]. Does not require persistent + storage[cite: 48]. PCS uses manifest keys[cite: 49]. Caching policy determines storage[cite: 50]. + * **Direct Registration**: Always stores keys; `CachedKeys` is `true`[cite: 51, 52]. + * **Indirect Registration**: Never stores keys; `CachedKeys` is `false`[cite: 53]. + +#### GET `https://api.trustedservices.intel.com/sgx/certification/v3/pckcerts` + +Retrieves certificates based on encrypted PPID and PCE-ID[cite: 53]. + +**Request** + +| Name | Type | Type | Required | Pattern | Description | +|:--------------------------|:-------|:-------|:---------|:--------------------|:--------------------------------------------------------------| +| Ocp-Apim-Subscription-Key | String | Header | True | | Subscription key[cite: 54]. | +| PPID-Encryption-Key | String | Header | False | | Key type for PPID encryption (Default: `RSA-3072`)[cite: 54]. | +| encrypted\_ppid | String | Query | True | `[0-9a-fA-F]{768}$` | Base16-encoded PPID[cite: 54]. | +| pceid | String | Query | True | `[0-9a-fA-F]{4}$` | Base16-encoded PCE-ID[cite: 54]. | + +**Example Request** + +```bash +curl -X GET "[https://api.trustedservices.intel.com/sgx/certification/v3/pckcerts?encrypted_ppid=...&pceid=](https://api.trustedservices.intel.com/sgx/certification/v3/pckcerts?encrypted_ppid=...&pceid=)..." -H "Ocp-Apim-Subscription-Key: {subscription_key}" +``` + +**Response**: Response description can be +found [here](https://www.google.com/search?q=%23response-get-and-post-2)[cite: 55]. + +#### GET `https://api.trustedservices.intel.com/sgx/certification/v3/pckcerts/config` + +Retrieves certificates for a specific CPUSVN (multi-package only)[cite: 55]. + +**Request** + +| Name | Type | Type | Required | Pattern | Description | +|:--------------------------|:-------|:-------|:---------|:--------------------|:----------------------------------------| +| Ocp-Apim-Subscription-Key | String | Header | True | | Subscription key[cite: 56]. | +| PPID-Encryption-Key | String | Header | False | | Key type for PPID encryption[cite: 56]. | +| encrypted\_ppid | String | Query | True | `[0-9a-fA-F]{768}$` | Base16-encoded PPID[cite: 56]. | +| pceid | String | Query | True | `[0-9a-fA-F]{4}$` | Base16-encoded PCE-ID[cite: 56]. | +| cpusvn | String | Query | True | `[0-9a-fA-F]{32}$` | Base16-encoded CPUSVN[cite: 56]. | + +**Example Request** + +```bash +curl -X GET "[https://api.trustedservices.intel.com/sgx/certification/v3/pckcerts/config?encrypted_ppid=...&pceid=...&cpusvn=](https://api.trustedservices.intel.com/sgx/certification/v3/pckcerts/config?encrypted_ppid=...&pceid=...&cpusvn=)..." -H "Ocp-Apim-Subscription-Key: {subscription_key}" +``` + +**Response**: Response description can be +found [here](https://www.google.com/search?q=%23response-get-and-post-2)[cite: 57]. + +#### POST `https://api.trustedservices.intel.com/sgx/certification/v3/pckcerts` + +Retrieves certificates based on Platform Manifest and PCE-ID (multi-package only)[cite: 57]. + +**Request** + +| Name | Type | Request Type | Required | Pattern | Description | +|:--------------------------|:-------|:-------------|:---------|:-----------------------------|:--------------------------------------------| +| Ocp-Apim-Subscription-Key | String | Header | True | | Subscription key[cite: 58]. | +| Content-Type | String | Header | True | `application/json` | Content Type[cite: 58]. | +| platformManifest | String | Body Field | True | `[0-9a-fA-F]{16882,112884}$` | Base16-encoded Platform Manifest[cite: 58]. | +| pceid | String | Body Field | True | `[0-9a-fA-F]{4}$` | Base16-encoded PCE-ID[cite: 58]. | + +**Body** + +```json +{ + "platformManifest": "...", + "pceid": "..." +} +``` + +**Example Request** + +```bash +curl -X POST -d '{"platformManifest": "...", "pceid": "..."}' -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: {subscription_key}" "[https://api.trustedservices.intel.com/sgx/certification/v3/pckcerts](https://api.trustedservices.intel.com/sgx/certification/v3/pckcerts)" +``` + +**Response**: Response description can be +found [here](https://www.google.com/search?q=%23response-get-and-post-2)[cite: 59]. + +#### POST `https://api.trustedservices.intel.com/sgx/certification/v3/pckcerts/config` + +Retrieves certificates for a specific CPUSVN using Platform Manifest (multi-package only)[cite: 59]. + +**Request** + +| Name | Type | Request Type | Required | Pattern | Description | +|:--------------------------|:-------|:-------------|:---------|:-----------------------------|:--------------------------------------------| +| Ocp-Apim-Subscription-Key | String | Header | True | | Subscription key[cite: 61]. | +| Content-Type | String | Header | True | `application/json` | Content Type[cite: 61]. | +| platformManifest | String | Body Field | True | `[0-9a-fA-F]{16882,112884}$` | Base16-encoded Platform Manifest[cite: 61]. | +| cpusvn | String | Body Field | True | `[0-9a-fA-F]{32}$` | Base16-encoded CPUSVN[cite: 61]. | +| pceid | String | Body Field | True | `[0-9a-fA-F]{4}$` | Base16-encoded PCE-ID[cite: 61]. | + +**Body** + +```json +{ + "platformManifest": "...", + "cpusvn": "...", + "pceid": "..." +} +``` + +**Example Request** + +```bash +curl -X POST -d '{"platformManifest": "...", "cpusvn": "...", "pceid": "..."}' -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: {subscription_key}" "[https://api.trustedservices.intel.com/sgx/certification/v3/pckcerts/config](https://api.trustedservices.intel.com/sgx/certification/v3/pckcerts/config)" +``` + +**Response (GET and POST)** + +**Model**: PckCerts (JSON) - Array of data structures with `tcb`, `tcm`, and `certificate`[cite: 62]. + +**PckCerts Structure** + +```json +[ + { + "tcb": { + "sgxtcbcomp01svn": 0, + // Integer + "sgxtcbcomp02svn": 0, + // Integer + // ... (03 to 16) + "pcesvn": 0 + // Integer + }, + "tcm": "...", + // String, Hex-encoded TCBm [cite: 63, 64] + "cert": "..." + // String, PEM-encoded certificate or "Not available" [cite: 64] + } +] +``` + +**Example Response** + +```json +[ + { + "tcb": { + "sgxtcbcomp01svn": 0, + "sgxtcbcomp02svn": 0, + "sgxtcbcomp03svn": 0, + "sgxtcbcomp04svn": 0, + "sgxtcbcomp05svn": 0, + "sgxtcbcomp06svn": 0, + "sgxtcbcomp07svn": 0, + "sgxtcbcomp08svn": 0, + "sgxtcbcomp09svn": 0, + "sgxtcbcomp10svn": 0, + "sgxtcbcomp11svn": 0, + "sgxtcbcomp12svn": 0, + "sgxtcbcomp13svn": 0, + "sgxtcbcomp14svn": 0, + "sgxtcbcomp15svn": 0, + "sgxtcbcomp16svn": 0, + "pcesvn": 0 + }, + "tcm": "...", + "cert": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----" + } +] +``` + +**Status Codes** + +| Code | Model | Headers | Description | +|:-----|:---------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------| +| 200 | PckCerts | Content-Type: `application/json`[cite: 65]. \ Request-ID[cite: 65]. \ SGX-PCK-Certificate-Issuer-Chain: Issuer chain[cite: 66]. \ SGX-FMSPC[cite: 66]. \ SGX-PCK-Certificate-CA-Type[cite: 66]. \ Warning[cite: 66]. | Operation successful[cite: 65]. | +| 400 | | Request-ID[cite: 67]. \ Warning[cite: 67]. | Invalid request parameters[cite: 67]. | +| 401 | | Request-ID[cite: 68]. \ Warning[cite: 68]. | Failed to authenticate or authorize the request[cite: 68]. | +| 404 | | Request-ID[cite: 69]. \ Warning[cite: 69]. | PCK Certificate not found[cite: 69]. Reasons: PPID/PCE-ID not supported or Platform Manifest not registered[cite: 70]. | +| 500 | | Request-ID[cite: 70]. \ Warning[cite: 70]. | Internal server error occurred[cite: 70]. | +| 503 | | Request-ID[cite: 70]. \ Warning[cite: 70]. | Server is currently unable to process the request[cite: 70]. | + +----- + +### Get Revocation List V3 + +Retrieves the X.509 Certificate Revocation List (CRL) for revoked SGX PCK Certificates[cite: 71]. CRLs are issued by +Intel SGX Processor CA or Platform CA[cite: 71]. + +#### GET `https://api.trustedservices.intel.com/sgx/certification/v3/pckcrl` + +**Request** + +| Name | Type | Request Type | Required | Pattern | Description | +|:---------|:-------|:-------------|:---------|:------------|:------------| +| ca | String | Query | True | `(processor | platform)` | CA that issued the CRL[cite: 71]. | +| encoding | String | Query | False | `(pem | der)` | Encoding (Default: PEM)[cite: 71]. | + +**Example Request** + +```bash +curl -X GET "[https://api.trustedservices.intel.com/sgx/certification/v3/pckcrl?ca=platform&encoding=der](https://api.trustedservices.intel.com/sgx/certification/v3/pckcrl?ca=platform&encoding=der)" +``` + +**Response** + +**Model**: PckCrl (X-PEM-FILE or PKIX-CRL) - PEM or DER-encoded CRL[cite: 71]. + +**Example Response** + +``` +-----BEGIN X509 CRL----- +... +-----END X509 CRL----- +``` + +**Status Codes** + +| Code | Model | Headers | Description | +|:-----|:-------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------------------------------------------------| +| 200 | PckCrl | Content-Type: `application/x-pem-file` (PEM) or `application/pkix-crl` (DER)[cite: 72]. \ Request-ID[cite: 72]. \ SGX-PCK-CRL-Issuer-Chain: Issuer chain[cite: 72]. \ Warning[cite: 72]. | Operation successful[cite: 72]. | +| 400 | | Request-ID[cite: 72]. \ Warning[cite: 73]. | Invalid request parameters[cite: 72]. | +| 401 | | Request-ID[cite: 73]. \ Warning[cite: 73]. | Failed to authenticate or authorize[cite: 73]. | +| 500 | | Request-ID[cite: 73]. \ Warning[cite: 73]. | Internal server error occurred[cite: 73]. | +| 503 | | Request-ID[cite: 73]. \ Warning[cite: 73]. | Server is currently unable to process[cite: 73]. | + +----- + +### Get TCB Info V3 + +Retrieves SGX TCB information for a given FMSPC[cite: 74]. + +**Algorithm for TCB Status:** + +1. Retrieve FMSPC from the SGX PCK Certificate[cite: 74]. +2. Retrieve TCB Info matching the FMSPC[cite: 75]. +3. Iterate through the sorted TCB Levels[cite: 75]: + * Compare all SGX TCB Comp SVNs (01-16) from the certificate with TCB Level values[cite: 76]. If all are \>=, + proceed[cite: 76]. Otherwise, move to the next item[cite: 76]. + * Compare PCESVN from the certificate with the TCB Level value[cite: 77]. If \>=, read the status[cite: 77]. + Otherwise, move to the next item[cite: 78]. +4. If no match is found, the TCB Level is not supported[cite: 78]. + +#### GET `https://api.trustedservices.intel.com/sgx/certification/v3/tcb` + +**Request** + +| Name | Type | Request Type | Required | Pattern | Description | +|:------------------------|:-------|:-------------|:---------|:-------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------| +| fmspc | String | Query | True | `[0-9a-fA-F]{12}$` | Base16-encoded FMSPC (6 bytes)[cite: 81]. | +| update | String | Query | False | `(early | standard)` | Update type (Default: standard). 'early' provides early access, 'standard' provides standard access[cite: 81]. Cannot be used with `tcbEvaluationDataNumber`[cite: 81]. | +| tcbEvaluationDataNumber | Number | Query | False | `\d+$` | Specifies a TCB Evaluation Data Number. Allows fetching specific versions; returns 410 if \< M, 404 if \> N[cite: 81]. Cannot be used with `update`[cite: 81]. | + +**Example Requests** + +```bash +curl -X GET "[https://api.trustedservices.intel.com/sgx/certification/v3/tcb?fmspc=...&update=early](https://api.trustedservices.intel.com/sgx/certification/v3/tcb?fmspc=...&update=early)" +curl -X GET "[https://api.trustedservices.intel.com/sgx/certification/v3/tcb?fmspc=...&tcbEvaluationDataNumber=](https://api.trustedservices.intel.com/sgx/certification/v3/tcb?fmspc=...&tcbEvaluationDataNumber=)..." +``` + +**Response** + +**Model**: TcbInfoV2 (JSON) - SGX TCB Info[cite: 82]. + +**TcbInfoV2 Structure** + +* `version`: Integer[cite: 83]. +* `issueDate`: String (date-time, ISO 8601 UTC)[cite: 84]. +* `nextUpdate`: String (date-time, ISO 8601 UTC)[cite: 85]. +* `fmspc`: String (Base16-encoded FMSPC)[cite: 85]. +* `pceId`: String (Base16-encoded PCE-ID)[cite: 85]. +* `tcbType`: Integer[cite: 85]. +* `tcbEvaluationDataNumber`: Integer, monotonically increasing sequence number for TCB evaluation data set + updates[cite: 86]. Synchronized across TCB Info and Identities[cite: 86]. Helps determine which data supersedes + another[cite: 87]. +* `tcbLevels`: Array of TCB level objects[cite: 87]. + * `tcb`: Object with `sgxtcbcompXXsvn` (Integer) and `pcesvn` (Integer)[cite: 87]. + * `tcbDate`: String (date-time, ISO 8601 UTC)[cite: 89]. If advisories exist after this date with enforced + mitigations, status won't be `UpToDate`[cite: 88]. + * `tcbStatus`: String (`UpToDate`, `HardeningNeeded`, `ConfigurationNeeded`, `ConfigurationAndHardeningNeeded`, + `OutOfDate`, `OutOfDateConfigurationNeeded`, `Revoked`)[cite: 90, 91, 92]. + * `advisoryIDs`: Array of strings (e.g., `INTEL-SA-XXXXX`, `INTEL-DOC-XXXXX`)[cite: 93, 94]. +* `signature`: String (Base16 encoded)[cite: 94]. + +**Example Response** + +```json +{ + "tcbInfo": { + "version": 2, + "issueDate": "2018-07-30T12:00:00Z", + "nextUpdate": "2018-08-30T12:00:00Z", + "fmspc": "...", + "pceId": "0000", + "tcbType": 1, + "tcbEvaluationDataNumber": 7, + "tcbLevels": [ + { + "tcb": { + "sgxtcbcomp01svn": 0, + /* ... */ + "pcesvn": 0 + }, + "tcbDate": "2018-07-11T12:00:00Z", + "tcbStatus": "UpToDate", + "advisoryIDs": [ + "INTEL-SA-00070", + "INTEL-SA-00076" + ] + } + ] + }, + "signature": "..." +} +``` + +**Status Codes** + +| Code | Model | Headers | Description | +|:-----|:----------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------| +| 200 | TcbInfoV2 | Content-Type: `application/json`[cite: 96]. \ Request-ID[cite: 96]. \ SGX-TCB-Info-Issuer-Chain: Issuer chain[cite: 96]. \ Warning[cite: 96]. | Operation successful[cite: 96]. | +| 400 | | Request-ID[cite: 96]. \ Warning[cite: 96]. | Invalid request (bad FMSPC or conflicting `update`/`tcbEvaluationDataNumber`)[cite: 96]. | +| 401 | | Request-ID[cite: 96]. \ Warning[cite: 96]. | Failed to authenticate or authorize[cite: 96]. | +| 404 | | Request-ID[cite: 96]. \ Warning[cite: 96]. | TCB info not found for FMSPC or `tcbEvaluationDataNumber`[cite: 96]. | +| 410 | | Request-ID[cite: 98]. \ Warning[cite: 98]. | TCB Information for `tcbEvaluationDataNumber` no longer available[cite: 98]. | +| 500 | | Request-ID[cite: 98]. \ Warning[cite: 98]. | Internal server error[cite: 98]. | +| 503 | | Request-ID[cite: 98]. \ Warning[cite: 98]. | Server unable to process[cite: 98]. | + +----- + +### Get Quoting Enclave Identity V3 + +Verifies if an SGX Enclave Report matches a valid Quoting Enclave (QE) identity[cite: 99]. + +**Algorithm:** + +1. Retrieve and validate QE Identity[cite: 99]. +2. Compare SGX Enclave Report against QE Identity: + * Verify `MRSIGNER` equals `mrsigner`[cite: 100]. + * Verify `ISVPRODID` equals `isvprodid`[cite: 101]. + * Verify `(miscselectMask & MISCSELECT)` equals `miscselect`[cite: 102]. + * Verify `(attributesMask & ATTRIBUTES)` equals `attributes`[cite: 103, 104]. +3. If any check fails, identity doesn't match[cite: 105]. +4. Determine TCB status: + * Retrieve TCB Levels[cite: 106]. + * Find TCB Level with ISVSVN \<= Enclave Report ISVSVN (descending)[cite: 107]. + * Read `tcbStatus`; if not found, it's unsupported[cite: 108]. + +#### GET `https://api.trustedservices.intel.com/sgx/certification/v3/qe/identity` + +**Request** + +| Name | Type | Type | Required | Pattern | Description | +|:------------------------|:-------|:------|:---------|:--------|:------------------------------------------------------------------------------------------| +| update | String | Query | False | `(early | standard)` | Update type (Default: standard)[cite: 110]. Cannot be used with `tcbEvaluationDataNumber`[cite: 110]. | +| tcbEvaluationDataNumber | Number | Query | False | `\d+` | Specifies TCB Evaluation Data Number[cite: 110]. Cannot be used with `update`[cite: 110]. | + +**Example Requests** + +```bash +curl -X GET "[https://api.trustedservices.intel.com/sgx/certification/v3/qe/identity?update=early](https://api.trustedservices.intel.com/sgx/certification/v3/qe/identity?update=early)" +curl -X GET "[https://api.trustedservices.intel.com/sgx/certification/v3/qe/identity?tcbEvaluationDataNumber=](https://api.trustedservices.intel.com/sgx/certification/v3/qe/identity?tcbEvaluationDataNumber=)..." +``` + +**Response** + +**Model**: QEIdentityV2 (JSON) - QE Identity data[cite: 111]. + +**QEIdentityV2 Structure** + +* `enclaveIdentity`: + * `id`: String (`QE`, `QVE`, or `QAE`)[cite: 113]. + * `version`: Integer[cite: 113]. + * `issueDate`, `nextUpdate`: String (date-time, ISO 8601 UTC)[cite: 114]. + * `tcbEvaluationDataNumber`: Integer[cite: 115]. + * `miscselect`, `miscselectMask`: String (Base16-encoded)[cite: 115, 116]. + * `attributes`, `attributesMask`: String (Base16-encoded)[cite: 116]. + * `mrsigner`: String (Base16-encoded)[cite: 116]. + * `isvprodid`: Integer[cite: 116]. + * `tcbLevels`: Array of TCB level objects[cite: 116]. + * `tcb`: Object with `isvsvn` (Integer)[cite: 117]. + * `tcbDate`: String (date-time, ISO 8601 UTC)[cite: 117]. + * `tcbStatus`: String (`UpToDate`, `OutOfDate`, `Revoked`)[cite: 119]. + * `advisoryIDs`: Array of strings[cite: 119]. +* `signature`: String (Hex-encoded)[cite: 119]. + +**Status Codes** + +| Code | Model | Headers | Description | +|:-----|:-------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------| +| 200 | QEIdentityV2 | Content-Type: `application/json`[cite: 122]. \ Request-ID[cite: 122]. \ SGX-Enclave-Identity-Issuer-Chain: Issuer chain[cite: 122]. \ Warning[cite: 122]. | Operation successful[cite: 122]. | +| 400 | | Request-ID[cite: 122]. \ Warning[cite: 123]. | Invalid request (bad params or conflicting `update`/`tcbEvaluationDataNumber`)[cite: 122, 124]. | +| 401 | | Request-ID[cite: 123]. \ Warning[cite: 123]. | Failed to authenticate or authorize[cite: 123]. | +| 404 | | Request-ID[cite: 123]. \ Warning[cite: 123]. | QE identity not found for `tcbEvaluationDataNumber`[cite: 124]. | +| 410 | | Request-ID[cite: 124]. \ Warning[cite: 124]. | QEIdentity for `tcbEvaluationDataNumber` no longer available[cite: 124]. | +| 500 | | Request-ID[cite: 125]. \ Warning[cite: 125]. | Internal server error[cite: 125]. | +| 503 | | Request-ID[cite: 125]. \ Warning[cite: 125]. | Server unable to process[cite: 125]. | + +----- + +### Get Quote Verification Enclave Identity V3 + +Verifies if an SGX Enclave Report matches a valid QVE identity[cite: 126]. + +**Algorithm:** + +1. Retrieve and validate QVE Identity[cite: 126]. +2. Compare Enclave Report: `MRSIGNER`[cite: 127], `ISVPRODID`[cite: 128], `MISCSELECT` (with mask)[cite: 128], + `ATTRIBUTES` (with mask)[cite: 128]. +3. If any fails, no match[cite: 129]. +4. Determine TCB status via ISVSVN comparison[cite: 129, 130]. + +#### GET `https://api.trustedservices.intel.com/sgx/certification/v3/qve/identity` + +**Request**: Same parameters as `Get Quoting Enclave Identity V3` (`update` and `tcbEvaluationDataNumber`)[cite: 132]. + +**Response**: QVEIdentityV2 (JSON) - QVE Identity data[cite: 133]. Structure similar to QE +Identity[cite: 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144]. + +**Status Codes**: Similar to `Get Quoting Enclave Identity V3`[cite: 145]. + +----- + +### Get Quote Appraisal Enclave Identity V3 + +Verifies if an SGX Enclave Report matches a valid QAE identity[cite: 149]. + +**Algorithm:** + +1. Retrieve and validate QAE Identity[cite: 149]. +2. Compare Enclave Report: `MRSIGNER`[cite: 151], `ISVPRODID`[cite: 151], `MISCSELECT` (with mask)[cite: 152, 153], + `ATTRIBUTES` (with mask)[cite: 154, 155]. +3. If any fails, no match[cite: 155]. +4. Determine TCB status via ISVSVN comparison[cite: 157, 158]. + +#### GET `https://api.trustedservices.intel.com/sgx/certification/v3/qae/identity` + +**Request**: Same parameters as `Get Quoting Enclave Identity V3` (`update` and `tcbEvaluationDataNumber`)[cite: 160]. + +**Response**: QAEIdentityV2 (JSON) - QAE Identity data[cite: 161]. Structure similar to QE +Identity[cite: 162, 163, 164, 165, 166, 167, 168, 169, 170]. + +**Status Codes**: Similar to `Get Quoting Enclave Identity V3`[cite: 171, 174]. + +----- + +### PCK Certificate and CRL Specification + +This document specifies the hierarchy and format of X.509 v3 certificates and v2 CRLs for Provisioning Certification +Keys[cite: 175]. + +Enforcement of a mitigation means the attestation process can detect its presence and the result will differ[cite: 175]. +Intel offers `standard` (default) and `early` update parameters, affecting when enforcement occurs[cite: 176]. The +attestation result is an objective assessment[cite: 177]. Relying parties can use additional factors [cite: 178] and may +choose to trust an 'OutOfDate' platform, accepting risks[cite: 180]. Intel will strive to communicate schedule +deviations[cite: 181]. + diff --git a/crates/intel-dcap-api/specs/API spec V4.md b/crates/intel-dcap-api/specs/API spec V4.md new file mode 100644 index 0000000..0112b31 --- /dev/null +++ b/crates/intel-dcap-api/specs/API spec V4.md @@ -0,0 +1,664 @@ +This document outlines the API for Intelยฎ SGX and Intelยฎ TDX services, focusing on platform registration and +provisioning certification using ECDSA attestation. + +## Intelยฎ SGX and Intelยฎ TDX Registration Service for Scalable Platforms [cite: 1] + +The Intelยฎ SGX and Intelยฎ TDX Registration Service API enables the registration of Intelยฎ SGX platforms with multiple +processor packages as a unified platform instance[cite: 2]. This allows these platforms to be remotely attested as a +single entity[cite: 2]. It is important to note that the service enforces a minimum TLS protocol version of 1.2; any +attempts to connect with older TLS/SSL versions will be rejected[cite: 3]. + +### Register Platform + +This API facilitates the registration of multi-package SGX platforms, encompassing both initial registration and TCB ( +Trusted Computing Base) recovery[cite: 4]. During this process, the Registration Service authenticates the platform +manifest to confirm it originates from a genuine, non-revoked SGX platform[cite: 4]. If the platform configuration +passes verification, its provisioning root keys are securely stored[cite: 4]. These stored keys are subsequently used to +derive the public components of Provisioning Certification Keys (PCKs), which are then distributed as X.509 certificates +by the Provisioning Certification Service[cite: 5]. These PCK certificates are integral to the remote attestation +process for the platform[cite: 5]. + +**POST** `https://api.trustedservices.intel.com/sgx/registration/v1/platform` + +**Request** + +* **Headers**: In addition to standard HTTP headers (like `Content-Length`), the following is required[cite: 1]: + +| Name | Required | Value | Description | +|:-------------|:---------|:-------------------------|:----------------------------------------| +| Content-Type | True | application/octet-stream | MIME type of the request body[cite: 1]. | + +* **Body**: The request body must be a binary representation of the Platform Manifest structure[cite: 6]. This is an + opaque blob containing the registration manifest for a multi-package platform[cite: 6]. It includes the platform + provisioning root keys established by the platform instance and the necessary data to authenticate it as a genuine, + non-revoked SGX platform[cite: 6]. + +* **Example Request**: + ```bash + curl -v -X POST "Content-Type: application/octet-stream" --data-binary @platform_manifest.bin "https://api.trustedservices.intel.com/sgx/registration/v1/platform" [cite: 1] + ``` + +**Response** + +* **Model**: The response body will contain the hex-encoded representation of the PPID (Platform Provisioning ID) for + the registered platform instance, but only if the HTTP Status Code is 201[cite: 1]. Otherwise, the body will be + empty[cite: 1]. + +* **Example Response**: + ``` + 00112233445566778899AABBCCDDEEFF [cite: 1] + ``` + +* **Status Codes**: + +| Code | Headers | Body | Description | +|:-----|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------|:--------------------------------------------------------------------------------------------------| +| 201 | `Request-ID`: Randomly generated identifier for troubleshooting[cite: 7]. | Hex-encoded PPID | Operation successful; a new platform instance has been registered[cite: 7]. | +| 400 | `Request-ID`: Randomly generated identifier[cite: 8]. `Error-Code` & `Error-Message`: Details on the error (e.g., `InvalidRequestSyntax`, `InvalidRegistrationServer`, `InvalidOrRevokedPackage`, `PackageNotFound`, `IncompatiblePackage`, `InvalidPlatformManifest`, `CachedKeysPolicyViolation`)[cite: 8]. | | Invalid Platform Manifest[cite: 10]. The client should not retry without modifications[cite: 10]. | +| 415 | `Request-ID`: Randomly generated identifier[cite: 8]. | | The MIME type specified in the request is not supported[cite: 8]. | +| 500 | `Request-ID`: Randomly generated identifier[cite: 8]. | | An internal server error occurred[cite: 8]. | +| 503 | `Request-ID`: Randomly generated identifier[cite: 8]. | | The server is currently unable to process the request; try again later[cite: 8]. | + +### Add Package + +This API allows for adding new processor packages to an already registered platform instance[cite: 11]. Upon successful +execution, a Platform Membership Certificate is generated for each processor package included in the Add +Request[cite: 11]. This requires a subscription for registration[cite: 11]. + +**POST** `https://api.trustedservices.intel.com/sgx/registration/v1/package` + +**Request** + +* **Headers**: Besides standard headers like `Content-Length`[cite: 12], the following are needed: + +| Name | Required | Value | Description | +|:--------------------------|:---------|:-------------------------|:------------------------------------------------------------------| +| Ocp-Apim-Subscription-Key | True | *Your Subscription Key* | Subscription key for API access, found in your profile[cite: 12]. | +| Content-Type | True | application/octet-stream | MIME type of the request body[cite: 12]. | + +* **Body**: A binary representation of the Add Request structure, an opaque blob for adding new packages to an existing + platform[cite: 13]. + +* **Example Request**: + ```bash + curl -v -X POST "Content-Type: application/octet-stream" --data-binary @add_package_request.bin "https://api.trustedservices.intel.com/sgx/registration/v1/package" -H "Ocp-Apim-Subscription-Key: {subscription_key}" [cite: 14] + ``` + +**Response** + +* **Model**: For a 200 HTTP Status Code, the response is a fixed-size array (8 elements) containing binary Platform + Membership Certificate structures appended together[cite: 14]. Certificates fill the array sequentially, starting from + index 0, with remaining elements zeroed out[cite: 14]. + +* **Example Response (hex-encoded)**: + ``` + E8BDBECFEF9040184488777267355084...00000000 [cite: 15] + ``` + +* **Status Codes**: + +| Code | Headers | Body | Description | +|:-----|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------| +| 200 | `Content-Type`: application/octet-stream[cite: 18]. `Request-ID`: Randomly generated identifier[cite: 18]. `Certificate-Count`: Number of certificates returned[cite: 18]. | Fixed-size array (8 elements) with binary Platform Membership Certificates[cite: 18, 19]. | Operation successful; packages added to the platform[cite: 18]. | +| 400 | `Request-ID`: Randomly generated identifier[cite: 18]. `Error-Code` & `Error-Message`: Details on the error (e.g., `InvalidRequestSyntax`, `PlatformNotFound`, `InvalidOrRevokedPackage`, `PackageNotFound`[cite: 17], `InvalidAddRequest`)[cite: 18]. | | Invalid Add Request Payload[cite: 20]. Do not retry without modifications[cite: 20]. | +| 401 | `Request-ID`: Randomly generated identifier[cite: 18]. | | Failed to authenticate or authorize the request[cite: 18]. | +| 415 | `Request-ID`: Randomly generated identifier[cite: 18]. | | The MIME type specified is not supported[cite: 18]. | +| 500 | `Request-ID`: Randomly generated identifier[cite: 18]. | | Internal server error occurred[cite: 18]. | +| 503 | `Request-ID`: Randomly generated identifier[cite: 18]. | | Server is currently unable to process the request[cite: 18]. | + +## Intelยฎ SGX and Intelยฎ TDX Provisioning Certification Service for ECDSA Attestation [cite: 21] + +This service provides PCK certificates. You can download the Provisioning Certification Root CA Certificate (v4) in both +DER and PEM formats[cite: 21]. + +### Get/Post PCK Certificate V4 + +This API allows requesting a single PCK certificate. It offers two primary methods: + +1. **Using PPID and SVNs**: + * **Single-socket platforms**: No prerequisites[cite: 22]. + * **Multi-socket platforms**: Requires prior platform registration via the Register Platform API[cite: 22]. This + flow necessitates that platform root keys are persistently stored in the backend[cite: 23], and the Keys Caching + Policy must be `true`[cite: 23]. +2. **Using Platform Manifest and SVNs**: + * **Multi-socket platforms**: Does *not* require prior registration[cite: 24]. Platform root keys are *not* required + to be persistently stored[cite: 24]. The Keys Caching Policy determines whether keys are stored or not[cite: 25]. + * **Direct Registration (via Register Platform API)**: Keys are always stored; `CachedKeys` flag in PCK + certificates is `true`[cite: 26, 27]. + * **Indirect Registration (via Get PCK Certificate(s) API)**: Keys are never stored; `CachedKeys` flag is + `false`[cite: 28, 30]. Register Platform API cannot be used afterward[cite: 29]. + +**Note**: The PCS returns the PCK Certificate representing the highest TCB security level based on the CPUSVN and PCE +ISVSVN inputs[cite: 31]. + +**GET** `https://api.trustedservices.intel.com/sgx/certification/v4/pckcert` + +* **Request**: + +| Name | Type | Request Type | Required | Pattern | Description | +|:--------------------------|:-------|:-------------|:---------|:-------------------|:--------------------------------------------------------------| +| Ocp-Apim-Subscription-Key | String | Header | False | | Subscription key[cite: 32]. | +| PPID-Encryption-Key | String | Header | False | | Key type for PPID encryption (default: "RSA-3072")[cite: 32]. | +| encrypted_ppid | String | Query | True | `[0-9a-fA-F]{768}` | Base16-encoded encrypted PPID[cite: 32]. | +| cpusvn | String | Query | True | `[0-9a-fA-F]{32}` | Base16-encoded CPUSVN[cite: 32]. | +| pcesvn | String | Query | True | `[0-9a-fA-F]{4}` | Base16-encoded PCESVN (little endian)[cite: 32]. | +| pceid | String | Query | True | `[0-9a-fA-F]{4}` | Base16-encoded PCE-ID (little endian)[cite: 32]. | + +* **Example Request**: + ```bash + curl -v -X GET "https://api.trustedservices.intel.com/sgx/certification/v4/pckcert?encrypted_ppid={encrypted_ppid}&cpusvn={cpusvn}&pcesvn={pcesvn}&pceid={pceid}" -H "Ocp-Apim-Subscription-Key: {subscription_key}" [cite: 33] + ``` + +**POST** `https://api.trustedservices.intel.com/sgx/certification/v4/pckcert` + +* **Request**: + +| Name | Type | Request Type | Required | Pattern | Description | +|:--------------------------|:-------|:-------------|:---------|:----------------------------|:-------------------------------------------------| +| Ocp-Apim-Subscription-Key | String | Header | False | | Subscription key[cite: 33]. | +| Content-Type | String | Header | True | `application/json` | Content type[cite: 35]. | +| platformManifest | String | Body Field | True | `[0-9a-fA-F]{16862,112884}` | Base16-encoded Platform Manifest[cite: 35]. | +| cpusvn | String | Body Field | True | `[0-9a-fA-F]{32}` | Base16-encoded CPUSVN[cite: 35]. | +| pcesvn | String | Body Field | True | `[0-9a-fA-F]{4}` | Base16-encoded PCESVN (little endian)[cite: 35]. | +| pceid | String | Body Field | True | `[0-9a-fA-F]{4}` | Base16-encoded PCE-ID (little endian)[cite: 35]. | + +* **Body**: + ```json + { + "platformManifest": "...", [cite: 36] + "cpusvn": "...", [cite: 36] + "pcesvn": "...", [cite: 36] + "pceid": "..." [cite: 36] + } + ``` + +* **Example Request**: + ```bash + curl -v -X POST --data '{"platformManifest":"...","cpusvn":"...","pcesvn":"...","pceid":"..."}' "https://api.trustedservices.intel.com/sgx/certification/v4/pckcert" -H "Ocp-Apim-Subscription-Key: {subscription_key}" -H "Content-Type: application/json" [cite: 36] + ``` + +**Response (Both GET & POST)** + +* **Model**: `PckCert (X-PEM-FILE)` - PEM-encoded SGX PCK Certificate[cite: 36]. +* **Example Response**: + ```pem + -----BEGIN CERTIFICATE----- + ... + -----END CERTIFICATE----- [cite: 36] + ``` +* **Status Codes**: + +| Code | Model | Headers | Description | +|:-----|:--------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------| +| 200 | PckCert | `Content-Type`: application/x-pem-file[cite: 37]. `Request-ID`: Identifier[cite: 37]. `SGX-PCK-Certificate-Issuer-Chain`: PEM-encoded Issuer Chain[cite: 37]. `SGX-TCBm`: Hex-encoded CPUSVN & PCESVN[cite: 37]. `SGX-FMSPC`: Hex-encoded FMSPC[cite: 37]. `SGX-PCK-Certificate-CA-Type`: "processor" or "platform"[cite: 37]. `Warning` (Optional)[cite: 37]. | Operation successful[cite: 37]. | +| 400 | | `Request-ID`: Identifier[cite: 37]. `Warning` (Optional)[cite: 37]. `Error-Code` & `Error-Message` (e.g., `InvalidRequestSyntax`, `InvalidRegistrationServer`, `InvalidOrRevokedPackage`, `PackageNotFound`, `IncompatiblePackage`, `InvalidPlatformManifest`)[cite: 37]. | Invalid request parameters[cite: 37]. | +| 401 | | `Request-ID`: Identifier[cite: 37]. `Warning` (Optional)[cite: 37]. | Failed to authenticate or authorize[cite: 37]. | +| 404 | | `Request-ID`: Identifier[cite: 37]. `Warning` (Optional)[cite: 37]. | PCK Certificate not found (e.g., unsupported PPID/PCE-ID, TCB below minimum, Platform Manifest not registered/updated)[cite: 37]. | +| 429 | | `Retry-After`: Wait time in seconds[cite: 37]. `Warning` (Optional)[cite: 37]. | Too many requests[cite: 37]. | +| 500 | | `Request-ID`: Identifier[cite: 37]. `Warning` (Optional)[cite: 37]. | Internal server error[cite: 37]. | +| 503 | | `Request-ID`: Identifier[cite: 39]. `Warning` (Optional)[cite: 39]. | Server is currently unable to process[cite: 39]. | + +### Get PCK Certificates V4 + +This API retrieves PCK certificates for *all* configured TCB levels for a platform. The usage conditions (single-socket +vs. multi-socket, PPID vs. Platform Manifest, key caching) are similar to the single PCK certificate +API[cite: 40, 41, 42, 43, 44, 45, 46, 47, 48]. + +**GET** `https://api.trustedservices.intel.com/sgx/certification/v4/pckcerts` (Using PPID & PCE-ID) + +* **Request**: + +| Name | Type | Request Type | Required | Pattern | Description | +|:--------------------------|:-------|:-------------|:---------|:-------------------|:------------------------------------------| +| Ocp-Apim-Subscription-Key | String | Header | False | | Subscription key[cite: 49]. | +| PPID-Encryption-Key | String | Header | False | | Key type (default: "RSA-3072")[cite: 49]. | +| encrypted_ppid | String | Query | True | `[0-9a-fA-F]{768}` | Encrypted PPID[cite: 49]. | +| pceid | String | Query | True | `[0-9a-fA-F]{4}` | PCE-ID[cite: 49]. | + +* **Example Request**: + ```bash + curl -v -X GET "https://api.trustedservices.intel.com/sgx/certification/v4/pckcerts?encrypted_ppid={...}&pceid={...}" -H "Ocp-Apim-Subscription-Key: {subscription_key}" [cite: 50] + ``` + +**GET** `https://api.trustedservices.intel.com/sgx/certification/v4/pckcerts/config` (Using PPID, PCE-ID & +CPUSVN) [cite: 51] + +* **Request**: + +| Name | Type | Request Type | Required | Pattern | Description | +|:--------------------------|:-------|:-------------|:---------|:-------------------|:------------------------------------------| +| Ocp-Apim-Subscription-Key | String | Header | False | | Subscription key[cite: 52]. | +| PPID-Encryption-Key | String | Header | False | | Key type (default: "RSA-3072")[cite: 52]. | +| encrypted_ppid | String | Query | True | `[0-9a-fA-F]{768}` | Encrypted PPID[cite: 52]. | +| pceid | String | Query | True | `[0-9a-fA-F]{4}` | PCE-ID[cite: 52]. | +| cpusvn | String | Query | True | `[0-9a-fA-F]{32}` | CPUSVN[cite: 52]. | + +* **Example Request**: + ```bash + curl -v -X GET "https://api.trustedservices.intel.com/sgx/certification/v4/pckcerts/config?encrypted_ppid={...}&pceid={...}&cpusvn={...}" -H "Ocp-Apim-Subscription-Key: {subscription_key}" [cite: 53] + ``` + +**POST** `https://api.trustedservices.intel.com/sgx/certification/v4/pckcerts` (Using Platform Manifest & PCE-ID) + +* **Request**: + +| Name | Type | Request Type | Required | Pattern | Description | +|:--------------------------|:-------|:-------------|:---------|:----------------------------|:-----------------------------| +| Ocp-Apim-Subscription-Key | String | Header | False | | Subscription key[cite: 54]. | +| Content-Type | String | Header | True | `application/json` | Content type[cite: 54]. | +| platformManifest | String | Body Field | True | `[0-9a-fA-F]{16862,112884}` | Platform Manifest[cite: 54]. | +| pceid | String | Body Field | True | `[0-9a-fA-F]{4}` | PCE-ID[cite: 54]. | + +* **Body**: + ```json + { + "platformManifest": "...", [cite: 55] + "pceid": "..." [cite: 55] + } + ``` +* **Example Request**: + ```bash + curl -v -X POST --data '{"platformManifest":"...","pceid":"..."}' "https://api.trustedservices.intel.com/sgx/certification/v4/pckcerts" -H "Ocp-Apim-Subscription-Key: {subscription_key}" -H "Content-Type: application/json" [cite: 55] + ``` + +**POST** `https://api.trustedservices.intel.com/sgx/certification/v4/pckcerts/config` (Using Platform Manifest, PCE-ID & +CPUSVN) + +* **Request**: + +| Name | Type | Request Type | Required | Pattern | Description | +|:--------------------------|:-------|:-------------|:---------|:----------------------------|:-----------------------------| +| Ocp-Apim-Subscription-Key | String | Header | False | | Subscription key[cite: 56]. | +| Content-Type | String | Header | True | `application/json` | Content type[cite: 57]. | +| platformManifest | String | Body Field | True | `[0-9a-fA-F]{16862,112884}` | Platform Manifest[cite: 56]. | +| cpusvn | String | Body Field | True | `[0-9a-fA-F]{32}` | CPUSVN[cite: 56]. | +| pceid | String | Body Field | True | `[0-9a-fA-F]{4}` | PCE-ID[cite: 56]. | + +* **Body**: + ```json + { + "platformManifest": "...", [cite: 57] + "cpusvn": "...", [cite: 57] + "pceid": "..." [cite: 57] + } + ``` +* **Example Request**: + ```bash + curl -v -X POST --data '{"platformManifest":"...","cpusvn":"...","pceid":"..."}' "https://api.trustedservices.intel.com/sgx/certification/v4/pckcerts/config" -H "Ocp-Apim-Subscription-Key: {subscription_key}" -H "Content-Type: application/json" [cite: 57] + ``` + +**Response (All GET & POST for multiple certs)** + +* **Model**: `PckCerts` (JSONArray of objects, each containing `tcb`, `tcbm`, and `cert`)[cite: 56]. + * `tcb`: Object with 16 `sgxtcbcompXXsvn` fields (integer 0-255) and `pcesvn` (integer 0-65535)[cite: 59]. + * `tcbm`: Hex-encoded string of CPUSVN (16 bytes) and PCESVN (2 bytes)[cite: 7]. + * `cert`: URL-encoded PEM PCK Certificate, or "Not available" string[cite: 60]. +* **Example Response**: + ```json + [ + { + "tcb": { + "sgxtcbcomp01svn": 3, + "sgxtcbcomp02svn": 1, + ... + "pcesvn": 11 + }, + "tcbm": "...", + "cert": "-----BEGIN%20CERTIFICATE-----%0A...%0A-----END%20CERTIFICATE-----" [cite: 61] + }, + ... + ] + ``` +* **Status Codes**: + +| Code | Model | Headers | Description | +|:-----|:---------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------| +| 200 | PckCerts | `Content-Type`: application/json[cite: 8]. `Request-ID`: Identifier[cite: 8]. `SGX-PCK-Certificate-Issuer-Chain`: Issuer Chain[cite: 62]. `SGX-FMSPC`: FMSPC[cite: 8]. `SGX-PCK-Certificate-CA-Type`: "processor" or "platform"[cite: 63]. `Warning` (Optional)[cite: 8]. | Operation successful[cite: 8]. | +| 400 | | `Request-ID`: Identifier[cite: 8]. `Warning` (Optional)[cite: 8]. `Error-Code` & `Error-Message` (e.g., `InvalidRequestSyntax`[cite: 65], `InvalidRegistrationServer`[cite: 65], `InvalidOrRevokedPackage`[cite: 65], `PackageNotFound`[cite: 65], `IncompatiblePackage`[cite: 65], `InvalidPlatformManifest` [cite: 66]) | Invalid request parameters[cite: 8]. | +| 401 | | `Request-ID`: Identifier[cite: 68]. `Warning` (Optional)[cite: 68]. | Failed to authenticate or authorize[cite: 68]. | +| 404 | | `Request-ID`: Identifier[cite: 68]. `Warning` (Optional)[cite: 68]. | PCK Certificate not found (e.g., unsupported PPID/PCE-ID, Platform Manifest not registered)[cite: 68]. | +| 429 | | `Retry-After`: Wait time[cite: 68]. `Warning` (Optional)[cite: 68]. | Too many requests[cite: 68]. | +| 500 | | `Request-ID`: Identifier[cite: 68]. `Warning` (Optional)[cite: 68]. | Internal server error[cite: 68]. | +| 503 | | `Request-ID`: Identifier[cite: 68]. `Warning` (Optional)[cite: 68]. | Server is currently unable to process[cite: 68]. | + +### Get Revocation List V4 + +This API retrieves the X.509 Certificate Revocation List (CRL) for revoked SGX PCK Certificates, issued by either the +Intel SGX Processor CA or Platform CA[cite: 69, 70]. + +**GET** `https://api.trustedservices.intel.com/sgx/certification/v4/pckcrl` [cite: 71] + +* **Request**: + +| Name | Type | Request Type | Required | Pattern | Description | +|:---------|:-------|:-------------|:---------|:------------|:------------| +| ca | String | Query | True | `(processor | platform)` | CA identifier ("processor" or "platform")[cite: 71, 72]. | +| encoding | String | Query | False | `(pem | der)` | CRL encoding (default: PEM)[cite: 71]. | + +* **Example Request**: + ```bash + curl -v -X GET "https://api.trustedservices.intel.com/sgx/certification/v4/pckcrl?ca=platform&encoding=pem" [cite: 71] + ``` + +**Response** + +* **Model**: `PckCrl` (X-PEM-FILE or PKIX-CRL) - PEM or DER encoded CRL[cite: 71]. +* **Example Response**: + ```pem + -----BEGIN X509 CRL----- + ... + -----END X509 CRL----- [cite: 71] + ``` +* **Status Codes**: + +| Code | Model | Headers | Description | +|:-----|:-------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------------------------------------------------| +| 200 | PckCrl | `Content-Type`: "application/x-pem-file" or "application/pkix-crl"[cite: 71]. `Request-ID`: Identifier[cite: 71]. `SGX-PCK-CRL-Issuer-Chain`: Issuer Chain[cite: 73]. `Warning` (Optional)[cite: 71]. | Operation successful[cite: 71]. | +| 400 | | `Request-ID`: Identifier[cite: 71]. `Warning` (Optional)[cite: 71]. | Invalid request parameters[cite: 71]. | +| 401 | | `Request-ID`: Identifier[cite: 74]. `Warning` (Optional)[cite: 74]. | Failed to authenticate or authorize[cite: 74]. | +| 500 | | `Request-ID`: Identifier[cite: 74]. `Warning` (Optional)[cite: 74]. | Internal server error[cite: 74]. | +| 503 | | `Request-ID`: Identifier[cite: 74]. `Warning` (Optional)[cite: 74]. | Server is currently unable to process[cite: 74]. | + +### Get SGX TCB Info V4 + +This API retrieves SGX TCB information for a specific FMSPC, which is crucial for determining the TCB status of a +platform[cite: 75]. The process involves: + +1. Retrieving the FMSPC from the SGX PCK Certificate[cite: 75]. +2. Fetching the corresponding SGX TCB info[cite: 76]. +3. Iterating through the TCB Levels: + * Comparing all 16 SGX TCB Comp SVNs from the certificate against the TCB Level; they must be >=[cite: 77, 78]. + * Comparing the PCESVN from the certificate against the TCB Level; it must be >=[cite: 79, 80]. If both match, the + TCB level's status is found[cite: 80]. +4. If no match is found, the TCB level is unsupported[cite: 82]. + +**GET** `https://api.trustedservices.intel.com/sgx/certification/v4/tcb` [cite: 82] + +* **Request**: + +| Name | Type | Request Type | Required | Pattern | Description | +|:------------------------|:-------|:-------------|:---------|:------------------|:-------------------------------------------------------------------------------------------------------| +| fmspc | String | Query | True | `[0-9a-fA-F]{12}` | Base16-encoded FMSPC[cite: 83]. | +| update | String | Query | False | `(early | standard)` | TCB Info update type (default: standard). `early` provides access sooner than `standard`[cite: 83]. Cannot be used with `tcbEvaluationDataNumber`[cite: 83]. | +| tcbEvaluationDataNumber | Number | Query | False | `\d+` | Retrieves TCB info for a specific evaluation number[cite: 83]. Cannot be used with `update`[cite: 83]. | + +* **Example Requests**: + ```bash + curl -v -X GET "https://api.trustedservices.intel.com/sgx/certification/v4/tcb?fmspc={fmspc_value}&update=early" [cite: 84] + curl -v -X GET "https://api.trustedservices.intel.com/sgx/certification/v4/tcb?fmspc={fmspc_value}&tcbEvaluationDataNumber={number}" [cite: 84] + ``` + +**Response** + +* **Model**: `Appendix A: TCB info V3`[cite: 86]. (See Appendix A below). +* **Example Response**: (JSON structure as shown in the document)[cite: 85]. +* **Status Codes**: + +| Code | Model | Headers | Description | +|:-----|:----------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------| +| 200 | TcbInfoV3 | `Content-Type`: application/json[cite: 86]. `Request-ID`: Identifier[cite: 86]. `TCB-Info-Issuer-Chain`: Issuer Chain[cite: 86]. `Warning` (Optional)[cite: 86]. | Operation successful[cite: 86]. | +| 400 | | `Request-ID`: Identifier[cite: 86]. `Warning` (Optional)[cite: 86]. | Invalid request (bad `fmspc`, invalid params, or `update` & `tcbEvaluationDataNumber` used together)[cite: 86]. | +| 401 | | `Request-ID`: Identifier[cite: 86]. `Warning` (Optional)[cite: 87]. | Failed to authenticate or authorize[cite: 86]. | +| 404 | | `Request-ID`: Identifier[cite: 86]. `Warning` (Optional)[cite: 87]. | TCB info not found for the given `fmspc` or `tcbEvaluationDataNumber`[cite: 86]. | +| 410 | | `Request-ID`: Identifier[cite: 88]. `Warning` (Optional)[cite: 88]. | TCB info for the provided `tcbEvaluationDataNumber` is no longer available[cite: 88]. | +| 500 | | `Request-ID`: Identifier[cite: 88]. `Warning` (Optional)[cite: 88]. | Internal server error[cite: 88]. | +| 503 | | `Request-ID`: Identifier[cite: 88]. `Warning` (Optional)[cite: 88]. | Server currently unable to process[cite: 88]. | + +### Get TDX TCB Info V4 + +This API retrieves TDX TCB information[cite: 89]. The TCB status determination follows a similar process to SGX but +includes additional steps for TDX TEE TCB SVNs and TDX Module +Identity[cite: 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102]. + +**GET** `https://api.trustedservices.intel.com/tdx/certification/v4/tcb` [cite: 102] + +* **Request**: + +| Name | Type | Request Type | Required | Pattern | Description | +|:------------------------|:-------|:-------------|:---------|:------------------|:---------------------------------------------------------------------------------------------------------| +| fmspc | String | Query | True | `[0-9a-fA-F]{12}` | Base16-encoded FMSPC[cite: 103]. | +| update | String | Query | False | `(early | standard)` | TCB Info update type (default: standard)[cite: 103]. Cannot be used with `tcbEvaluationDataNumber`[cite: 103]. | +| tcbEvaluationDataNumber | Number | Query | False | `\d+` | Retrieves TCB info for a specific evaluation number[cite: 103]. Cannot be used with `update`[cite: 103]. | + +* **Example Requests**: + ```bash + curl -v -X GET "https://api.trustedservices.intel.com/tdx/certification/v4/tcb?fmspc={fmspc_value}&update=early" [cite: 104] + curl -v -X GET "https://api.trustedservices.intel.com/tdx/certification/v4/tcb?fmspc={fmspc_value}&tcbEvaluationDataNumber={number}" [cite: 104] + ``` + +**Response** + +* **Model**: `Appendix A: TCB info V3`[cite: 107]. (See Appendix A below). +* **Example Response**: (JSON structure including `tdxModule` and `tdxtcbcomponents` as shown in the + document)[cite: 105, 106]. +* **Status Codes**: Similar to Get SGX TCB Info V4[cite: 108]. + +### Enclave Identity V4 + +This set of APIs allows for determining if an SGX Enclave's identity matches Intel's published identity[cite: 109]. The +process involves: + +1. Retrieving the Enclave Identity (SGX QE, TDX QE, QVE, or QAE)[cite: 109]. +2. Comparing `MRSIGNER` and `ISVPRODID` fields[cite: 109]. +3. Applying `miscselectMask` and `attributesMask` and comparing the results[cite: 111, 112, 113, 114]. +4. If checks pass, determining the TCB status by finding the highest TCB Level (sorted by ISVSVN) whose ISVSVN is <= the + Enclave Report's ISVSVN[cite: 116, 117]. + +**GET** `https://api.trustedservices.intel.com/sgx/certification/v4/qe/identity` [cite: 118] +**GET** `https://api.trustedservices.intel.com/tdx/certification/v4/qe/identity` [cite: 128] +**GET** `https://api.trustedservices.intel.com/sgx/certification/v4/qve/identity` [cite: 133] +**GET** `https://api.trustedservices.intel.com/sgx/certification/v4/qae/identity` [cite: 138] + +* **Request**: + +| Name | Type | Request Type | Required | Pattern | Description | +|:------------------------|:-------|:-------------|:---------|:--------|:--------------------------------------------------------------------------------------------------------------------------------------------| +| update | String | Query | False | `(early | standard)` | Identity update type (default: standard)[cite: 118, 127, 132, 137]. Cannot be used with `tcbEvaluationDataNumber`[cite: 118, 121, 127, 132, 137]. | +| tcbEvaluationDataNumber | Number | Query | False | `\d+` | Retrieves Identity for a specific evaluation number[cite: 119, 120, 127, 132, 137]. Cannot be used with `update`[cite: 121, 127, 132, 137]. | + +* **Example Requests** (SGX QE shown): + ```bash + curl -v -X GET "https://api.trustedservices.intel.com/sgx/certification/v4/qe/identity?update=early" [cite: 122] + curl -v -X GET "https://api.trustedservices.intel.com/sgx/certification/v4/qe/identity?tcbEvaluationDataNumber={number}" [cite: 122] + ``` + +**Response** + +* **Model**: `Appendix B: Enclave Identity V2`[cite: 122, 128, 134, 139]. (See Appendix B below). +* **Example Response**: (JSON structure as shown in the document for QE[cite: 125], TDX QE[cite: 131], QVE[cite: 136], + and QAE [cite: 141]). +* **Status Codes** (SGX QE shown, others are similar): + +| Code | Model | Headers | Description | +|:-----|:------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------------------------------------------------------------------------| +| 200 | EIdentityV2 | `Content-Type`: application/json[cite: 122]. `Request-ID`: Identifier[cite: 122]. `SGX-Enclave-Identity-Issuer-Chain`: Issuer Chain[cite: 122]. `Warning` (Optional)[cite: 122]. | Operation successful[cite: 122]. | +| 400 | | `Request-ID`: Identifier[cite: 122]. `Warning` (Optional)[cite: 122]. | Invalid request (params or `update` & `tcbEvaluationDataNumber` conflict)[cite: 122]. | +| 401 | | `Request-ID`: Identifier[cite: 123]. `Warning` (Optional)[cite: 123]. | Failed to authenticate or authorize[cite: 122]. | +| 404 | | `Request-ID`: Identifier[cite: 123]. `Warning` (Optional)[cite: 123]. | Identity info not found[cite: 122]. | +| 410 | | `Request-ID`: Identifier[cite: 124]. `Warning` (Optional)[cite: 124]. | Identity info no longer available[cite: 124]. | +| 500 | | `Request-ID`: Identifier[cite: 124]. `Warning` (Optional)[cite: 124]. | Internal server error[cite: 124]. | +| 503 | | `Request-ID`: Identifier[cite: 124]. `Warning` (Optional)[cite: 124]. | Server currently unable to process[cite: 124]. | + +### Retrieve FMSPCs V4 + +Retrieves a list of FMSPC values for SGX and TDX platforms that support DCAP attestation[cite: 141]. + +**GET** `https://api.trustedservices.intel.com/sgx/certification/v4/fmspcs` [cite: 141] + +* **Request**: + +| Name | Type | Request Type | Required | Description | +|:---------|:-------|:-------------|:---------|:----------------------------------------------------------------------------| +| platform | String | Query | False | Optional platform filter: `all` (default), `client`, `E3`, `E5`[cite: 141]. | + +* **Example Request**: + ```bash + curl -v -X GET "https://api.trustedservices.intel.com/sgx/certification/v4/fmspcs?platform=E5" [cite: 141] + ``` + +**Response** + +* **Example Response**: + ```json + [ + {"platform": "E3", "fmspc": "123456789000"}, [cite: 142] + {"platform": "E5", "fmspc": "987654321000"}, [cite: 142] + {"platform": "client", "fmspc": "ABCDEF123456"} [cite: 142] + ] + ``` +* **Status Codes**: + +| Code | Headers | Description | +|:-----|:-------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------| +| 200 | `Content-Type`: application/json[cite: 142]. `Request-ID`: Identifier[cite: 142]. `Warning` (Optional)[cite: 142]. | Operation successful[cite: 142]. | +| 400 | `Request-ID`: Identifier[cite: 142]. `Warning` (Optional)[cite: 143]. | Invalid request parameters[cite: 142]. | +| 500 | `Request-ID`: Identifier[cite: 142]. `Warning` (Optional)[cite: 142]. | Internal server error[cite: 142]. | +| 503 | `Request-ID`: Identifier[cite: 142]. `Warning` (Optional)[cite: 142]. | Server currently unable to process[cite: 142]. | + +### Retrieve TCB Evaluation Data Numbers V4 + +Retrieves the list of currently supported TCB Evaluation Data Numbers and their associated TCB-R event +states[cite: 142]. + +**GET** `https://api.trustedservices.intel.com/{sgx|tdx}/certification/v4/tcbevaluationdatanumbers` [cite: 142] + +* **Example Requests**: + ```bash + curl -v -X GET "https://api.trustedservices.intel.com/sgx/certification/v4/tcbevaluationdatanumbers" [cite: 142] + curl -v -X GET "https://api.trustedservices.intel.com/tdx/certification/v4/tcbevaluationdatanumbers" [cite: 142] + ``` + +**Response** + +* **Model**: `Appendix C: TCB Evaluation Data Numbers V1`[cite: 144]. (See Appendix C below). +* **Example Response**: + ```json + { + "tcbEvaluationDataNumbers": { + "version": 1, + "issueDate": "2023-04-13T09:38:17Z", + "nextUpdate": "2023-05-13T09:38:17Z", + "tcbNumbers": [ + {"tcbEvaluationDataNumber": 12, "tcbRecoveryEventDate": "2023-04-13T00:00:00Z", "tcbDate": "2023-04-13T00:00:00Z"}, + {"tcbEvaluationDataNumber": 11, "tcbRecoveryEventDate": "2023-01-14T00:00:00Z", "tcbDate": "2023-01-14T00:00:00Z"} + ], + "signature": "..." [cite: 142] + } + } + ``` +* **Status Codes**: + +| Code | Headers | Description | +|:-----|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------| +| 200 | `Content-Type`: application/json[cite: 144]. `Request-ID`: Identifier[cite: 144]. `TCB-Evaluation-Data-Numbers-Issuer-Chain`: Issuer Chain[cite: 145]. `Warning` (Optional)[cite: 144]. | Operation successful[cite: 144]. | +| 500 | `Request-ID`: Identifier[cite: 144]. `Warning` (Optional)[cite: 144]. | Internal server error[cite: 144]. | +| 503 | `Request-ID`: Identifier[cite: 144]. `Warning` (Optional)[cite: 144]. | Server currently unable to process[cite: 146]. | + +--- + +## Appendix A: TCB Info V3 [cite: 147] + +This defines the structure of the TCB Info V3 JSON response[cite: 147]. + +* `tcbInfo`: (Object) + * `id`: (String) Identifier (e.g., "SGX", "TDX")[cite: 148]. + * `version`: (Integer) Structure version[cite: 148]. + * `issueDate`: (String - datetime) Creation timestamp (ISO 8601 UTC)[cite: 148]. + * `nextUpdate`: (String - datetime) Next update timestamp (ISO 8601 UTC)[cite: 149]. + * `fmspc`: (String) Base16-encoded FMSPC[cite: 149]. + * `pceId`: (String) Base16-encoded PCE ID[cite: 149]. + * `tcbType`: (Integer) TCB level composition type[cite: 149]. + * `tcbEvaluationDataNumber`: (Integer) Monotonically increasing sequence number, synchronized across TCB Info and + Enclave Identities, indicating updates[cite: 150, 151, 152]. + * `tdxModule`: (Object - Optional, only for TDX TCB Info)[cite: 153]. + * `mrsigner`: (String) Base16-encoded TDX SEAM module's signer measurement[cite: 154]. + * `attributes`: (String) Base16-encoded "golden" attributes[cite: 154]. + * `attributesMask`: (String) Base16-encoded attributes mask[cite: 154]. + * `tdxModuleIdentities`: (Array - Optional, for multiple TDX SEAM Modules)[cite: 154]. + * `id`: (String) Module identifier[cite: 154]. + * `mrsigner`: (String) Base16-encoded signer measurement[cite: 155]. + * `attributes`: (String) Base16-encoded "golden" attributes[cite: 155]. + * `attributesMask`: (String) Base16-encoded attributes mask[cite: 156]. + * `tcbLevels`: (Array) Sorted list of TCB levels for this module[cite: 157]. + * `tcb`: (Object) + * `isvsvn`: (Integer) ISV SVN[cite: 157]. + * `tcbDate`: (String - datetime) TCB date (ISO 8601 UTC)[cite: 158]. + * `tcbStatus`: (String) "UpToDate", "OutOfDate", or "Revoked"[cite: 158]. + * `advisoryIDs`: (Array - Optional) List of relevant `INTEL-SA-XXXXX` or `INTEL-DOC-XXXXX` + identifiers[cite: 159, 160]. + * `tcbLevels`: (Array) Sorted list of TCB levels for the FMSPC[cite: 160]. + * `tcb`: (Object) + * `sgxtcbcomponents`: (Array - Optional) 16 SGX TCB Components (SVN, Category, Type)[cite: 161]. + * `tdxtcbcomponents`: (Array - Optional, only for TDX TCB Info) 16 TDX TCB Components (SVN, Category, + Type)[cite: 161, 162, 164]. + * `pcesvn`: (Integer) PCE SVN[cite: 161]. + * `tcbDate`: (String - datetime) TCB date (ISO 8601 UTC)[cite: 165]. + * `tcbStatus`: (String) "UpToDate", "HardeningNeeded", "ConfigurationNeeded", " + ConfigurationAndHardeningNeeded", "OutOfDate", "OutOfDateConfigurationNeeded", "Revoked"[cite: 165, 166]. + * `advisoryIDs`: (Array - Optional) List of relevant `INTEL-SA-XXXXX` or `INTEL-DOC-XXXXX` + identifiers[cite: 167, 168]. + * `signature`: (String) Base16-encoded signature over the `tcbInfo` body[cite: 163]. + +--- + +## Appendix B: Enclave Identity V2 [cite: 168] + +This defines the structure of the Enclave Identity V2 JSON response[cite: 168]. + +* `enclaveIdentity`: (Object) + * `id`: (String) Identifier ("QE", "QVE", "QAE", "TD_QE")[cite: 169]. + * `version`: (Integer) Structure version[cite: 169]. + * `issueDate`: (String - datetime) Creation timestamp (ISO 8601 UTC)[cite: 170]. + * `nextUpdate`: (String - datetime) Next update timestamp (ISO 8601 UTC)[cite: 170]. + * `tcbEvaluationDataNumber`: (Integer) Monotonically increasing sequence number, synchronized across TCB Info and + Enclave Identities[cite: 171, 172]. + * `miscselect`: (String) Base16-encoded "golden" miscselect value[cite: 172]. + * `miscselectMask`: (String) Base16-encoded miscselect mask[cite: 172]. + * `attributes`: (String) Base16-encoded "golden" attributes value[cite: 172]. + * `attributesMask`: (String) Base16-encoded attributes mask[cite: 173]. + * `mrsigner`: (String) Base16-encoded mrsigner hash[cite: 173]. + * `isvprodid`: (Integer) Enclave Product ID[cite: 173]. + * `tcbLevels`: (Array) Sorted list of Enclave TCB levels[cite: 173]. + * `tcb`: (Object) + * `isvsvn`: (Integer) Enclave's ISV SVN[cite: 173]. + * `tcbDate`: (String - datetime) TCB date (ISO 8601 UTC)[cite: 174]. + * `tcbStatus`: (String) "UpToDate", "OutOfDate", or "Revoked"[cite: 174, 176]. + * `advisoryIDs`: (Array - Optional) List of relevant `INTEL-SA-XXXXX` or `INTEL-DOC-XXXXX` + identifiers[cite: 177]. + * `signature`: (String) Base16-encoded signature over the `enclaveIdentity` body[cite: 175]. + +--- + +## Appendix C: TCB Evaluation Data Numbers V1 [cite: 177] + +This defines the structure of the TCB Evaluation Data Numbers V1 JSON response[cite: 177]. + +* `tcbEvaluationDataNumbers`: (Object) + * `id`: (String) Identifier ("SGX" or "TDX")[cite: 178]. + * `version`: (Integer) Structure version[cite: 178]. + * `issueDate`: (String - datetime) Creation timestamp (ISO 8601 UTC)[cite: 178]. + * `nextUpdate`: (String - datetime) Suggested next call timestamp (ISO 8601 UTC)[cite: 179]. + * `tcbNumbers`: (Array) List of TCB Evaluation Data Number objects[cite: 179]. + * `tcbEvaluationDataNumber`: (Integer) The number itself[cite: 179]. + * `tcbRecoveryEventDate`: (String - datetime) The date Intel first publishes related collateral (ISO 8601 + UTC)[cite: 179]. + * `tcbDate`: (String - datetime) TCB date (ISO 8601 UTC)[cite: 180, 181]. + * `signature`: (String) Base16-encoded signature over the structure's body[cite: 181]. + +--- + +## Appendix D: PCK Certificate and CRL Specification + +This section refers to an external document that specifies the hierarchy and format of X.509 v3 certificates and X.509 +v2 CRLs issued by Intel for Provisioning Certification Keys[cite: 181]. + +--- + +**Notes on TCB Status and Enforcement:** + +* **Enforcement Grace Periods**: Intel provides "early" and "standard" update parameters, offering different enforcement + grace periods[cite: 182]. The attestation result depends on which parameter is used[cite: 182]. +* **Relying Party Trust Decisions**: Relying parties can use additional factors beyond the attestation result to make + trust decisions[cite: 183]. They might accept risks even if a platform is technically "OutOfDate" due to low-severity + issues[cite: 184]. +* **Communication**: Intel aims to communicate planned deviations via email to registered API subscribers[cite: 185]. diff --git a/crates/intel-dcap-api/tests/mock_api_tests.rs b/crates/intel-dcap-api/tests/mock_api_tests.rs new file mode 100644 index 0000000..34a1f39 --- /dev/null +++ b/crates/intel-dcap-api/tests/mock_api_tests.rs @@ -0,0 +1,312 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright (c) 2025 Matter Labs + +use intel_dcap_api::{ApiClient, ApiVersion, CaType, IntelApiError, UpdateType}; +use mockito::Server; +use reqwest::Client; + +// Create a test client without TLS requirements +async fn create_test_client(base_url: &str) -> ApiClient { + // Create a custom client without TLS requirements for testing + ApiClient::new_with_base_url(base_url).expect("Failed to create client") +} + +#[tokio::test] +async fn test_simple_request() { + let mut server = Server::new_async().await; + + // First, test with plain reqwest to ensure mock works + let _m = server + .mock("GET", "/test") + .with_status(200) + .with_body("test") + .create_async() + .await; + + let client = Client::new(); + let resp = client + .get(format!("{}/test", server.url())) + .send() + .await + .unwrap(); + assert_eq!(resp.status(), 200); + assert_eq!(resp.text().await.unwrap(), "test"); +} + +#[tokio::test] +async fn test_tdx_tcb_minimal() { + let mut server = Server::new_async().await; + + // Use minimal response + let _m = server + .mock("GET", "/tdx/certification/v4/tcb") + .match_query(mockito::Matcher::UrlEncoded( + "fmspc".into(), + "test123".into(), + )) + .with_status(200) + .with_header("TCB-Info-Issuer-Chain", "test-cert") + .with_body("{}") + .create_async() + .await; + + let client = create_test_client(&server.url()).await; + let result = client.get_tdx_tcb_info("test123", None, None).await; + + match &result { + Ok(resp) => { + assert_eq!(resp.tcb_info_json, "{}"); + assert_eq!(resp.issuer_chain, "test-cert"); + } + Err(e) => { + eprintln!("Error: {:?}", e); + panic!("Request failed"); + } + } +} + +#[tokio::test] +async fn test_sgx_qe_identity_minimal() { + let mut server = Server::new_async().await; + + let _m = server + .mock("GET", "/sgx/certification/v4/qe/identity") + .with_status(200) + .with_header("SGX-Enclave-Identity-Issuer-Chain", "test-cert") + .with_body("{}") + .create_async() + .await; + + let client = create_test_client(&server.url()).await; + let result = client.get_sgx_qe_identity(None, None).await; + + assert!(result.is_ok()); + let resp = result.unwrap(); + assert_eq!(resp.enclave_identity_json, "{}"); + assert_eq!(resp.issuer_chain, "test-cert"); +} + +#[tokio::test] +async fn test_pck_crl_minimal() { + let mut server = Server::new_async().await; + + let _m = server + .mock("GET", "/sgx/certification/v4/pckcrl") + .match_query(mockito::Matcher::UrlEncoded( + "ca".into(), + "processor".into(), + )) + .with_status(200) + .with_header("SGX-PCK-CRL-Issuer-Chain", "test-cert") + .with_body("test-crl") + .create_async() + .await; + + let client = create_test_client(&server.url()).await; + let result = client.get_pck_crl(CaType::Processor, None).await; + + assert!(result.is_ok()); + let resp = result.unwrap(); + assert_eq!(String::from_utf8_lossy(&resp.crl_data), "test-crl"); + assert_eq!(resp.issuer_chain, "test-cert"); +} + +#[tokio::test] +async fn test_error_handling() { + let mut server = Server::new_async().await; + + let _m = server + .mock("GET", "/sgx/certification/v4/tcb") + .match_query(mockito::Matcher::UrlEncoded("fmspc".into(), "bad".into())) + .with_status(404) + .with_header("Request-ID", "test-123") + .create_async() + .await; + + let client = create_test_client(&server.url()).await; + let result = client.get_sgx_tcb_info("bad", None, None).await; + + assert!(result.is_err()); + match result.unwrap_err() { + IntelApiError::ApiError { + status, request_id, .. + } => { + assert_eq!(status.as_u16(), 404); + assert_eq!(request_id, "test-123"); + } + _ => panic!("Wrong error type"), + } +} + +#[tokio::test] +async fn test_update_types() { + let mut server = Server::new_async().await; + + // Test Early update type + let _m1 = server + .mock("GET", "/tdx/certification/v4/tcb") + .match_query(mockito::Matcher::AllOf(vec![ + mockito::Matcher::UrlEncoded("fmspc".into(), "test".into()), + mockito::Matcher::UrlEncoded("update".into(), "early".into()), + ])) + .with_status(200) + .with_header("TCB-Info-Issuer-Chain", "cert") + .with_body("{\"early\":true}") + .create_async() + .await; + + let client = create_test_client(&server.url()).await; + let result = client + .get_tdx_tcb_info("test", Some(UpdateType::Early), None) + .await; + assert!(result.is_ok()); + assert_eq!(result.unwrap().tcb_info_json, "{\"early\":true}"); + + // Test Standard update type + let _m2 = server + .mock("GET", "/tdx/certification/v4/tcb") + .match_query(mockito::Matcher::AllOf(vec![ + mockito::Matcher::UrlEncoded("fmspc".into(), "test".into()), + mockito::Matcher::UrlEncoded("update".into(), "standard".into()), + ])) + .with_status(200) + .with_header("TCB-Info-Issuer-Chain", "cert") + .with_body("{\"standard\":true}") + .create_async() + .await; + + let result2 = client + .get_tdx_tcb_info("test", Some(UpdateType::Standard), None) + .await; + assert!(result2.is_ok()); + assert_eq!(result2.unwrap().tcb_info_json, "{\"standard\":true}"); +} + +#[tokio::test] +async fn test_v3_api_headers() { + let mut server = Server::new_async().await; + + // V3 uses different header names for CRL + let _m = server + .mock("GET", "/sgx/certification/v3/pckcrl") + .match_query(mockito::Matcher::UrlEncoded("ca".into(), "platform".into())) + .with_status(200) + .with_header("SGX-PCK-CRL-Issuer-Chain", "v3-cert") + .with_body("v3-crl-data") + .create_async() + .await; + + let client = ApiClient::new_with_options(server.url(), ApiVersion::V3).unwrap(); + let result = client.get_pck_crl(CaType::Platform, None).await; + + assert!(result.is_ok()); + let resp = result.unwrap(); + assert_eq!(String::from_utf8_lossy(&resp.crl_data), "v3-crl-data"); + assert_eq!(resp.issuer_chain, "v3-cert"); +} + +#[tokio::test] +async fn test_sgx_qve_identity() { + let mut server = Server::new_async().await; + + let _m = server + .mock("GET", "/sgx/certification/v4/qve/identity") + .with_status(200) + .with_header("SGX-Enclave-Identity-Issuer-Chain", "qve-cert") + .with_body("{\"id\":\"QVE\"}") + .create_async() + .await; + + let client = create_test_client(&server.url()).await; + let result = client.get_sgx_qve_identity(None, None).await; + + assert!(result.is_ok()); + let resp = result.unwrap(); + assert_eq!(resp.enclave_identity_json, "{\"id\":\"QVE\"}"); + assert_eq!(resp.issuer_chain, "qve-cert"); +} + +#[tokio::test] +async fn test_tdx_qe_identity() { + let mut server = Server::new_async().await; + + let _m = server + .mock("GET", "/tdx/certification/v4/qe/identity") + .with_status(200) + .with_header("SGX-Enclave-Identity-Issuer-Chain", "tdx-qe-cert") + .with_body("{\"id\":\"TDX-QE\"}") + .create_async() + .await; + + let client = create_test_client(&server.url()).await; + let result = client.get_tdx_qe_identity(None, None).await; + + assert!(result.is_ok()); + let resp = result.unwrap(); + assert_eq!(resp.enclave_identity_json, "{\"id\":\"TDX-QE\"}"); + assert_eq!(resp.issuer_chain, "tdx-qe-cert"); +} + +#[tokio::test] +async fn test_error_with_details() { + let mut server = Server::new_async().await; + + let _m = server + .mock("GET", "/sgx/certification/v4/pckcert") + .match_query(mockito::Matcher::Any) + .with_status(400) + .with_header("Request-ID", "error-req-123") + .with_header("Error-Code", "InvalidParameter") + .with_header("Error-Message", "PPID format is invalid") + .create_async() + .await; + + let client = create_test_client(&server.url()).await; + let result = client + .get_pck_certificate_by_ppid("bad", "bad", "bad", "bad", None, None) + .await; + + assert!(result.is_err()); + match result.unwrap_err() { + IntelApiError::ApiError { + status, + request_id, + error_code, + error_message, + } => { + assert_eq!(status.as_u16(), 400); + assert_eq!(request_id, "error-req-123"); + assert_eq!(error_code.as_deref(), Some("InvalidParameter")); + assert_eq!(error_message.as_deref(), Some("PPID format is invalid")); + } + _ => panic!("Wrong error type"), + } +} + +#[tokio::test] +async fn test_sgx_tcb_info() { + let mut server = Server::new_async().await; + + let _m = server + .mock("GET", "/sgx/certification/v4/tcb") + .match_query(mockito::Matcher::UrlEncoded( + "fmspc".into(), + "00606A6A0000".into(), + )) + .with_status(200) + .with_header("TCB-Info-Issuer-Chain", "sgx-tcb-cert") + .with_body("{\"tcbInfo\":{\"fmspc\":\"00606A6A0000\"}}") + .create_async() + .await; + + let client = create_test_client(&server.url()).await; + let result = client.get_sgx_tcb_info("00606A6A0000", None, None).await; + + assert!(result.is_ok()); + let resp = result.unwrap(); + assert_eq!( + resp.tcb_info_json, + "{\"tcbInfo\":{\"fmspc\":\"00606A6A0000\"}}" + ); + assert_eq!(resp.issuer_chain, "sgx-tcb-cert"); +} diff --git a/crates/intel-dcap-api/tests/real_data_mock_tests.rs b/crates/intel-dcap-api/tests/real_data_mock_tests.rs new file mode 100644 index 0000000..026335d --- /dev/null +++ b/crates/intel-dcap-api/tests/real_data_mock_tests.rs @@ -0,0 +1,901 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright (c) 2025 Matter Labs + +use intel_dcap_api::{ + ApiClient, ApiVersion, CaType, CrlEncoding, IntelApiError, PlatformFilter, UpdateType, +}; +use mockito::Server; +use percent_encoding::{percent_encode, NON_ALPHANUMERIC}; +use serde_json::Value; + +// Include real test data +const TDX_TCB_INFO_DATA: &[u8] = include_bytes!("test_data/tdx_tcb_info.json"); +const PCK_CRL_PROCESSOR_DATA: &[u8] = include_bytes!("test_data/pck_crl_processor.json"); +const PCK_CRL_PLATFORM_DATA: &[u8] = include_bytes!("test_data/pck_crl_platform.json"); +const SGX_QE_IDENTITY_DATA: &[u8] = include_bytes!("test_data/sgx_qe_identity.json"); +const SGX_QVE_IDENTITY_DATA: &[u8] = include_bytes!("test_data/sgx_qve_identity.json"); +const TDX_QE_IDENTITY_DATA: &[u8] = include_bytes!("test_data/tdx_qe_identity.json"); +const SGX_TCB_INFO_ALT_DATA: &[u8] = include_bytes!("test_data/sgx_tcb_info_alt.json"); +const SGX_QAE_IDENTITY_DATA: &[u8] = include_bytes!("test_data/sgx_qae_identity.json"); +const FMSPCS_DATA: &[u8] = include_bytes!("test_data/fmspcs.json"); +const SGX_TCB_EVAL_NUMS_DATA: &[u8] = include_bytes!("test_data/sgx_tcb_eval_nums.json"); +const TDX_TCB_EVAL_NUMS_DATA: &[u8] = include_bytes!("test_data/tdx_tcb_eval_nums.json"); +const PCK_CRL_PROCESSOR_DER_DATA: &[u8] = include_bytes!("test_data/pck_crl_processor_der.json"); +const SGX_TCB_INFO_EARLY_DATA: &[u8] = include_bytes!("test_data/sgx_tcb_info_early.json"); +const TDX_TCB_INFO_EVAL17_DATA: &[u8] = include_bytes!("test_data/tdx_tcb_info_eval17.json"); +const FMSPCS_NO_FILTER_DATA: &[u8] = include_bytes!("test_data/fmspcs_no_filter.json"); +// const FMSPCS_ALL_PLATFORMS_DATA: &[u8] = include_bytes!("test_data/fmspcs_all_platforms.json"); // Reserved for future use +const SGX_QE_IDENTITY_V3_DATA: &[u8] = include_bytes!("test_data/sgx_qe_identity_v3.json"); +const SGX_TCB_INFO_V3_DATA: &[u8] = include_bytes!("test_data/sgx_tcb_info_v3.json"); +const TDX_TCB_INFO_ALT_DATA: &[u8] = include_bytes!("test_data/tdx_tcb_info_00806F050000.json"); + +fn parse_test_data(data: &[u8]) -> Value { + serde_json::from_slice(data).expect("Failed to parse test data") +} + +#[tokio::test] +async fn test_tdx_tcb_info_with_real_data() { + let mut server = Server::new_async().await; + let test_data = parse_test_data(TDX_TCB_INFO_DATA); + + // URL encode the issuer chain header value + let issuer_chain = test_data["issuer_chain"].as_str().unwrap(); + let encoded_issuer_chain = + percent_encode(issuer_chain.as_bytes(), NON_ALPHANUMERIC).to_string(); + + let _m = server + .mock("GET", "/tdx/certification/v4/tcb") + .match_query(mockito::Matcher::UrlEncoded( + "fmspc".into(), + "00806F050000".into(), + )) + .with_status(200) + .with_header("Content-Type", "application/json") + .with_header("TCB-Info-Issuer-Chain", &encoded_issuer_chain) + .with_body(test_data["tcb_info_json"].as_str().unwrap()) + .create_async() + .await; + + let client = ApiClient::new_with_base_url(server.url()).unwrap(); + let result = client.get_tdx_tcb_info("00806F050000", None, None).await; + + if let Err(e) = &result { + eprintln!("Error: {:?}", e); + eprintln!("Server URL: {}", server.url()); + } + + assert!(result.is_ok()); + let response = result.unwrap(); + assert_eq!( + response.tcb_info_json, + test_data["tcb_info_json"].as_str().unwrap() + ); + assert_eq!( + response.issuer_chain, + test_data["issuer_chain"].as_str().unwrap() + ); + + // Verify the JSON can be parsed + let tcb_info: Value = serde_json::from_str(&response.tcb_info_json).unwrap(); + assert_eq!(tcb_info["tcbInfo"]["fmspc"], "00806F050000"); + assert_eq!(tcb_info["tcbInfo"]["id"], "TDX"); +} + +#[tokio::test] +async fn test_sgx_qe_identity_with_real_data() { + let mut server = Server::new_async().await; + let test_data = parse_test_data(SGX_QE_IDENTITY_DATA); + + let issuer_chain = test_data["issuer_chain"].as_str().unwrap(); + let encoded_issuer_chain = + percent_encode(issuer_chain.as_bytes(), NON_ALPHANUMERIC).to_string(); + + let _m = server + .mock("GET", "/sgx/certification/v4/qe/identity") + .with_status(200) + .with_header("Content-Type", "application/json") + .with_header("SGX-Enclave-Identity-Issuer-Chain", &encoded_issuer_chain) + .with_body(test_data["enclave_identity_json"].as_str().unwrap()) + .create_async() + .await; + + let client = ApiClient::new_with_base_url(server.url()).unwrap(); + let result = client.get_sgx_qe_identity(None, None).await; + + assert!(result.is_ok()); + let response = result.unwrap(); + assert_eq!( + response.enclave_identity_json, + test_data["enclave_identity_json"].as_str().unwrap() + ); + assert_eq!( + response.issuer_chain, + test_data["issuer_chain"].as_str().unwrap() + ); + + // Verify the JSON structure + let identity: Value = serde_json::from_str(&response.enclave_identity_json).unwrap(); + assert_eq!(identity["enclaveIdentity"]["id"], "QE"); +} + +#[tokio::test] +async fn test_sgx_qve_identity_with_real_data() { + let mut server = Server::new_async().await; + let test_data = parse_test_data(SGX_QVE_IDENTITY_DATA); + + let issuer_chain = test_data["issuer_chain"].as_str().unwrap(); + let encoded_issuer_chain = + percent_encode(issuer_chain.as_bytes(), NON_ALPHANUMERIC).to_string(); + + let _m = server + .mock("GET", "/sgx/certification/v4/qve/identity") + .with_status(200) + .with_header("Content-Type", "application/json") + .with_header("SGX-Enclave-Identity-Issuer-Chain", &encoded_issuer_chain) + .with_body(test_data["enclave_identity_json"].as_str().unwrap()) + .create_async() + .await; + + let client = ApiClient::new_with_base_url(server.url()).unwrap(); + let result = client.get_sgx_qve_identity(None, None).await; + + assert!(result.is_ok()); + let response = result.unwrap(); + + // Verify the JSON structure + let identity: Value = serde_json::from_str(&response.enclave_identity_json).unwrap(); + assert_eq!(identity["enclaveIdentity"]["id"], "QVE"); +} + +#[tokio::test] +async fn test_tdx_qe_identity_with_real_data() { + let mut server = Server::new_async().await; + let test_data = parse_test_data(TDX_QE_IDENTITY_DATA); + + let issuer_chain = test_data["issuer_chain"].as_str().unwrap(); + let encoded_issuer_chain = + percent_encode(issuer_chain.as_bytes(), NON_ALPHANUMERIC).to_string(); + + let _m = server + .mock("GET", "/tdx/certification/v4/qe/identity") + .with_status(200) + .with_header("Content-Type", "application/json") + .with_header("SGX-Enclave-Identity-Issuer-Chain", &encoded_issuer_chain) + .with_body(test_data["enclave_identity_json"].as_str().unwrap()) + .create_async() + .await; + + let client = ApiClient::new_with_base_url(server.url()).unwrap(); + let result = client.get_tdx_qe_identity(None, None).await; + + assert!(result.is_ok()); + let response = result.unwrap(); + + // Verify the JSON structure + let identity: Value = serde_json::from_str(&response.enclave_identity_json).unwrap(); + assert_eq!(identity["enclaveIdentity"]["id"], "TD_QE"); +} + +#[tokio::test] +async fn test_pck_crl_processor_with_real_data() { + let mut server = Server::new_async().await; + let test_data = parse_test_data(PCK_CRL_PROCESSOR_DATA); + + let issuer_chain = test_data["issuer_chain"].as_str().unwrap(); + let encoded_issuer_chain = + percent_encode(issuer_chain.as_bytes(), NON_ALPHANUMERIC).to_string(); + + let _m = server + .mock("GET", "/sgx/certification/v4/pckcrl") + .match_query(mockito::Matcher::UrlEncoded( + "ca".into(), + "processor".into(), + )) + .with_status(200) + .with_header("SGX-PCK-CRL-Issuer-Chain", &encoded_issuer_chain) + .with_body(test_data["crl_data"].as_str().unwrap()) + .create_async() + .await; + + let client = ApiClient::new_with_base_url(server.url()).unwrap(); + let result = client.get_pck_crl(CaType::Processor, None).await; + + assert!(result.is_ok()); + let response = result.unwrap(); + assert_eq!( + String::from_utf8_lossy(&response.crl_data), + test_data["crl_data"].as_str().unwrap() + ); + assert_eq!( + response.issuer_chain, + test_data["issuer_chain"].as_str().unwrap() + ); + + // Verify it's a valid CRL format + let crl_str = String::from_utf8_lossy(&response.crl_data); + assert!(crl_str.contains("BEGIN X509 CRL")); + assert!(crl_str.contains("END X509 CRL")); +} + +#[tokio::test] +async fn test_pck_crl_platform_with_real_data() { + let mut server = Server::new_async().await; + let test_data = parse_test_data(PCK_CRL_PLATFORM_DATA); + + let issuer_chain = test_data["issuer_chain"].as_str().unwrap(); + let encoded_issuer_chain = + percent_encode(issuer_chain.as_bytes(), NON_ALPHANUMERIC).to_string(); + + let _m = server + .mock("GET", "/sgx/certification/v4/pckcrl") + .match_query(mockito::Matcher::UrlEncoded("ca".into(), "platform".into())) + .with_status(200) + .with_header("SGX-PCK-CRL-Issuer-Chain", &encoded_issuer_chain) + .with_body(test_data["crl_data"].as_str().unwrap()) + .create_async() + .await; + + let client = ApiClient::new_with_base_url(server.url()).unwrap(); + let result = client.get_pck_crl(CaType::Platform, None).await; + + assert!(result.is_ok()); + let response = result.unwrap(); + + // Verify issuer chain contains multiple certificates + assert!(response.issuer_chain.contains("BEGIN CERTIFICATE")); + assert!(response.issuer_chain.contains("END CERTIFICATE")); +} + +#[tokio::test] +async fn test_sgx_tcb_info_alt_with_real_data() { + let mut server = Server::new_async().await; + let test_data = parse_test_data(SGX_TCB_INFO_ALT_DATA); + + let issuer_chain = test_data["issuer_chain"].as_str().unwrap(); + let encoded_issuer_chain = + percent_encode(issuer_chain.as_bytes(), NON_ALPHANUMERIC).to_string(); + + let _m = server + .mock("GET", "/sgx/certification/v4/tcb") + .match_query(mockito::Matcher::UrlEncoded( + "fmspc".into(), + "00906ED50000".into(), + )) + .with_status(200) + .with_header("Content-Type", "application/json") + .with_header("TCB-Info-Issuer-Chain", &encoded_issuer_chain) + .with_body(test_data["tcb_info_json"].as_str().unwrap()) + .create_async() + .await; + + let client = ApiClient::new_with_base_url(server.url()).unwrap(); + let result = client.get_sgx_tcb_info("00906ED50000", None, None).await; + + assert!(result.is_ok()); + let response = result.unwrap(); + + // Verify the JSON structure + let tcb_info: Value = serde_json::from_str(&response.tcb_info_json).unwrap(); + assert_eq!(tcb_info["tcbInfo"]["fmspc"], "00906ED50000"); + assert_eq!(tcb_info["tcbInfo"]["id"], "SGX"); +} + +#[tokio::test] +async fn test_tdx_tcb_with_update_type() { + let mut server = Server::new_async().await; + let test_data = parse_test_data(TDX_TCB_INFO_DATA); + + // Test with Early update type + let issuer_chain = test_data["issuer_chain"].as_str().unwrap(); + let encoded_issuer_chain = + percent_encode(issuer_chain.as_bytes(), NON_ALPHANUMERIC).to_string(); + + let _m1 = server + .mock("GET", "/tdx/certification/v4/tcb") + .match_query(mockito::Matcher::AllOf(vec![ + mockito::Matcher::UrlEncoded("fmspc".into(), "00806F050000".into()), + mockito::Matcher::UrlEncoded("update".into(), "early".into()), + ])) + .with_status(200) + .with_header("TCB-Info-Issuer-Chain", &encoded_issuer_chain) + .with_body(test_data["tcb_info_json"].as_str().unwrap()) + .create_async() + .await; + + let client = ApiClient::new_with_base_url(server.url()).unwrap(); + let result = client + .get_tdx_tcb_info("00806F050000", Some(UpdateType::Early), None) + .await; + assert!(result.is_ok()); +} + +#[tokio::test] +async fn test_error_handling_with_intel_headers() { + let mut server = Server::new_async().await; + + // Real error response from Intel API + let _m = server + .mock("GET", "/sgx/certification/v4/tcb") + .match_query(mockito::Matcher::UrlEncoded( + "fmspc".into(), + "invalid".into(), + )) + .with_status(404) + .with_header("Request-ID", "abc123def456") + .create_async() + .await; + + let client = ApiClient::new_with_base_url(server.url()).unwrap(); + let result = client.get_sgx_tcb_info("invalid", None, None).await; + + assert!(result.is_err()); + match result.unwrap_err() { + IntelApiError::ApiError { + status, request_id, .. + } => { + assert_eq!(status.as_u16(), 404); + assert_eq!(request_id, "abc123def456"); + } + _ => panic!("Expected ApiError"), + } +} + +#[tokio::test] +async fn test_v3_api_with_real_data() { + let mut server = Server::new_async().await; + let test_data = parse_test_data(PCK_CRL_PROCESSOR_DATA); + + // V3 uses different header names + let issuer_chain = test_data["issuer_chain"].as_str().unwrap(); + let encoded_issuer_chain = + percent_encode(issuer_chain.as_bytes(), NON_ALPHANUMERIC).to_string(); + + let _m = server + .mock("GET", "/sgx/certification/v3/pckcrl") + .match_query(mockito::Matcher::UrlEncoded( + "ca".into(), + "processor".into(), + )) + .with_status(200) + .with_header("SGX-PCK-CRL-Issuer-Chain", &encoded_issuer_chain) + .with_body(test_data["crl_data"].as_str().unwrap()) + .create_async() + .await; + + let client = ApiClient::new_with_options(server.url(), ApiVersion::V3).unwrap(); + let result = client.get_pck_crl(CaType::Processor, None).await; + + assert!(result.is_ok()); + let response = result.unwrap(); + assert_eq!( + String::from_utf8_lossy(&response.crl_data), + test_data["crl_data"].as_str().unwrap() + ); +} + +#[tokio::test] +async fn test_sgx_qae_identity_with_real_data() { + let mut server = Server::new_async().await; + let test_data = parse_test_data(SGX_QAE_IDENTITY_DATA); + + let issuer_chain = test_data["issuer_chain"].as_str().unwrap(); + let encoded_issuer_chain = + percent_encode(issuer_chain.as_bytes(), NON_ALPHANUMERIC).to_string(); + + let _m = server + .mock("GET", "/sgx/certification/v4/qae/identity") + .with_status(200) + .with_header("Content-Type", "application/json") + .with_header("SGX-Enclave-Identity-Issuer-Chain", &encoded_issuer_chain) + .with_body(test_data["enclave_identity_json"].as_str().unwrap()) + .create_async() + .await; + + let client = ApiClient::new_with_base_url(server.url()).unwrap(); + let result = client.get_sgx_qae_identity(None, None).await; + + assert!(result.is_ok()); + let response = result.unwrap(); + assert_eq!( + response.enclave_identity_json, + test_data["enclave_identity_json"].as_str().unwrap() + ); + assert_eq!( + response.issuer_chain, + test_data["issuer_chain"].as_str().unwrap() + ); + + // Verify the JSON structure + let identity: Value = serde_json::from_str(&response.enclave_identity_json).unwrap(); + assert_eq!(identity["enclaveIdentity"]["id"], "QAE"); +} + +#[tokio::test] +async fn test_get_fmspcs_with_real_data() { + let mut server = Server::new_async().await; + let test_data = parse_test_data(FMSPCS_DATA); + + let _m = server + .mock("GET", "/sgx/certification/v4/fmspcs") + .match_query(mockito::Matcher::UrlEncoded( + "platform".into(), + "all".into(), + )) + .with_status(200) + .with_header("Content-Type", "application/json") + .with_body(test_data["fmspcs_json"].as_str().unwrap()) + .create_async() + .await; + + let client = ApiClient::new_with_base_url(server.url()).unwrap(); + let result = client.get_fmspcs(Some(PlatformFilter::All)).await; + + assert!(result.is_ok()); + let fmspcs_json = result.unwrap(); + assert_eq!(fmspcs_json, test_data["fmspcs_json"].as_str().unwrap()); + + // Verify the JSON structure + let fmspcs: Value = serde_json::from_str(&fmspcs_json).unwrap(); + assert!(fmspcs.is_array()); + assert!(!fmspcs.as_array().unwrap().is_empty()); +} + +#[tokio::test] +async fn test_sgx_tcb_evaluation_data_numbers_with_real_data() { + let mut server = Server::new_async().await; + let test_data = parse_test_data(SGX_TCB_EVAL_NUMS_DATA); + + let issuer_chain = test_data["issuer_chain"].as_str().unwrap(); + let encoded_issuer_chain = + percent_encode(issuer_chain.as_bytes(), NON_ALPHANUMERIC).to_string(); + + let _m = server + .mock("GET", "/sgx/certification/v4/tcbevaluationdatanumbers") + .with_status(200) + .with_header("Content-Type", "application/json") + .with_header( + "TCB-Evaluation-Data-Numbers-Issuer-Chain", + &encoded_issuer_chain, + ) + .with_body( + test_data["tcb_evaluation_data_numbers_json"] + .as_str() + .unwrap(), + ) + .create_async() + .await; + + let client = ApiClient::new_with_base_url(server.url()).unwrap(); + let result = client.get_sgx_tcb_evaluation_data_numbers().await; + + assert!(result.is_ok()); + let response = result.unwrap(); + assert_eq!( + response.tcb_evaluation_data_numbers_json, + test_data["tcb_evaluation_data_numbers_json"] + .as_str() + .unwrap() + ); + assert_eq!( + response.issuer_chain, + test_data["issuer_chain"].as_str().unwrap() + ); + + // Verify the JSON structure + let eval_nums: Value = + serde_json::from_str(&response.tcb_evaluation_data_numbers_json).unwrap(); + assert!(eval_nums.is_object()); +} + +#[tokio::test] +async fn test_tdx_tcb_evaluation_data_numbers_with_real_data() { + let mut server = Server::new_async().await; + let test_data = parse_test_data(TDX_TCB_EVAL_NUMS_DATA); + + let issuer_chain = test_data["issuer_chain"].as_str().unwrap(); + let encoded_issuer_chain = + percent_encode(issuer_chain.as_bytes(), NON_ALPHANUMERIC).to_string(); + + let _m = server + .mock("GET", "/tdx/certification/v4/tcbevaluationdatanumbers") + .with_status(200) + .with_header("Content-Type", "application/json") + .with_header( + "TCB-Evaluation-Data-Numbers-Issuer-Chain", + &encoded_issuer_chain, + ) + .with_body( + test_data["tcb_evaluation_data_numbers_json"] + .as_str() + .unwrap(), + ) + .create_async() + .await; + + let client = ApiClient::new_with_base_url(server.url()).unwrap(); + let result = client.get_tdx_tcb_evaluation_data_numbers().await; + + assert!(result.is_ok()); + let response = result.unwrap(); + assert_eq!( + response.tcb_evaluation_data_numbers_json, + test_data["tcb_evaluation_data_numbers_json"] + .as_str() + .unwrap() + ); + assert_eq!( + response.issuer_chain, + test_data["issuer_chain"].as_str().unwrap() + ); +} + +#[tokio::test] +async fn test_pck_crl_der_encoding_with_real_data() { + let mut server = Server::new_async().await; + let test_data = parse_test_data(PCK_CRL_PROCESSOR_DER_DATA); + + let issuer_chain = test_data["issuer_chain"].as_str().unwrap(); + let encoded_issuer_chain = + percent_encode(issuer_chain.as_bytes(), NON_ALPHANUMERIC).to_string(); + + // The DER data is stored as base64 in our test data + let crl_base64 = test_data["crl_data_base64"].as_str().unwrap(); + use base64::{engine::general_purpose, Engine as _}; + let crl_der = general_purpose::STANDARD.decode(crl_base64).unwrap(); + + let _m = server + .mock("GET", "/sgx/certification/v4/pckcrl") + .match_query(mockito::Matcher::AllOf(vec![ + mockito::Matcher::UrlEncoded("ca".into(), "processor".into()), + mockito::Matcher::UrlEncoded("encoding".into(), "der".into()), + ])) + .with_status(200) + .with_header("SGX-PCK-CRL-Issuer-Chain", &encoded_issuer_chain) + .with_body(crl_der) + .create_async() + .await; + + let client = ApiClient::new_with_base_url(server.url()).unwrap(); + let result = client + .get_pck_crl(CaType::Processor, Some(CrlEncoding::Der)) + .await; + + assert!(result.is_ok()); + let response = result.unwrap(); + + // Verify the response data matches + let response_base64 = general_purpose::STANDARD.encode(&response.crl_data); + assert_eq!(response_base64, crl_base64); + assert_eq!( + response.issuer_chain, + test_data["issuer_chain"].as_str().unwrap() + ); +} + +#[tokio::test] +async fn test_sgx_tcb_info_early_update_with_real_data() { + let mut server = Server::new_async().await; + let test_data = parse_test_data(SGX_TCB_INFO_EARLY_DATA); + + let issuer_chain = test_data["issuer_chain"].as_str().unwrap(); + let encoded_issuer_chain = + percent_encode(issuer_chain.as_bytes(), NON_ALPHANUMERIC).to_string(); + + let _m = server + .mock("GET", "/sgx/certification/v4/tcb") + .match_query(mockito::Matcher::AllOf(vec![ + mockito::Matcher::UrlEncoded("fmspc".into(), "00906ED50000".into()), + mockito::Matcher::UrlEncoded("update".into(), "early".into()), + ])) + .with_status(200) + .with_header("Content-Type", "application/json") + .with_header("TCB-Info-Issuer-Chain", &encoded_issuer_chain) + .with_body(test_data["tcb_info_json"].as_str().unwrap()) + .create_async() + .await; + + let client = ApiClient::new_with_base_url(server.url()).unwrap(); + let result = client + .get_sgx_tcb_info("00906ED50000", Some(UpdateType::Early), None) + .await; + + assert!(result.is_ok()); + let response = result.unwrap(); + assert_eq!( + response.tcb_info_json, + test_data["tcb_info_json"].as_str().unwrap() + ); + + // Verify the JSON structure + let tcb_info: Value = serde_json::from_str(&response.tcb_info_json).unwrap(); + assert_eq!(tcb_info["tcbInfo"]["fmspc"], "00906ED50000"); +} + +#[tokio::test] +async fn test_tdx_tcb_info_with_eval_number_with_real_data() { + let mut server = Server::new_async().await; + let test_data = parse_test_data(TDX_TCB_INFO_EVAL17_DATA); + + let issuer_chain = test_data["issuer_chain"].as_str().unwrap(); + let encoded_issuer_chain = + percent_encode(issuer_chain.as_bytes(), NON_ALPHANUMERIC).to_string(); + + let _m = server + .mock("GET", "/tdx/certification/v4/tcb") + .match_query(mockito::Matcher::AllOf(vec![ + mockito::Matcher::UrlEncoded("fmspc".into(), "00806F050000".into()), + mockito::Matcher::UrlEncoded("tcbEvaluationDataNumber".into(), "17".into()), + ])) + .with_status(200) + .with_header("Content-Type", "application/json") + .with_header("TCB-Info-Issuer-Chain", &encoded_issuer_chain) + .with_body(test_data["tcb_info_json"].as_str().unwrap()) + .create_async() + .await; + + let client = ApiClient::new_with_base_url(server.url()).unwrap(); + let result = client + .get_tdx_tcb_info("00806F050000", None, Some(17)) + .await; + + assert!(result.is_ok()); + let response = result.unwrap(); + + // Verify the response + let tcb_info: Value = serde_json::from_str(&response.tcb_info_json).unwrap(); + assert_eq!(tcb_info["tcbInfo"]["fmspc"], "00806F050000"); + assert_eq!(tcb_info["tcbInfo"]["id"], "TDX"); +} + +#[tokio::test] +async fn test_get_fmspcs_v3_should_fail() { + let server = Server::new_async().await; + + // FMSPCs is V4 only + let client = ApiClient::new_with_options(server.url(), ApiVersion::V3).unwrap(); + let result = client.get_fmspcs(None).await; + + assert!(result.is_err()); + match result.unwrap_err() { + IntelApiError::UnsupportedApiVersion(msg) => { + assert!(msg.contains("API v4 only")); + } + _ => panic!("Expected UnsupportedApiVersion error"), + } +} + +#[tokio::test] +async fn test_tcb_evaluation_data_numbers_v3_should_fail() { + let server = Server::new_async().await; + + // TCB evaluation data numbers is V4 only + let client = ApiClient::new_with_options(server.url(), ApiVersion::V3).unwrap(); + + let sgx_result = client.get_sgx_tcb_evaluation_data_numbers().await; + assert!(sgx_result.is_err()); + match sgx_result.unwrap_err() { + IntelApiError::UnsupportedApiVersion(msg) => { + assert!(msg.contains("requires API v4")); + } + _ => panic!("Expected UnsupportedApiVersion error"), + } + + let tdx_result = client.get_tdx_tcb_evaluation_data_numbers().await; + assert!(tdx_result.is_err()); + match tdx_result.unwrap_err() { + IntelApiError::UnsupportedApiVersion(msg) => { + assert!(msg.contains("requires API v4")); + } + _ => panic!("Expected UnsupportedApiVersion error"), + } +} + +#[tokio::test] +async fn test_get_fmspcs_no_filter_with_real_data() { + let mut server = Server::new_async().await; + let test_data = parse_test_data(FMSPCS_NO_FILTER_DATA); + + let _m = server + .mock("GET", "/sgx/certification/v4/fmspcs") + .with_status(200) + .with_header("Content-Type", "application/json") + .with_body(test_data["fmspcs_json"].as_str().unwrap()) + .create_async() + .await; + + let client = ApiClient::new_with_base_url(server.url()).unwrap(); + let result = client.get_fmspcs(None).await; + + assert!(result.is_ok()); + let fmspcs_json = result.unwrap(); + assert_eq!(fmspcs_json, test_data["fmspcs_json"].as_str().unwrap()); +} + +#[tokio::test] +async fn test_sgx_qe_identity_v3_with_real_data() { + let mut server = Server::new_async().await; + let test_data = parse_test_data(SGX_QE_IDENTITY_V3_DATA); + + let issuer_chain = test_data["issuer_chain"].as_str().unwrap(); + let encoded_issuer_chain = + percent_encode(issuer_chain.as_bytes(), NON_ALPHANUMERIC).to_string(); + + // V3 uses different header names + let _m = server + .mock("GET", "/sgx/certification/v3/qe/identity") + .with_status(200) + .with_header("Content-Type", "application/json") + .with_header("SGX-Enclave-Identity-Issuer-Chain", &encoded_issuer_chain) + .with_body(test_data["enclave_identity_json"].as_str().unwrap()) + .create_async() + .await; + + let client = ApiClient::new_with_options(server.url(), ApiVersion::V3).unwrap(); + let result = client.get_sgx_qe_identity(None, None).await; + + if let Err(e) = &result { + eprintln!("Error in V3 test: {:?}", e); + } + + assert!(result.is_ok()); + let response = result.unwrap(); + assert_eq!( + response.enclave_identity_json, + test_data["enclave_identity_json"].as_str().unwrap() + ); + assert_eq!( + response.issuer_chain, + test_data["issuer_chain"].as_str().unwrap() + ); +} + +#[tokio::test] +async fn test_sgx_tcb_info_v3_with_real_data() { + let mut server = Server::new_async().await; + let test_data = parse_test_data(SGX_TCB_INFO_V3_DATA); + + let issuer_chain = test_data["issuer_chain"].as_str().unwrap(); + let encoded_issuer_chain = + percent_encode(issuer_chain.as_bytes(), NON_ALPHANUMERIC).to_string(); + + // V3 uses different header names + let _m = server + .mock("GET", "/sgx/certification/v3/tcb") + .match_query(mockito::Matcher::UrlEncoded( + "fmspc".into(), + "00906ED50000".into(), + )) + .with_status(200) + .with_header("Content-Type", "application/json") + .with_header("SGX-TCB-Info-Issuer-Chain", &encoded_issuer_chain) + .with_body(test_data["tcb_info_json"].as_str().unwrap()) + .create_async() + .await; + + let client = ApiClient::new_with_options(server.url(), ApiVersion::V3).unwrap(); + let result = client.get_sgx_tcb_info("00906ED50000", None, None).await; + + assert!(result.is_ok()); + let response = result.unwrap(); + assert_eq!( + response.tcb_info_json, + test_data["tcb_info_json"].as_str().unwrap() + ); + + // Verify the JSON structure + let tcb_info: Value = serde_json::from_str(&response.tcb_info_json).unwrap(); + assert_eq!(tcb_info["tcbInfo"]["fmspc"], "00906ED50000"); +} + +#[tokio::test] +async fn test_tdx_tcb_info_alternate_fmspc_with_real_data() { + let mut server = Server::new_async().await; + let test_data = parse_test_data(TDX_TCB_INFO_ALT_DATA); + + let issuer_chain = test_data["issuer_chain"].as_str().unwrap(); + let encoded_issuer_chain = + percent_encode(issuer_chain.as_bytes(), NON_ALPHANUMERIC).to_string(); + + let _m = server + .mock("GET", "/tdx/certification/v4/tcb") + .match_query(mockito::Matcher::UrlEncoded( + "fmspc".into(), + "00806F050000".into(), + )) + .with_status(200) + .with_header("Content-Type", "application/json") + .with_header("TCB-Info-Issuer-Chain", &encoded_issuer_chain) + .with_body(test_data["tcb_info_json"].as_str().unwrap()) + .create_async() + .await; + + let client = ApiClient::new_with_base_url(server.url()).unwrap(); + let result = client.get_tdx_tcb_info("00806F050000", None, None).await; + + assert!(result.is_ok()); + let response = result.unwrap(); + + // Verify we got the same data as the first TDX TCB info test + let tcb_info: Value = serde_json::from_str(&response.tcb_info_json).unwrap(); + assert_eq!(tcb_info["tcbInfo"]["fmspc"], "00806F050000"); + assert_eq!(tcb_info["tcbInfo"]["id"], "TDX"); +} + +#[tokio::test] +async fn test_platform_filter_combinations() { + let mut server = Server::new_async().await; + + // Test with different platform filters + let filters = vec![ + (Some(PlatformFilter::All), "all"), + (Some(PlatformFilter::Client), "client"), + (Some(PlatformFilter::E3), "E3"), + (Some(PlatformFilter::E5), "E5"), + (None, ""), + ]; + + for (filter, query_value) in filters { + let mock_response = r#"[{"fmspc": "00906ED50000", "platform": "SGX"}]"#; + + let mut mock = server.mock("GET", "/sgx/certification/v4/fmspcs"); + + if !query_value.is_empty() { + mock = mock.match_query(mockito::Matcher::UrlEncoded( + "platform".into(), + query_value.into(), + )); + } + + let _m = mock + .with_status(200) + .with_header("Content-Type", "application/json") + .with_body(mock_response) + .create_async() + .await; + + let client = ApiClient::new_with_base_url(server.url()).unwrap(); + let result = client.get_fmspcs(filter).await; + + assert!(result.is_ok()); + let response = result.unwrap(); + assert!(response.contains("00906ED50000")); + } +} + +#[tokio::test] +async fn test_error_scenarios() { + let mut server = Server::new_async().await; + + // Test 404 with Error headers + let _m = server + .mock("GET", "/sgx/certification/v4/tcb") + .match_query(mockito::Matcher::UrlEncoded( + "fmspc".into(), + "invalid".into(), + )) + .with_status(404) + .with_header("Request-ID", "test123") + .with_header("Error-Code", "InvalidParameter") + .with_header("Error-Message", "Invalid FMSPC format") + .create_async() + .await; + + let client = ApiClient::new_with_base_url(server.url()).unwrap(); + let result = client.get_sgx_tcb_info("invalid", None, None).await; + + assert!(result.is_err()); + match result.unwrap_err() { + IntelApiError::ApiError { + status, + request_id, + error_code, + error_message, + } => { + assert_eq!(status.as_u16(), 404); + assert_eq!(request_id, "test123"); + assert_eq!(error_code.as_deref(), Some("InvalidParameter")); + assert_eq!(error_message.as_deref(), Some("Invalid FMSPC format")); + } + _ => panic!("Expected ApiError"), + } +} diff --git a/crates/intel-dcap-api/tests/test_data/fmspcs.json b/crates/intel-dcap-api/tests/test_data/fmspcs.json new file mode 100644 index 0000000..93e4cc8 --- /dev/null +++ b/crates/intel-dcap-api/tests/test_data/fmspcs.json @@ -0,0 +1,3 @@ +{ + "fmspcs_json": "[{\"fmspc\":\"00A06D080000\",\"platform\":\"E5\"},{\"fmspc\":\"10A06D070000\",\"platform\":\"E5\"},{\"fmspc\":\"70A06D070000\",\"platform\":\"E5\"},{\"fmspc\":\"00A06E050000\",\"platform\":\"E5\"},{\"fmspc\":\"00906EA50000\",\"platform\":\"client\"},{\"fmspc\":\"20606C040000\",\"platform\":\"E5\"},{\"fmspc\":\"50806F000000\",\"platform\":\"E5\"},{\"fmspc\":\"00A067110000\",\"platform\":\"E3\"},{\"fmspc\":\"00606C040000\",\"platform\":\"E5\"},{\"fmspc\":\"00706E470000\",\"platform\":\"client\"},{\"fmspc\":\"00806EA60000\",\"platform\":\"client\"},{\"fmspc\":\"00706A800000\",\"platform\":\"client\"},{\"fmspc\":\"00706A100000\",\"platform\":\"client\"},{\"fmspc\":\"F0806F000000\",\"platform\":\"E5\"},{\"fmspc\":\"00806EB70000\",\"platform\":\"client\"},{\"fmspc\":\"00906EC50000\",\"platform\":\"client\"},{\"fmspc\":\"90806F000000\",\"platform\":\"E5\"},{\"fmspc\":\"10A06F010000\",\"platform\":\"E5\"},{\"fmspc\":\"00906EC10000\",\"platform\":\"client\"},{\"fmspc\":\"B0C06F000000\",\"platform\":\"E5\"},{\"fmspc\":\"20A06F000000\",\"platform\":\"E5\"},{\"fmspc\":\"00906ED50000\",\"platform\":\"E3\"},{\"fmspc\":\"40A06F000000\",\"platform\":\"E5\"},{\"fmspc\":\"60A06F000000\",\"platform\":\"E5\"},{\"fmspc\":\"D0806F000000\",\"platform\":\"E5\"},{\"fmspc\":\"00A065510000\",\"platform\":\"client\"},{\"fmspc\":\"10A06D080000\",\"platform\":\"E5\"},{\"fmspc\":\"30606A000000\",\"platform\":\"E5\"},{\"fmspc\":\"20806EB70000\",\"platform\":\"client\"},{\"fmspc\":\"00906EA10000\",\"platform\":\"E3\"},{\"fmspc\":\"30806F040000\",\"platform\":\"E5\"},{\"fmspc\":\"C0806F000000\",\"platform\":\"E5\"},{\"fmspc\":\"30A06D050000\",\"platform\":\"E5\"},{\"fmspc\":\"60C06F000000\",\"platform\":\"E5\"},{\"fmspc\":\"20A06D080000\",\"platform\":\"E5\"},{\"fmspc\":\"10A06D000000\",\"platform\":\"E5\"},{\"fmspc\":\"00806F050000\",\"platform\":\"E5\"},{\"fmspc\":\"60A06D070000\",\"platform\":\"E5\"},{\"fmspc\":\"20906EC10000\",\"platform\":\"client\"},{\"fmspc\":\"90C06F000000\",\"platform\":\"E5\"},{\"fmspc\":\"80C06F000000\",\"platform\":\"E5\"},{\"fmspc\":\"00806F000000\",\"platform\":\"E5\"},{\"fmspc\":\"00906EB10000\",\"platform\":\"client\"},{\"fmspc\":\"00606A000000\",\"platform\":\"E5\"}]" +} \ No newline at end of file diff --git a/crates/intel-dcap-api/tests/test_data/fmspcs_all_platforms.json b/crates/intel-dcap-api/tests/test_data/fmspcs_all_platforms.json new file mode 100644 index 0000000..93e4cc8 --- /dev/null +++ b/crates/intel-dcap-api/tests/test_data/fmspcs_all_platforms.json @@ -0,0 +1,3 @@ +{ + "fmspcs_json": "[{\"fmspc\":\"00A06D080000\",\"platform\":\"E5\"},{\"fmspc\":\"10A06D070000\",\"platform\":\"E5\"},{\"fmspc\":\"70A06D070000\",\"platform\":\"E5\"},{\"fmspc\":\"00A06E050000\",\"platform\":\"E5\"},{\"fmspc\":\"00906EA50000\",\"platform\":\"client\"},{\"fmspc\":\"20606C040000\",\"platform\":\"E5\"},{\"fmspc\":\"50806F000000\",\"platform\":\"E5\"},{\"fmspc\":\"00A067110000\",\"platform\":\"E3\"},{\"fmspc\":\"00606C040000\",\"platform\":\"E5\"},{\"fmspc\":\"00706E470000\",\"platform\":\"client\"},{\"fmspc\":\"00806EA60000\",\"platform\":\"client\"},{\"fmspc\":\"00706A800000\",\"platform\":\"client\"},{\"fmspc\":\"00706A100000\",\"platform\":\"client\"},{\"fmspc\":\"F0806F000000\",\"platform\":\"E5\"},{\"fmspc\":\"00806EB70000\",\"platform\":\"client\"},{\"fmspc\":\"00906EC50000\",\"platform\":\"client\"},{\"fmspc\":\"90806F000000\",\"platform\":\"E5\"},{\"fmspc\":\"10A06F010000\",\"platform\":\"E5\"},{\"fmspc\":\"00906EC10000\",\"platform\":\"client\"},{\"fmspc\":\"B0C06F000000\",\"platform\":\"E5\"},{\"fmspc\":\"20A06F000000\",\"platform\":\"E5\"},{\"fmspc\":\"00906ED50000\",\"platform\":\"E3\"},{\"fmspc\":\"40A06F000000\",\"platform\":\"E5\"},{\"fmspc\":\"60A06F000000\",\"platform\":\"E5\"},{\"fmspc\":\"D0806F000000\",\"platform\":\"E5\"},{\"fmspc\":\"00A065510000\",\"platform\":\"client\"},{\"fmspc\":\"10A06D080000\",\"platform\":\"E5\"},{\"fmspc\":\"30606A000000\",\"platform\":\"E5\"},{\"fmspc\":\"20806EB70000\",\"platform\":\"client\"},{\"fmspc\":\"00906EA10000\",\"platform\":\"E3\"},{\"fmspc\":\"30806F040000\",\"platform\":\"E5\"},{\"fmspc\":\"C0806F000000\",\"platform\":\"E5\"},{\"fmspc\":\"30A06D050000\",\"platform\":\"E5\"},{\"fmspc\":\"60C06F000000\",\"platform\":\"E5\"},{\"fmspc\":\"20A06D080000\",\"platform\":\"E5\"},{\"fmspc\":\"10A06D000000\",\"platform\":\"E5\"},{\"fmspc\":\"00806F050000\",\"platform\":\"E5\"},{\"fmspc\":\"60A06D070000\",\"platform\":\"E5\"},{\"fmspc\":\"20906EC10000\",\"platform\":\"client\"},{\"fmspc\":\"90C06F000000\",\"platform\":\"E5\"},{\"fmspc\":\"80C06F000000\",\"platform\":\"E5\"},{\"fmspc\":\"00806F000000\",\"platform\":\"E5\"},{\"fmspc\":\"00906EB10000\",\"platform\":\"client\"},{\"fmspc\":\"00606A000000\",\"platform\":\"E5\"}]" +} \ No newline at end of file diff --git a/crates/intel-dcap-api/tests/test_data/fmspcs_no_filter.json b/crates/intel-dcap-api/tests/test_data/fmspcs_no_filter.json new file mode 100644 index 0000000..93e4cc8 --- /dev/null +++ b/crates/intel-dcap-api/tests/test_data/fmspcs_no_filter.json @@ -0,0 +1,3 @@ +{ + "fmspcs_json": "[{\"fmspc\":\"00A06D080000\",\"platform\":\"E5\"},{\"fmspc\":\"10A06D070000\",\"platform\":\"E5\"},{\"fmspc\":\"70A06D070000\",\"platform\":\"E5\"},{\"fmspc\":\"00A06E050000\",\"platform\":\"E5\"},{\"fmspc\":\"00906EA50000\",\"platform\":\"client\"},{\"fmspc\":\"20606C040000\",\"platform\":\"E5\"},{\"fmspc\":\"50806F000000\",\"platform\":\"E5\"},{\"fmspc\":\"00A067110000\",\"platform\":\"E3\"},{\"fmspc\":\"00606C040000\",\"platform\":\"E5\"},{\"fmspc\":\"00706E470000\",\"platform\":\"client\"},{\"fmspc\":\"00806EA60000\",\"platform\":\"client\"},{\"fmspc\":\"00706A800000\",\"platform\":\"client\"},{\"fmspc\":\"00706A100000\",\"platform\":\"client\"},{\"fmspc\":\"F0806F000000\",\"platform\":\"E5\"},{\"fmspc\":\"00806EB70000\",\"platform\":\"client\"},{\"fmspc\":\"00906EC50000\",\"platform\":\"client\"},{\"fmspc\":\"90806F000000\",\"platform\":\"E5\"},{\"fmspc\":\"10A06F010000\",\"platform\":\"E5\"},{\"fmspc\":\"00906EC10000\",\"platform\":\"client\"},{\"fmspc\":\"B0C06F000000\",\"platform\":\"E5\"},{\"fmspc\":\"20A06F000000\",\"platform\":\"E5\"},{\"fmspc\":\"00906ED50000\",\"platform\":\"E3\"},{\"fmspc\":\"40A06F000000\",\"platform\":\"E5\"},{\"fmspc\":\"60A06F000000\",\"platform\":\"E5\"},{\"fmspc\":\"D0806F000000\",\"platform\":\"E5\"},{\"fmspc\":\"00A065510000\",\"platform\":\"client\"},{\"fmspc\":\"10A06D080000\",\"platform\":\"E5\"},{\"fmspc\":\"30606A000000\",\"platform\":\"E5\"},{\"fmspc\":\"20806EB70000\",\"platform\":\"client\"},{\"fmspc\":\"00906EA10000\",\"platform\":\"E3\"},{\"fmspc\":\"30806F040000\",\"platform\":\"E5\"},{\"fmspc\":\"C0806F000000\",\"platform\":\"E5\"},{\"fmspc\":\"30A06D050000\",\"platform\":\"E5\"},{\"fmspc\":\"60C06F000000\",\"platform\":\"E5\"},{\"fmspc\":\"20A06D080000\",\"platform\":\"E5\"},{\"fmspc\":\"10A06D000000\",\"platform\":\"E5\"},{\"fmspc\":\"00806F050000\",\"platform\":\"E5\"},{\"fmspc\":\"60A06D070000\",\"platform\":\"E5\"},{\"fmspc\":\"20906EC10000\",\"platform\":\"client\"},{\"fmspc\":\"90C06F000000\",\"platform\":\"E5\"},{\"fmspc\":\"80C06F000000\",\"platform\":\"E5\"},{\"fmspc\":\"00806F000000\",\"platform\":\"E5\"},{\"fmspc\":\"00906EB10000\",\"platform\":\"client\"},{\"fmspc\":\"00606A000000\",\"platform\":\"E5\"}]" +} \ No newline at end of file diff --git a/crates/intel-dcap-api/tests/test_data/pck_crl_platform.json b/crates/intel-dcap-api/tests/test_data/pck_crl_platform.json new file mode 100644 index 0000000..bdad22c --- /dev/null +++ b/crates/intel-dcap-api/tests/test_data/pck_crl_platform.json @@ -0,0 +1,4 @@ +{ + "crl_data": "-----BEGIN X509 CRL-----\nMIIKYTCCCggCAQEwCgYIKoZIzj0EAwIwcDEiMCAGA1UEAwwZSW50ZWwgU0dYIFBD\nSyBQbGF0Zm9ybSBDQTEaMBgGA1UECgwRSW50ZWwgQ29ycG9yYXRpb24xFDASBgNV\nBAcMC1NhbnRhIENsYXJhMQswCQYDVQQIDAJDQTELMAkGA1UEBhMCVVMXDTI1MDUy\nNzE5MjUwNVoXDTI1MDYyNjE5MjUwNVowggk0MDMCFG/DTlAj5yiSNDXWGqS4PGGB\nZq01Fw0yNTA1MjcxOTI1MDVaMAwwCgYDVR0VBAMKAQEwNAIVAO+ubpcV/KE7h+Mz\n6CYe1tmQqSatFw0yNTA1MjcxOTI1MDVaMAwwCgYDVR0VBAMKAQEwNAIVAP1ghkhi\nnLpzB4tNSS9LPqdBrQjNFw0yNTA1MjcxOTI1MDVaMAwwCgYDVR0VBAMKAQEwNAIV\nAIr5JBhOHVr93XPD1joS9ei1c35WFw0yNTA1MjcxOTI1MDVaMAwwCgYDVR0VBAMK\nAQEwNAIVALEleXjPqczdB1mr+MXKcvrjp4qbFw0yNTA1MjcxOTI1MDVaMAwwCgYD\nVR0VBAMKAQEwMwIUdP6mFKlyvg4oQ/IFmDWBHthy+bMXDTI1MDUyNzE5MjUwNVow\nDDAKBgNVHRUEAwoBATA0AhUA+cTvVrOrSNV34Qi67fS/iAFCFLkXDTI1MDUyNzE5\nMjUwNVowDDAKBgNVHRUEAwoBATAzAhQHHeB3j55fxPKHjzDWsHyaMOazCxcNMjUw\nNTI3MTkyNTA1WjAMMAoGA1UdFQQDCgEBMDQCFQDN4kJPlyzqlP8jmTf02AwlAp3W\nCxcNMjUwNTI3MTkyNTA1WjAMMAoGA1UdFQQDCgEBMDMCFGwzGeUQm2RQfTzxEyzg\nA0nvUnMZFw0yNTA1MjcxOTI1MDVaMAwwCgYDVR0VBAMKAQEwNAIVAN8I11a2anSX\n9DtbtYraBNP096k3Fw0yNTA1MjcxOTI1MDVaMAwwCgYDVR0VBAMKAQEwMwIUKK9I\nW2z2fkCaOdXLWu5FmPeo+nsXDTI1MDUyNzE5MjUwNVowDDAKBgNVHRUEAwoBATA0\nAhUA+4strsCSytqKqbxP8vHCDQNGZowXDTI1MDUyNzE5MjUwNVowDDAKBgNVHRUE\nAwoBATA0AhUAzUhQrFK9zGmmpvBYyLxXu9C1+GQXDTI1MDUyNzE5MjUwNVowDDAK\nBgNVHRUEAwoBATA0AhUAmU3TZm9SdfuAX5XdAr1QyyZ52K0XDTI1MDUyNzE5MjUw\nNVowDDAKBgNVHRUEAwoBATAzAhQHAhNpACUidNkDXu31RXRi+tDvTBcNMjUwNTI3\nMTkyNTA1WjAMMAoGA1UdFQQDCgEBMDMCFGHyv3Pjm04EqifYAb1z0kMZtb+AFw0y\nNTA1MjcxOTI1MDVaMAwwCgYDVR0VBAMKAQEwMwIUOZK+hRuWkC7/OJWebC7/GwZR\npLUXDTI1MDUyNzE5MjUwNVowDDAKBgNVHRUEAwoBATAzAhQP2kOgC2jqebfC3q6s\nC0mL37KvkBcNMjUwNTI3MTkyNTA1WjAMMAoGA1UdFQQDCgEBMDMCFGOfE5pQQP3P\n8ZHopPsb8IbtYDlxFw0yNTA1MjcxOTI1MDVaMAwwCgYDVR0VBAMKAQEwNAIVAJWd\nUz+SSdweUTVEzcgwvxm38fMBFw0yNTA1MjcxOTI1MDVaMAwwCgYDVR0VBAMKAQEw\nMwIUeuN3SKn5EvTGO6erB8WTzh0dEYEXDTI1MDUyNzE5MjUwNVowDDAKBgNVHRUE\nAwoBATAzAhQTiEszJpk4wZWqFw/KddoXdTjfCxcNMjUwNTI3MTkyNTA1WjAMMAoG\nA1UdFQQDCgEBMDQCFQCF08k4G3en4E0RnJ5a1nSf8/+rhxcNMjUwNTI3MTkyNTA1\nWjAMMAoGA1UdFQQDCgEBMDQCFQCTiHykQR56kjvR/tKBmylJ8gG1tBcNMjUwNTI3\nMTkyNTA1WjAMMAoGA1UdFQQDCgEBMDMCFCSY3GKDkwmW/YvyOjesviajvtRXFw0y\nNTA1MjcxOTI1MDVaMAwwCgYDVR0VBAMKAQEwNAIVAIpm8adJSIZnaJzDkDrFTGYr\ncS5zFw0yNTA1MjcxOTI1MDVaMAwwCgYDVR0VBAMKAQEwNAIVAK/BNhC902y3mF0Q\nZIGogNOgH9oHFw0yNTA1MjcxOTI1MDVaMAwwCgYDVR0VBAMKAQEwNAIVAO/gSywz\n0DaqyWymc78emke2TVy7Fw0yNTA1MjcxOTI1MDVaMAwwCgYDVR0VBAMKAQEwNAIV\nAIPZrI2LtQnRxsgJrXEuhDBVntfzFw0yNTA1MjcxOTI1MDVaMAwwCgYDVR0VBAMK\nAQEwMwIUeTH9ULUHHBu/xbe23ti0W52LhSkXDTI1MDUyNzE5MjUwNVowDDAKBgNV\nHRUEAwoBATAzAhQfog4pcL3l1X97jd+DOUhOHx0IIxcNMjUwNTI3MTkyNTA1WjAM\nMAoGA1UdFQQDCgEBMDMCFB6HssOzLY0j5BHO80GXuVrwyK31Fw0yNTA1MjcxOTI1\nMDVaMAwwCgYDVR0VBAMKAQEwNAIVAJr9LukKRzVQoWfZlpEUN8dQLR8JFw0yNTA1\nMjcxOTI1MDVaMAwwCgYDVR0VBAMKAQEwMwIURIGw8RcooTtpbT6px3CgsV7FjdoX\nDTI1MDUyNzE5MjUwNVowDDAKBgNVHRUEAwoBATA0AhUAp4WfV5gu8OZ9N7yO8u9a\nyDX/GqkXDTI1MDUyNzE5MjUwNVowDDAKBgNVHRUEAwoBATA0AhUAnWd1O4HkcJCu\np2P77ExFSbzbmTMXDTI1MDUyNzE5MjUwNVowDDAKBgNVHRUEAwoBATAzAhQ0v7t6\nHZxWgUfhGLYU97du0+9o3xcNMjUwNTI3MTkyNTA1WjAMMAoGA1UdFQQDCgEBMDMC\nFCw8xv6SedsVFtXOOfKomM2loXXhFw0yNTA1MjcxOTI1MDVaMAwwCgYDVR0VBAMK\nAQEwMwIUcXlIaHUJI0vpeeS33ObzG+9ktowXDTI1MDUyNzE5MjUwNVowDDAKBgNV\nHRUEAwoBATA0AhUAnXbvLDnBNuhli25zlrHXRFonYx8XDTI1MDUyNzE5MjUwNVow\nDDAKBgNVHRUEAwoBATA0AhUAw+Al/KmV829ZtIRnk54+NOY2Gm8XDTI1MDUyNzE5\nMjUwNVowDDAKBgNVHRUEAwoBATA0AhUAjF9rMlfaBbF0KeLmG6ll1nMwYGoXDTI1\nMDUyNzE5MjUwNVowDDAKBgNVHRUEAwoBATA0AhUAoXxRci7B4MMnj+i98FIFnL7E\n5kgXDTI1MDUyNzE5MjUwNVowDDAKBgNVHRUEAwoBAaAvMC0wCgYDVR0UBAMCAQEw\nHwYDVR0jBBgwFoAUlW9dzb0b4elAScnU9DPOAVcL3lQwCgYIKoZIzj0EAwIDRwAw\nRAIgUpcU4PTB0Bc3qvMCWYHx5EEDXqxSLgCoYKp4C/GgxpkCIE/xDOudQg2ldK1m\nABQqvvzE8ibtGcDyaq1WI56Wv1bl\n-----END X509 CRL-----\n", + "issuer_chain": "-----BEGIN CERTIFICATE-----\nMIICljCCAj2gAwIBAgIVAJVvXc29G+HpQEnJ1PQzzgFXC95UMAoGCCqGSM49BAMC\nMGgxGjAYBgNVBAMMEUludGVsIFNHWCBSb290IENBMRowGAYDVQQKDBFJbnRlbCBD\nb3Jwb3JhdGlvbjEUMBIGA1UEBwwLU2FudGEgQ2xhcmExCzAJBgNVBAgMAkNBMQsw\nCQYDVQQGEwJVUzAeFw0xODA1MjExMDUwMTBaFw0zMzA1MjExMDUwMTBaMHAxIjAg\nBgNVBAMMGUludGVsIFNHWCBQQ0sgUGxhdGZvcm0gQ0ExGjAYBgNVBAoMEUludGVs\nIENvcnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0Ex\nCzAJBgNVBAYTAlVTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENSB/7t21lXSO\n2Cuzpxw74eJB72EyDGgW5rXCtx2tVTLq6hKk6z+UiRZCnqR7psOvgqFeSxlmTlJl\neTmi2WYz3qOBuzCBuDAfBgNVHSMEGDAWgBQiZQzWWp00ifODtJVSv1AbOScGrDBS\nBgNVHR8ESzBJMEegRaBDhkFodHRwczovL2NlcnRpZmljYXRlcy50cnVzdGVkc2Vy\ndmljZXMuaW50ZWwuY29tL0ludGVsU0dYUm9vdENBLmRlcjAdBgNVHQ4EFgQUlW9d\nzb0b4elAScnU9DPOAVcL3lQwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYB\nAf8CAQAwCgYIKoZIzj0EAwIDRwAwRAIgXsVki0w+i6VYGW3UF/22uaXe0YJDj1Ue\nnA+TjD1ai5cCICYb1SAmD5xkfTVpvo4UoyiSYxrDWLmUR4CI9NKyfPN+\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIICjzCCAjSgAwIBAgIUImUM1lqdNInzg7SVUr9QGzknBqwwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTE4MDUyMTEwNDUxMFoXDTQ5MTIzMTIzNTk1OVowaDEaMBgG\nA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENvcnBvcmF0\naW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJBgNVBAYT\nAlVTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEC6nEwMDIYZOj/iPWsCzaEKi7\n1OiOSLRFhWGjbnBVJfVnkY4u3IjkDYYL0MxO4mqsyYjlBalTVYxFP2sJBK5zlKOB\nuzCBuDAfBgNVHSMEGDAWgBQiZQzWWp00ifODtJVSv1AbOScGrDBSBgNVHR8ESzBJ\nMEegRaBDhkFodHRwczovL2NlcnRpZmljYXRlcy50cnVzdGVkc2VydmljZXMuaW50\nZWwuY29tL0ludGVsU0dYUm9vdENBLmRlcjAdBgNVHQ4EFgQUImUM1lqdNInzg7SV\nUr9QGzknBqwwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwCgYI\nKoZIzj0EAwIDSQAwRgIhAOW/5QkR+S9CiSDcNoowLuPRLsWGf/Yi7GSX94BgwTwg\nAiEA4J0lrHoMs+Xo5o/sX6O9QWxHRAvZUGOdRQ7cvqRXaqI=\n-----END CERTIFICATE-----\n" +} \ No newline at end of file diff --git a/crates/intel-dcap-api/tests/test_data/pck_crl_processor.json b/crates/intel-dcap-api/tests/test_data/pck_crl_processor.json new file mode 100644 index 0000000..ec77f5b --- /dev/null +++ b/crates/intel-dcap-api/tests/test_data/pck_crl_processor.json @@ -0,0 +1,4 @@ +{ + "crl_data": "-----BEGIN X509 CRL-----\nMIIBKjCB0QIBATAKBggqhkjOPQQDAjBxMSMwIQYDVQQDDBpJbnRlbCBTR1ggUENL\nIFByb2Nlc3NvciBDQTEaMBgGA1UECgwRSW50ZWwgQ29ycG9yYXRpb24xFDASBgNV\nBAcMC1NhbnRhIENsYXJhMQswCQYDVQQIDAJDQTELMAkGA1UEBhMCVVMXDTI1MDUy\nNzE4NDYyNVoXDTI1MDYyNjE4NDYyNVqgLzAtMAoGA1UdFAQDAgEBMB8GA1UdIwQY\nMBaAFNDoqtp11/kuSReYPHsUZdDV8llNMAoGCCqGSM49BAMCA0gAMEUCIQDtYSVu\nju3asUsAGZ2Hbe9uvZmk5zvLtwDk38KrWfb5zAIgSfk6Dmqhc4+moiRuRz0wQqLj\nckwO2BEUviI+nZfN75I=\n-----END X509 CRL-----\n", + "issuer_chain": "-----BEGIN CERTIFICATE-----\nMIICmDCCAj6gAwIBAgIVANDoqtp11/kuSReYPHsUZdDV8llNMAoGCCqGSM49BAMC\nMGgxGjAYBgNVBAMMEUludGVsIFNHWCBSb290IENBMRowGAYDVQQKDBFJbnRlbCBD\nb3Jwb3JhdGlvbjEUMBIGA1UEBwwLU2FudGEgQ2xhcmExCzAJBgNVBAgMAkNBMQsw\nCQYDVQQGEwJVUzAeFw0xODA1MjExMDUwMTBaFw0zMzA1MjExMDUwMTBaMHExIzAh\nBgNVBAMMGkludGVsIFNHWCBQQ0sgUHJvY2Vzc29yIENBMRowGAYDVQQKDBFJbnRl\nbCBDb3Jwb3JhdGlvbjEUMBIGA1UEBwwLU2FudGEgQ2xhcmExCzAJBgNVBAgMAkNB\nMQswCQYDVQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABL9q+NMp2IOg\ntdl1bk/uWZ5+TGQm8aCi8z78fs+fKCQ3d+uDzXnVTAT2ZhDCifyIuJwvN3wNBp9i\nHBSSMJMJrBOjgbswgbgwHwYDVR0jBBgwFoAUImUM1lqdNInzg7SVUr9QGzknBqww\nUgYDVR0fBEswSTBHoEWgQ4ZBaHR0cHM6Ly9jZXJ0aWZpY2F0ZXMudHJ1c3RlZHNl\ncnZpY2VzLmludGVsLmNvbS9JbnRlbFNHWFJvb3RDQS5kZXIwHQYDVR0OBBYEFNDo\nqtp11/kuSReYPHsUZdDV8llNMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAG\nAQH/AgEAMAoGCCqGSM49BAMCA0gAMEUCIQCJgTbtVqOyZ1m3jqiAXM6QYa6r5sWS\n4y/G7y8uIJGxdwIgRqPvBSKzzQagBLQq5s5A70pdoiaRJ8z/0uDz4NgV91k=\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIICjzCCAjSgAwIBAgIUImUM1lqdNInzg7SVUr9QGzknBqwwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTE4MDUyMTEwNDUxMFoXDTQ5MTIzMTIzNTk1OVowaDEaMBgG\nA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENvcnBvcmF0\naW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJBgNVBAYT\nAlVTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEC6nEwMDIYZOj/iPWsCzaEKi7\n1OiOSLRFhWGjbnBVJfVnkY4u3IjkDYYL0MxO4mqsyYjlBalTVYxFP2sJBK5zlKOB\nuzCBuDAfBgNVHSMEGDAWgBQiZQzWWp00ifODtJVSv1AbOScGrDBSBgNVHR8ESzBJ\nMEegRaBDhkFodHRwczovL2NlcnRpZmljYXRlcy50cnVzdGVkc2VydmljZXMuaW50\nZWwuY29tL0ludGVsU0dYUm9vdENBLmRlcjAdBgNVHQ4EFgQUImUM1lqdNInzg7SV\nUr9QGzknBqwwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwCgYI\nKoZIzj0EAwIDSQAwRgIhAOW/5QkR+S9CiSDcNoowLuPRLsWGf/Yi7GSX94BgwTwg\nAiEA4J0lrHoMs+Xo5o/sX6O9QWxHRAvZUGOdRQ7cvqRXaqI=\n-----END CERTIFICATE-----\n" +} \ No newline at end of file diff --git a/crates/intel-dcap-api/tests/test_data/pck_crl_processor_der.json b/crates/intel-dcap-api/tests/test_data/pck_crl_processor_der.json new file mode 100644 index 0000000..3421b50 --- /dev/null +++ b/crates/intel-dcap-api/tests/test_data/pck_crl_processor_der.json @@ -0,0 +1,4 @@ +{ + "crl_data_base64": "MIIBKjCB0QIBATAKBggqhkjOPQQDAjBxMSMwIQYDVQQDDBpJbnRlbCBTR1ggUENLIFByb2Nlc3NvciBDQTEaMBgGA1UECgwRSW50ZWwgQ29ycG9yYXRpb24xFDASBgNVBAcMC1NhbnRhIENsYXJhMQswCQYDVQQIDAJDQTELMAkGA1UEBhMCVVMXDTI1MDUyNzE5MjMwOVoXDTI1MDYyNjE5MjMwOVqgLzAtMAoGA1UdFAQDAgEBMB8GA1UdIwQYMBaAFNDoqtp11/kuSReYPHsUZdDV8llNMAoGCCqGSM49BAMCA0gAMEUCIQC2Q0kz4IioOr5HsdYUY8b0m3XSS6FwuKVUAIvroURNHgIgIo5mAP1gCBeW719AqdBaxnoNuUypHQ/X+1zfDiY69ec=", + "issuer_chain": "-----BEGIN CERTIFICATE-----\nMIICmDCCAj6gAwIBAgIVANDoqtp11/kuSReYPHsUZdDV8llNMAoGCCqGSM49BAMC\nMGgxGjAYBgNVBAMMEUludGVsIFNHWCBSb290IENBMRowGAYDVQQKDBFJbnRlbCBD\nb3Jwb3JhdGlvbjEUMBIGA1UEBwwLU2FudGEgQ2xhcmExCzAJBgNVBAgMAkNBMQsw\nCQYDVQQGEwJVUzAeFw0xODA1MjExMDUwMTBaFw0zMzA1MjExMDUwMTBaMHExIzAh\nBgNVBAMMGkludGVsIFNHWCBQQ0sgUHJvY2Vzc29yIENBMRowGAYDVQQKDBFJbnRl\nbCBDb3Jwb3JhdGlvbjEUMBIGA1UEBwwLU2FudGEgQ2xhcmExCzAJBgNVBAgMAkNB\nMQswCQYDVQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABL9q+NMp2IOg\ntdl1bk/uWZ5+TGQm8aCi8z78fs+fKCQ3d+uDzXnVTAT2ZhDCifyIuJwvN3wNBp9i\nHBSSMJMJrBOjgbswgbgwHwYDVR0jBBgwFoAUImUM1lqdNInzg7SVUr9QGzknBqww\nUgYDVR0fBEswSTBHoEWgQ4ZBaHR0cHM6Ly9jZXJ0aWZpY2F0ZXMudHJ1c3RlZHNl\ncnZpY2VzLmludGVsLmNvbS9JbnRlbFNHWFJvb3RDQS5kZXIwHQYDVR0OBBYEFNDo\nqtp11/kuSReYPHsUZdDV8llNMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAG\nAQH/AgEAMAoGCCqGSM49BAMCA0gAMEUCIQCJgTbtVqOyZ1m3jqiAXM6QYa6r5sWS\n4y/G7y8uIJGxdwIgRqPvBSKzzQagBLQq5s5A70pdoiaRJ8z/0uDz4NgV91k=\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIICjzCCAjSgAwIBAgIUImUM1lqdNInzg7SVUr9QGzknBqwwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTE4MDUyMTEwNDUxMFoXDTQ5MTIzMTIzNTk1OVowaDEaMBgG\nA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENvcnBvcmF0\naW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJBgNVBAYT\nAlVTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEC6nEwMDIYZOj/iPWsCzaEKi7\n1OiOSLRFhWGjbnBVJfVnkY4u3IjkDYYL0MxO4mqsyYjlBalTVYxFP2sJBK5zlKOB\nuzCBuDAfBgNVHSMEGDAWgBQiZQzWWp00ifODtJVSv1AbOScGrDBSBgNVHR8ESzBJ\nMEegRaBDhkFodHRwczovL2NlcnRpZmljYXRlcy50cnVzdGVkc2VydmljZXMuaW50\nZWwuY29tL0ludGVsU0dYUm9vdENBLmRlcjAdBgNVHQ4EFgQUImUM1lqdNInzg7SV\nUr9QGzknBqwwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwCgYI\nKoZIzj0EAwIDSQAwRgIhAOW/5QkR+S9CiSDcNoowLuPRLsWGf/Yi7GSX94BgwTwg\nAiEA4J0lrHoMs+Xo5o/sX6O9QWxHRAvZUGOdRQ7cvqRXaqI=\n-----END CERTIFICATE-----\n" +} \ No newline at end of file diff --git a/crates/intel-dcap-api/tests/test_data/sgx_qae_identity.json b/crates/intel-dcap-api/tests/test_data/sgx_qae_identity.json new file mode 100644 index 0000000..4c4c329 --- /dev/null +++ b/crates/intel-dcap-api/tests/test_data/sgx_qae_identity.json @@ -0,0 +1,4 @@ +{ + "enclave_identity_json": "{\"enclaveIdentity\":{\"id\":\"QAE\",\"version\":2,\"issueDate\":\"2025-05-27T19:31:54Z\",\"nextUpdate\":\"2025-06-26T19:31:54Z\",\"tcbEvaluationDataNumber\":17,\"miscselect\":\"00000000\",\"miscselectMask\":\"FFFFFFFF\",\"attributes\":\"01000000000000000000000000000000\",\"attributesMask\":\"FBFFFFFFFFFFFFFF0000000000000000\",\"mrsigner\":\"8C4F5775D796503E96137F77C68A829A0056AC8DED70140B081B094490C57BFF\",\"isvprodid\":3,\"tcbLevels\":[{\"tcb\":{\"isvsvn\":3},\"tcbDate\":\"2024-03-13T00:00:00Z\",\"tcbStatus\":\"UpToDate\"}]},\"signature\":\"a5dfb799f78ea3d32f7760f2b529fc80fe7efa3236c9888e8ece69379e206880f0b67b9407a9b139feb5007b785601f09050d4963116c1bd2cd5def4e3a11da8\"}", + "issuer_chain": "-----BEGIN CERTIFICATE-----\nMIICjTCCAjKgAwIBAgIUfjiC1ftVKUpASY5FhAPpFJG99FUwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTI1MDUwNjA5MjUwMFoXDTMyMDUwNjA5MjUwMFowbDEeMBwG\nA1UEAwwVSW50ZWwgU0dYIFRDQiBTaWduaW5nMRowGAYDVQQKDBFJbnRlbCBDb3Jw\nb3JhdGlvbjEUMBIGA1UEBwwLU2FudGEgQ2xhcmExCzAJBgNVBAgMAkNBMQswCQYD\nVQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABENFG8xzydWRfK92bmGv\nP+mAh91PEyV7Jh6FGJd5ndE9aBH7R3E4A7ubrlh/zN3C4xvpoouGlirMba+W2lju\nypajgbUwgbIwHwYDVR0jBBgwFoAUImUM1lqdNInzg7SVUr9QGzknBqwwUgYDVR0f\nBEswSTBHoEWgQ4ZBaHR0cHM6Ly9jZXJ0aWZpY2F0ZXMudHJ1c3RlZHNlcnZpY2Vz\nLmludGVsLmNvbS9JbnRlbFNHWFJvb3RDQS5kZXIwHQYDVR0OBBYEFH44gtX7VSlK\nQEmORYQD6RSRvfRVMA4GA1UdDwEB/wQEAwIGwDAMBgNVHRMBAf8EAjAAMAoGCCqG\nSM49BAMCA0kAMEYCIQDdmmRuAo3qCO8TC1IoJMITAoOEw4dlgEBHzSz1TuMSTAIh\nAKVTqOkt59+co0O3m3hC+v5Fb00FjYWcgeu3EijOULo5\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIICjzCCAjSgAwIBAgIUImUM1lqdNInzg7SVUr9QGzknBqwwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTE4MDUyMTEwNDUxMFoXDTQ5MTIzMTIzNTk1OVowaDEaMBgG\nA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENvcnBvcmF0\naW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJBgNVBAYT\nAlVTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEC6nEwMDIYZOj/iPWsCzaEKi7\n1OiOSLRFhWGjbnBVJfVnkY4u3IjkDYYL0MxO4mqsyYjlBalTVYxFP2sJBK5zlKOB\nuzCBuDAfBgNVHSMEGDAWgBQiZQzWWp00ifODtJVSv1AbOScGrDBSBgNVHR8ESzBJ\nMEegRaBDhkFodHRwczovL2NlcnRpZmljYXRlcy50cnVzdGVkc2VydmljZXMuaW50\nZWwuY29tL0ludGVsU0dYUm9vdENBLmRlcjAdBgNVHQ4EFgQUImUM1lqdNInzg7SV\nUr9QGzknBqwwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwCgYI\nKoZIzj0EAwIDSQAwRgIhAOW/5QkR+S9CiSDcNoowLuPRLsWGf/Yi7GSX94BgwTwg\nAiEA4J0lrHoMs+Xo5o/sX6O9QWxHRAvZUGOdRQ7cvqRXaqI=\n-----END CERTIFICATE-----\n" +} \ No newline at end of file diff --git a/crates/intel-dcap-api/tests/test_data/sgx_qe_identity.json b/crates/intel-dcap-api/tests/test_data/sgx_qe_identity.json new file mode 100644 index 0000000..3c4c157 --- /dev/null +++ b/crates/intel-dcap-api/tests/test_data/sgx_qe_identity.json @@ -0,0 +1,4 @@ +{ + "enclave_identity_json": "{\"enclaveIdentity\":{\"id\":\"QE\",\"version\":2,\"issueDate\":\"2025-05-27T19:05:27Z\",\"nextUpdate\":\"2025-06-26T19:05:27Z\",\"tcbEvaluationDataNumber\":17,\"miscselect\":\"00000000\",\"miscselectMask\":\"FFFFFFFF\",\"attributes\":\"11000000000000000000000000000000\",\"attributesMask\":\"FBFFFFFFFFFFFFFF0000000000000000\",\"mrsigner\":\"8C4F5775D796503E96137F77C68A829A0056AC8DED70140B081B094490C57BFF\",\"isvprodid\":1,\"tcbLevels\":[{\"tcb\":{\"isvsvn\":8},\"tcbDate\":\"2024-03-13T00:00:00Z\",\"tcbStatus\":\"UpToDate\"},{\"tcb\":{\"isvsvn\":6},\"tcbDate\":\"2021-11-10T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00615\"]},{\"tcb\":{\"isvsvn\":5},\"tcbDate\":\"2020-11-11T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00477\",\"INTEL-SA-00615\"]},{\"tcb\":{\"isvsvn\":4},\"tcbDate\":\"2019-11-13T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00334\",\"INTEL-SA-00477\",\"INTEL-SA-00615\"]},{\"tcb\":{\"isvsvn\":2},\"tcbDate\":\"2019-05-15T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00219\",\"INTEL-SA-00293\",\"INTEL-SA-00334\",\"INTEL-SA-00477\",\"INTEL-SA-00615\"]},{\"tcb\":{\"isvsvn\":1},\"tcbDate\":\"2018-08-15T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00202\",\"INTEL-SA-00219\",\"INTEL-SA-00293\",\"INTEL-SA-00334\",\"INTEL-SA-00477\",\"INTEL-SA-00615\"]}]},\"signature\":\"5ecc03899589b58e8216c69c3439d1a9310d8af9ebfb37e61518a2a3cb801e0019a5fc955e38e6becc1c75a8a05bb337c93c1a61009a34cc8291fdd82f67ae19\"}", + "issuer_chain": "-----BEGIN CERTIFICATE-----\nMIICjTCCAjKgAwIBAgIUfjiC1ftVKUpASY5FhAPpFJG99FUwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTI1MDUwNjA5MjUwMFoXDTMyMDUwNjA5MjUwMFowbDEeMBwG\nA1UEAwwVSW50ZWwgU0dYIFRDQiBTaWduaW5nMRowGAYDVQQKDBFJbnRlbCBDb3Jw\nb3JhdGlvbjEUMBIGA1UEBwwLU2FudGEgQ2xhcmExCzAJBgNVBAgMAkNBMQswCQYD\nVQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABENFG8xzydWRfK92bmGv\nP+mAh91PEyV7Jh6FGJd5ndE9aBH7R3E4A7ubrlh/zN3C4xvpoouGlirMba+W2lju\nypajgbUwgbIwHwYDVR0jBBgwFoAUImUM1lqdNInzg7SVUr9QGzknBqwwUgYDVR0f\nBEswSTBHoEWgQ4ZBaHR0cHM6Ly9jZXJ0aWZpY2F0ZXMudHJ1c3RlZHNlcnZpY2Vz\nLmludGVsLmNvbS9JbnRlbFNHWFJvb3RDQS5kZXIwHQYDVR0OBBYEFH44gtX7VSlK\nQEmORYQD6RSRvfRVMA4GA1UdDwEB/wQEAwIGwDAMBgNVHRMBAf8EAjAAMAoGCCqG\nSM49BAMCA0kAMEYCIQDdmmRuAo3qCO8TC1IoJMITAoOEw4dlgEBHzSz1TuMSTAIh\nAKVTqOkt59+co0O3m3hC+v5Fb00FjYWcgeu3EijOULo5\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIICjzCCAjSgAwIBAgIUImUM1lqdNInzg7SVUr9QGzknBqwwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTE4MDUyMTEwNDUxMFoXDTQ5MTIzMTIzNTk1OVowaDEaMBgG\nA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENvcnBvcmF0\naW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJBgNVBAYT\nAlVTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEC6nEwMDIYZOj/iPWsCzaEKi7\n1OiOSLRFhWGjbnBVJfVnkY4u3IjkDYYL0MxO4mqsyYjlBalTVYxFP2sJBK5zlKOB\nuzCBuDAfBgNVHSMEGDAWgBQiZQzWWp00ifODtJVSv1AbOScGrDBSBgNVHR8ESzBJ\nMEegRaBDhkFodHRwczovL2NlcnRpZmljYXRlcy50cnVzdGVkc2VydmljZXMuaW50\nZWwuY29tL0ludGVsU0dYUm9vdENBLmRlcjAdBgNVHQ4EFgQUImUM1lqdNInzg7SV\nUr9QGzknBqwwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwCgYI\nKoZIzj0EAwIDSQAwRgIhAOW/5QkR+S9CiSDcNoowLuPRLsWGf/Yi7GSX94BgwTwg\nAiEA4J0lrHoMs+Xo5o/sX6O9QWxHRAvZUGOdRQ7cvqRXaqI=\n-----END CERTIFICATE-----\n" +} \ No newline at end of file diff --git a/crates/intel-dcap-api/tests/test_data/sgx_qe_identity_v3.json b/crates/intel-dcap-api/tests/test_data/sgx_qe_identity_v3.json new file mode 100644 index 0000000..f545dbb --- /dev/null +++ b/crates/intel-dcap-api/tests/test_data/sgx_qe_identity_v3.json @@ -0,0 +1,4 @@ +{ + "enclave_identity_json": "{\"enclaveIdentity\":{\"id\":\"QE\",\"version\":2,\"issueDate\":\"2025-05-27T18:38:43Z\",\"nextUpdate\":\"2025-06-26T18:38:43Z\",\"tcbEvaluationDataNumber\":17,\"miscselect\":\"00000000\",\"miscselectMask\":\"FFFFFFFF\",\"attributes\":\"11000000000000000000000000000000\",\"attributesMask\":\"FBFFFFFFFFFFFFFF0000000000000000\",\"mrsigner\":\"8C4F5775D796503E96137F77C68A829A0056AC8DED70140B081B094490C57BFF\",\"isvprodid\":1,\"tcbLevels\":[{\"tcb\":{\"isvsvn\":8},\"tcbDate\":\"2024-03-13T00:00:00Z\",\"tcbStatus\":\"UpToDate\"},{\"tcb\":{\"isvsvn\":6},\"tcbDate\":\"2021-11-10T00:00:00Z\",\"tcbStatus\":\"OutOfDate\"},{\"tcb\":{\"isvsvn\":5},\"tcbDate\":\"2020-11-11T00:00:00Z\",\"tcbStatus\":\"OutOfDate\"},{\"tcb\":{\"isvsvn\":4},\"tcbDate\":\"2019-11-13T00:00:00Z\",\"tcbStatus\":\"OutOfDate\"},{\"tcb\":{\"isvsvn\":2},\"tcbDate\":\"2019-05-15T00:00:00Z\",\"tcbStatus\":\"OutOfDate\"},{\"tcb\":{\"isvsvn\":1},\"tcbDate\":\"2018-08-15T00:00:00Z\",\"tcbStatus\":\"OutOfDate\"}]},\"signature\":\"b4cc7bd5ee712a62cf6fbad0a052bd44194a25a5313b4bfff241a3c08ff00bcf0d15f1feb3a369bd9b362a6e5104c82f06d827ef676e70fdccf947566b77f6e8\"}", + "issuer_chain": "-----BEGIN CERTIFICATE-----\nMIICjTCCAjKgAwIBAgIUfjiC1ftVKUpASY5FhAPpFJG99FUwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTI1MDUwNjA5MjUwMFoXDTMyMDUwNjA5MjUwMFowbDEeMBwG\nA1UEAwwVSW50ZWwgU0dYIFRDQiBTaWduaW5nMRowGAYDVQQKDBFJbnRlbCBDb3Jw\nb3JhdGlvbjEUMBIGA1UEBwwLU2FudGEgQ2xhcmExCzAJBgNVBAgMAkNBMQswCQYD\nVQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABENFG8xzydWRfK92bmGv\nP+mAh91PEyV7Jh6FGJd5ndE9aBH7R3E4A7ubrlh/zN3C4xvpoouGlirMba+W2lju\nypajgbUwgbIwHwYDVR0jBBgwFoAUImUM1lqdNInzg7SVUr9QGzknBqwwUgYDVR0f\nBEswSTBHoEWgQ4ZBaHR0cHM6Ly9jZXJ0aWZpY2F0ZXMudHJ1c3RlZHNlcnZpY2Vz\nLmludGVsLmNvbS9JbnRlbFNHWFJvb3RDQS5kZXIwHQYDVR0OBBYEFH44gtX7VSlK\nQEmORYQD6RSRvfRVMA4GA1UdDwEB/wQEAwIGwDAMBgNVHRMBAf8EAjAAMAoGCCqG\nSM49BAMCA0kAMEYCIQDdmmRuAo3qCO8TC1IoJMITAoOEw4dlgEBHzSz1TuMSTAIh\nAKVTqOkt59+co0O3m3hC+v5Fb00FjYWcgeu3EijOULo5\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIICjzCCAjSgAwIBAgIUImUM1lqdNInzg7SVUr9QGzknBqwwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTE4MDUyMTEwNDUxMFoXDTQ5MTIzMTIzNTk1OVowaDEaMBgG\nA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENvcnBvcmF0\naW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJBgNVBAYT\nAlVTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEC6nEwMDIYZOj/iPWsCzaEKi7\n1OiOSLRFhWGjbnBVJfVnkY4u3IjkDYYL0MxO4mqsyYjlBalTVYxFP2sJBK5zlKOB\nuzCBuDAfBgNVHSMEGDAWgBQiZQzWWp00ifODtJVSv1AbOScGrDBSBgNVHR8ESzBJ\nMEegRaBDhkFodHRwczovL2NlcnRpZmljYXRlcy50cnVzdGVkc2VydmljZXMuaW50\nZWwuY29tL0ludGVsU0dYUm9vdENBLmRlcjAdBgNVHQ4EFgQUImUM1lqdNInzg7SV\nUr9QGzknBqwwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwCgYI\nKoZIzj0EAwIDSQAwRgIhAOW/5QkR+S9CiSDcNoowLuPRLsWGf/Yi7GSX94BgwTwg\nAiEA4J0lrHoMs+Xo5o/sX6O9QWxHRAvZUGOdRQ7cvqRXaqI=\n-----END CERTIFICATE-----\n" +} \ No newline at end of file diff --git a/crates/intel-dcap-api/tests/test_data/sgx_qve_identity.json b/crates/intel-dcap-api/tests/test_data/sgx_qve_identity.json new file mode 100644 index 0000000..2a29b18 --- /dev/null +++ b/crates/intel-dcap-api/tests/test_data/sgx_qve_identity.json @@ -0,0 +1,4 @@ +{ + "enclave_identity_json": "{\"enclaveIdentity\":{\"id\":\"QVE\",\"version\":2,\"issueDate\":\"2025-05-27T19:31:54Z\",\"nextUpdate\":\"2025-06-26T19:31:54Z\",\"tcbEvaluationDataNumber\":17,\"miscselect\":\"00000000\",\"miscselectMask\":\"FFFFFFFF\",\"attributes\":\"01000000000000000000000000000000\",\"attributesMask\":\"FBFFFFFFFFFFFFFF0000000000000000\",\"mrsigner\":\"8C4F5775D796503E96137F77C68A829A0056AC8DED70140B081B094490C57BFF\",\"isvprodid\":2,\"tcbLevels\":[{\"tcb\":{\"isvsvn\":3},\"tcbDate\":\"2024-03-13T00:00:00Z\",\"tcbStatus\":\"UpToDate\"}]},\"signature\":\"3bb26b16155b207f884ef10fad705129bf566ccc9e6bd4e9907c99bc0ccd6deb6b6451b103b495926c582ece9d22c491f05a627806e09ca07e1063de898460e7\"}", + "issuer_chain": "-----BEGIN CERTIFICATE-----\nMIICjTCCAjKgAwIBAgIUfjiC1ftVKUpASY5FhAPpFJG99FUwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTI1MDUwNjA5MjUwMFoXDTMyMDUwNjA5MjUwMFowbDEeMBwG\nA1UEAwwVSW50ZWwgU0dYIFRDQiBTaWduaW5nMRowGAYDVQQKDBFJbnRlbCBDb3Jw\nb3JhdGlvbjEUMBIGA1UEBwwLU2FudGEgQ2xhcmExCzAJBgNVBAgMAkNBMQswCQYD\nVQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABENFG8xzydWRfK92bmGv\nP+mAh91PEyV7Jh6FGJd5ndE9aBH7R3E4A7ubrlh/zN3C4xvpoouGlirMba+W2lju\nypajgbUwgbIwHwYDVR0jBBgwFoAUImUM1lqdNInzg7SVUr9QGzknBqwwUgYDVR0f\nBEswSTBHoEWgQ4ZBaHR0cHM6Ly9jZXJ0aWZpY2F0ZXMudHJ1c3RlZHNlcnZpY2Vz\nLmludGVsLmNvbS9JbnRlbFNHWFJvb3RDQS5kZXIwHQYDVR0OBBYEFH44gtX7VSlK\nQEmORYQD6RSRvfRVMA4GA1UdDwEB/wQEAwIGwDAMBgNVHRMBAf8EAjAAMAoGCCqG\nSM49BAMCA0kAMEYCIQDdmmRuAo3qCO8TC1IoJMITAoOEw4dlgEBHzSz1TuMSTAIh\nAKVTqOkt59+co0O3m3hC+v5Fb00FjYWcgeu3EijOULo5\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIICjzCCAjSgAwIBAgIUImUM1lqdNInzg7SVUr9QGzknBqwwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTE4MDUyMTEwNDUxMFoXDTQ5MTIzMTIzNTk1OVowaDEaMBgG\nA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENvcnBvcmF0\naW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJBgNVBAYT\nAlVTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEC6nEwMDIYZOj/iPWsCzaEKi7\n1OiOSLRFhWGjbnBVJfVnkY4u3IjkDYYL0MxO4mqsyYjlBalTVYxFP2sJBK5zlKOB\nuzCBuDAfBgNVHSMEGDAWgBQiZQzWWp00ifODtJVSv1AbOScGrDBSBgNVHR8ESzBJ\nMEegRaBDhkFodHRwczovL2NlcnRpZmljYXRlcy50cnVzdGVkc2VydmljZXMuaW50\nZWwuY29tL0ludGVsU0dYUm9vdENBLmRlcjAdBgNVHQ4EFgQUImUM1lqdNInzg7SV\nUr9QGzknBqwwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwCgYI\nKoZIzj0EAwIDSQAwRgIhAOW/5QkR+S9CiSDcNoowLuPRLsWGf/Yi7GSX94BgwTwg\nAiEA4J0lrHoMs+Xo5o/sX6O9QWxHRAvZUGOdRQ7cvqRXaqI=\n-----END CERTIFICATE-----\n" +} \ No newline at end of file diff --git a/crates/intel-dcap-api/tests/test_data/sgx_tcb_eval_nums.json b/crates/intel-dcap-api/tests/test_data/sgx_tcb_eval_nums.json new file mode 100644 index 0000000..9076051 --- /dev/null +++ b/crates/intel-dcap-api/tests/test_data/sgx_tcb_eval_nums.json @@ -0,0 +1,4 @@ +{ + "issuer_chain": "-----BEGIN CERTIFICATE-----\nMIICjTCCAjKgAwIBAgIUfjiC1ftVKUpASY5FhAPpFJG99FUwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTI1MDUwNjA5MjUwMFoXDTMyMDUwNjA5MjUwMFowbDEeMBwG\nA1UEAwwVSW50ZWwgU0dYIFRDQiBTaWduaW5nMRowGAYDVQQKDBFJbnRlbCBDb3Jw\nb3JhdGlvbjEUMBIGA1UEBwwLU2FudGEgQ2xhcmExCzAJBgNVBAgMAkNBMQswCQYD\nVQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABENFG8xzydWRfK92bmGv\nP+mAh91PEyV7Jh6FGJd5ndE9aBH7R3E4A7ubrlh/zN3C4xvpoouGlirMba+W2lju\nypajgbUwgbIwHwYDVR0jBBgwFoAUImUM1lqdNInzg7SVUr9QGzknBqwwUgYDVR0f\nBEswSTBHoEWgQ4ZBaHR0cHM6Ly9jZXJ0aWZpY2F0ZXMudHJ1c3RlZHNlcnZpY2Vz\nLmludGVsLmNvbS9JbnRlbFNHWFJvb3RDQS5kZXIwHQYDVR0OBBYEFH44gtX7VSlK\nQEmORYQD6RSRvfRVMA4GA1UdDwEB/wQEAwIGwDAMBgNVHRMBAf8EAjAAMAoGCCqG\nSM49BAMCA0kAMEYCIQDdmmRuAo3qCO8TC1IoJMITAoOEw4dlgEBHzSz1TuMSTAIh\nAKVTqOkt59+co0O3m3hC+v5Fb00FjYWcgeu3EijOULo5\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIICjzCCAjSgAwIBAgIUImUM1lqdNInzg7SVUr9QGzknBqwwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTE4MDUyMTEwNDUxMFoXDTQ5MTIzMTIzNTk1OVowaDEaMBgG\nA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENvcnBvcmF0\naW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJBgNVBAYT\nAlVTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEC6nEwMDIYZOj/iPWsCzaEKi7\n1OiOSLRFhWGjbnBVJfVnkY4u3IjkDYYL0MxO4mqsyYjlBalTVYxFP2sJBK5zlKOB\nuzCBuDAfBgNVHSMEGDAWgBQiZQzWWp00ifODtJVSv1AbOScGrDBSBgNVHR8ESzBJ\nMEegRaBDhkFodHRwczovL2NlcnRpZmljYXRlcy50cnVzdGVkc2VydmljZXMuaW50\nZWwuY29tL0ludGVsU0dYUm9vdENBLmRlcjAdBgNVHQ4EFgQUImUM1lqdNInzg7SV\nUr9QGzknBqwwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwCgYI\nKoZIzj0EAwIDSQAwRgIhAOW/5QkR+S9CiSDcNoowLuPRLsWGf/Yi7GSX94BgwTwg\nAiEA4J0lrHoMs+Xo5o/sX6O9QWxHRAvZUGOdRQ7cvqRXaqI=\n-----END CERTIFICATE-----\n", + "tcb_evaluation_data_numbers_json": "{\"tcbEvaluationDataNumbers\":{\"id\":\"SGX\",\"version\":1,\"issueDate\":\"2025-05-27T19:04:23Z\",\"nextUpdate\":\"2025-06-26T19:04:23Z\",\"tcbEvalNumbers\":[{\"tcbEvaluationDataNumber\":19,\"tcbRecoveryEventDate\":\"2025-05-13T00:00:00Z\",\"tcbDate\":\"2025-05-14T00:00:00Z\"},{\"tcbEvaluationDataNumber\":18,\"tcbRecoveryEventDate\":\"2024-11-12T00:00:00Z\",\"tcbDate\":\"2024-11-13T00:00:00Z\"},{\"tcbEvaluationDataNumber\":17,\"tcbRecoveryEventDate\":\"2024-03-12T00:00:00Z\",\"tcbDate\":\"2024-03-13T00:00:00Z\"}]},\"signature\":\"19799ae10942dc046340aa279123fe743e2ab51c862ab6a04abdaab86083013ca81ac1963aa08f1a3b44f0c12e9c6d094cb98aa5ca51bc40439833ada6f0e9e1\"}" +} \ No newline at end of file diff --git a/crates/intel-dcap-api/tests/test_data/sgx_tcb_info_00906ED50000.json b/crates/intel-dcap-api/tests/test_data/sgx_tcb_info_00906ED50000.json new file mode 100644 index 0000000..8e17eee --- /dev/null +++ b/crates/intel-dcap-api/tests/test_data/sgx_tcb_info_00906ED50000.json @@ -0,0 +1,4 @@ +{ + "issuer_chain": "-----BEGIN CERTIFICATE-----\nMIICjTCCAjKgAwIBAgIUfjiC1ftVKUpASY5FhAPpFJG99FUwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTI1MDUwNjA5MjUwMFoXDTMyMDUwNjA5MjUwMFowbDEeMBwG\nA1UEAwwVSW50ZWwgU0dYIFRDQiBTaWduaW5nMRowGAYDVQQKDBFJbnRlbCBDb3Jw\nb3JhdGlvbjEUMBIGA1UEBwwLU2FudGEgQ2xhcmExCzAJBgNVBAgMAkNBMQswCQYD\nVQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABENFG8xzydWRfK92bmGv\nP+mAh91PEyV7Jh6FGJd5ndE9aBH7R3E4A7ubrlh/zN3C4xvpoouGlirMba+W2lju\nypajgbUwgbIwHwYDVR0jBBgwFoAUImUM1lqdNInzg7SVUr9QGzknBqwwUgYDVR0f\nBEswSTBHoEWgQ4ZBaHR0cHM6Ly9jZXJ0aWZpY2F0ZXMudHJ1c3RlZHNlcnZpY2Vz\nLmludGVsLmNvbS9JbnRlbFNHWFJvb3RDQS5kZXIwHQYDVR0OBBYEFH44gtX7VSlK\nQEmORYQD6RSRvfRVMA4GA1UdDwEB/wQEAwIGwDAMBgNVHRMBAf8EAjAAMAoGCCqG\nSM49BAMCA0kAMEYCIQDdmmRuAo3qCO8TC1IoJMITAoOEw4dlgEBHzSz1TuMSTAIh\nAKVTqOkt59+co0O3m3hC+v5Fb00FjYWcgeu3EijOULo5\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIICjzCCAjSgAwIBAgIUImUM1lqdNInzg7SVUr9QGzknBqwwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTE4MDUyMTEwNDUxMFoXDTQ5MTIzMTIzNTk1OVowaDEaMBgG\nA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENvcnBvcmF0\naW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJBgNVBAYT\nAlVTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEC6nEwMDIYZOj/iPWsCzaEKi7\n1OiOSLRFhWGjbnBVJfVnkY4u3IjkDYYL0MxO4mqsyYjlBalTVYxFP2sJBK5zlKOB\nuzCBuDAfBgNVHSMEGDAWgBQiZQzWWp00ifODtJVSv1AbOScGrDBSBgNVHR8ESzBJ\nMEegRaBDhkFodHRwczovL2NlcnRpZmljYXRlcy50cnVzdGVkc2VydmljZXMuaW50\nZWwuY29tL0ludGVsU0dYUm9vdENBLmRlcjAdBgNVHQ4EFgQUImUM1lqdNInzg7SV\nUr9QGzknBqwwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwCgYI\nKoZIzj0EAwIDSQAwRgIhAOW/5QkR+S9CiSDcNoowLuPRLsWGf/Yi7GSX94BgwTwg\nAiEA4J0lrHoMs+Xo5o/sX6O9QWxHRAvZUGOdRQ7cvqRXaqI=\n-----END CERTIFICATE-----\n", + "tcb_info_json": "{\"tcbInfo\":{\"id\":\"SGX\",\"version\":3,\"issueDate\":\"2025-05-27T19:31:07Z\",\"nextUpdate\":\"2025-06-26T19:31:07Z\",\"fmspc\":\"00906ED50000\",\"pceId\":\"0000\",\"tcbType\":0,\"tcbEvaluationDataNumber\":17,\"tcbLevels\":[{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":21},{\"svn\":21},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":14},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":13},\"tcbDate\":\"2024-03-13T00:00:00Z\",\"tcbStatus\":\"SWHardeningNeeded\",\"advisoryIDs\":[\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":21},{\"svn\":21},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":13},\"tcbDate\":\"2024-03-13T00:00:00Z\",\"tcbStatus\":\"ConfigurationAndSWHardeningNeeded\",\"advisoryIDs\":[\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":20},{\"svn\":20},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":14},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":13},\"tcbDate\":\"2023-02-15T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00828\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":20},{\"svn\":20},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":13},\"tcbDate\":\"2023-02-15T00:00:00Z\",\"tcbStatus\":\"OutOfDateConfigurationNeeded\",\"advisoryIDs\":[\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":19},{\"svn\":19},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":6},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":13},\"tcbDate\":\"2021-11-10T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":19},{\"svn\":19},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":13},\"tcbDate\":\"2021-11-10T00:00:00Z\",\"tcbStatus\":\"OutOfDateConfigurationNeeded\",\"advisoryIDs\":[\"INTEL-SA-00161\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":17},{\"svn\":17},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":6},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":11},\"tcbDate\":\"2021-11-10T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00161\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":17},{\"svn\":17},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":6},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":10},\"tcbDate\":\"2020-11-11T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00161\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":17},{\"svn\":17},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":11},\"tcbDate\":\"2021-11-10T00:00:00Z\",\"tcbStatus\":\"OutOfDateConfigurationNeeded\",\"advisoryIDs\":[\"INTEL-SA-00161\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":17},{\"svn\":17},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":10},\"tcbDate\":\"2020-11-11T00:00:00Z\",\"tcbStatus\":\"OutOfDateConfigurationNeeded\",\"advisoryIDs\":[\"INTEL-SA-00477\",\"INTEL-SA-00161\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":15},{\"svn\":15},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":6},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":10},\"tcbDate\":\"2020-06-10T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00381\",\"INTEL-SA-00389\",\"INTEL-SA-00477\",\"INTEL-SA-00161\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":15},{\"svn\":15},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":10},\"tcbDate\":\"2020-06-10T00:00:00Z\",\"tcbStatus\":\"OutOfDateConfigurationNeeded\",\"advisoryIDs\":[\"INTEL-SA-00161\",\"INTEL-SA-00381\",\"INTEL-SA-00389\",\"INTEL-SA-00477\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":14},{\"svn\":14},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":6},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":10},\"tcbDate\":\"2019-12-11T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00320\",\"INTEL-SA-00329\",\"INTEL-SA-00161\",\"INTEL-SA-00381\",\"INTEL-SA-00389\",\"INTEL-SA-00477\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":14},{\"svn\":14},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":10},\"tcbDate\":\"2019-12-11T00:00:00Z\",\"tcbStatus\":\"OutOfDateConfigurationNeeded\",\"advisoryIDs\":[\"INTEL-SA-00161\",\"INTEL-SA-00320\",\"INTEL-SA-00329\",\"INTEL-SA-00381\",\"INTEL-SA-00389\",\"INTEL-SA-00477\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":13},{\"svn\":13},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":2},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":9},\"tcbDate\":\"2019-11-13T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00161\",\"INTEL-SA-00320\",\"INTEL-SA-00329\",\"INTEL-SA-00381\",\"INTEL-SA-00389\",\"INTEL-SA-00477\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":13},{\"svn\":13},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":9},\"tcbDate\":\"2019-11-13T00:00:00Z\",\"tcbStatus\":\"OutOfDateConfigurationNeeded\",\"advisoryIDs\":[\"INTEL-SA-00219\",\"INTEL-SA-00161\",\"INTEL-SA-00320\",\"INTEL-SA-00329\",\"INTEL-SA-00381\",\"INTEL-SA-00389\",\"INTEL-SA-00477\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":2},{\"svn\":2},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":7},\"tcbDate\":\"2019-05-15T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00220\",\"INTEL-SA-00270\",\"INTEL-SA-00293\",\"INTEL-SA-00219\",\"INTEL-SA-00161\",\"INTEL-SA-00320\",\"INTEL-SA-00329\",\"INTEL-SA-00381\",\"INTEL-SA-00389\",\"INTEL-SA-00477\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":1},{\"svn\":1},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":7},\"tcbDate\":\"2019-01-09T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00233\",\"INTEL-SA-00220\",\"INTEL-SA-00270\",\"INTEL-SA-00293\",\"INTEL-SA-00219\",\"INTEL-SA-00161\",\"INTEL-SA-00320\",\"INTEL-SA-00329\",\"INTEL-SA-00381\",\"INTEL-SA-00389\",\"INTEL-SA-00477\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":1},{\"svn\":1},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":6},\"tcbDate\":\"2018-08-15T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00203\",\"INTEL-SA-00233\",\"INTEL-SA-00220\",\"INTEL-SA-00270\",\"INTEL-SA-00293\",\"INTEL-SA-00219\",\"INTEL-SA-00161\",\"INTEL-SA-00320\",\"INTEL-SA-00329\",\"INTEL-SA-00381\",\"INTEL-SA-00389\",\"INTEL-SA-00477\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]}]},\"signature\":\"6110be36e7515cd536981fedf215ef6b937de0f4c758b672557395a2dc987d94028eb8c4ee3c065bb5585fb2953233160253064128157a48cac7a76822f6aacb\"}" +} \ No newline at end of file diff --git a/crates/intel-dcap-api/tests/test_data/sgx_tcb_info_alt.json b/crates/intel-dcap-api/tests/test_data/sgx_tcb_info_alt.json new file mode 100644 index 0000000..8e17eee --- /dev/null +++ b/crates/intel-dcap-api/tests/test_data/sgx_tcb_info_alt.json @@ -0,0 +1,4 @@ +{ + "issuer_chain": "-----BEGIN CERTIFICATE-----\nMIICjTCCAjKgAwIBAgIUfjiC1ftVKUpASY5FhAPpFJG99FUwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTI1MDUwNjA5MjUwMFoXDTMyMDUwNjA5MjUwMFowbDEeMBwG\nA1UEAwwVSW50ZWwgU0dYIFRDQiBTaWduaW5nMRowGAYDVQQKDBFJbnRlbCBDb3Jw\nb3JhdGlvbjEUMBIGA1UEBwwLU2FudGEgQ2xhcmExCzAJBgNVBAgMAkNBMQswCQYD\nVQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABENFG8xzydWRfK92bmGv\nP+mAh91PEyV7Jh6FGJd5ndE9aBH7R3E4A7ubrlh/zN3C4xvpoouGlirMba+W2lju\nypajgbUwgbIwHwYDVR0jBBgwFoAUImUM1lqdNInzg7SVUr9QGzknBqwwUgYDVR0f\nBEswSTBHoEWgQ4ZBaHR0cHM6Ly9jZXJ0aWZpY2F0ZXMudHJ1c3RlZHNlcnZpY2Vz\nLmludGVsLmNvbS9JbnRlbFNHWFJvb3RDQS5kZXIwHQYDVR0OBBYEFH44gtX7VSlK\nQEmORYQD6RSRvfRVMA4GA1UdDwEB/wQEAwIGwDAMBgNVHRMBAf8EAjAAMAoGCCqG\nSM49BAMCA0kAMEYCIQDdmmRuAo3qCO8TC1IoJMITAoOEw4dlgEBHzSz1TuMSTAIh\nAKVTqOkt59+co0O3m3hC+v5Fb00FjYWcgeu3EijOULo5\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIICjzCCAjSgAwIBAgIUImUM1lqdNInzg7SVUr9QGzknBqwwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTE4MDUyMTEwNDUxMFoXDTQ5MTIzMTIzNTk1OVowaDEaMBgG\nA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENvcnBvcmF0\naW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJBgNVBAYT\nAlVTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEC6nEwMDIYZOj/iPWsCzaEKi7\n1OiOSLRFhWGjbnBVJfVnkY4u3IjkDYYL0MxO4mqsyYjlBalTVYxFP2sJBK5zlKOB\nuzCBuDAfBgNVHSMEGDAWgBQiZQzWWp00ifODtJVSv1AbOScGrDBSBgNVHR8ESzBJ\nMEegRaBDhkFodHRwczovL2NlcnRpZmljYXRlcy50cnVzdGVkc2VydmljZXMuaW50\nZWwuY29tL0ludGVsU0dYUm9vdENBLmRlcjAdBgNVHQ4EFgQUImUM1lqdNInzg7SV\nUr9QGzknBqwwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwCgYI\nKoZIzj0EAwIDSQAwRgIhAOW/5QkR+S9CiSDcNoowLuPRLsWGf/Yi7GSX94BgwTwg\nAiEA4J0lrHoMs+Xo5o/sX6O9QWxHRAvZUGOdRQ7cvqRXaqI=\n-----END CERTIFICATE-----\n", + "tcb_info_json": "{\"tcbInfo\":{\"id\":\"SGX\",\"version\":3,\"issueDate\":\"2025-05-27T19:31:07Z\",\"nextUpdate\":\"2025-06-26T19:31:07Z\",\"fmspc\":\"00906ED50000\",\"pceId\":\"0000\",\"tcbType\":0,\"tcbEvaluationDataNumber\":17,\"tcbLevels\":[{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":21},{\"svn\":21},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":14},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":13},\"tcbDate\":\"2024-03-13T00:00:00Z\",\"tcbStatus\":\"SWHardeningNeeded\",\"advisoryIDs\":[\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":21},{\"svn\":21},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":13},\"tcbDate\":\"2024-03-13T00:00:00Z\",\"tcbStatus\":\"ConfigurationAndSWHardeningNeeded\",\"advisoryIDs\":[\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":20},{\"svn\":20},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":14},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":13},\"tcbDate\":\"2023-02-15T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00828\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":20},{\"svn\":20},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":13},\"tcbDate\":\"2023-02-15T00:00:00Z\",\"tcbStatus\":\"OutOfDateConfigurationNeeded\",\"advisoryIDs\":[\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":19},{\"svn\":19},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":6},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":13},\"tcbDate\":\"2021-11-10T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":19},{\"svn\":19},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":13},\"tcbDate\":\"2021-11-10T00:00:00Z\",\"tcbStatus\":\"OutOfDateConfigurationNeeded\",\"advisoryIDs\":[\"INTEL-SA-00161\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":17},{\"svn\":17},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":6},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":11},\"tcbDate\":\"2021-11-10T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00161\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":17},{\"svn\":17},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":6},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":10},\"tcbDate\":\"2020-11-11T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00161\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":17},{\"svn\":17},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":11},\"tcbDate\":\"2021-11-10T00:00:00Z\",\"tcbStatus\":\"OutOfDateConfigurationNeeded\",\"advisoryIDs\":[\"INTEL-SA-00161\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":17},{\"svn\":17},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":10},\"tcbDate\":\"2020-11-11T00:00:00Z\",\"tcbStatus\":\"OutOfDateConfigurationNeeded\",\"advisoryIDs\":[\"INTEL-SA-00477\",\"INTEL-SA-00161\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":15},{\"svn\":15},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":6},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":10},\"tcbDate\":\"2020-06-10T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00381\",\"INTEL-SA-00389\",\"INTEL-SA-00477\",\"INTEL-SA-00161\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":15},{\"svn\":15},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":10},\"tcbDate\":\"2020-06-10T00:00:00Z\",\"tcbStatus\":\"OutOfDateConfigurationNeeded\",\"advisoryIDs\":[\"INTEL-SA-00161\",\"INTEL-SA-00381\",\"INTEL-SA-00389\",\"INTEL-SA-00477\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":14},{\"svn\":14},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":6},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":10},\"tcbDate\":\"2019-12-11T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00320\",\"INTEL-SA-00329\",\"INTEL-SA-00161\",\"INTEL-SA-00381\",\"INTEL-SA-00389\",\"INTEL-SA-00477\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":14},{\"svn\":14},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":10},\"tcbDate\":\"2019-12-11T00:00:00Z\",\"tcbStatus\":\"OutOfDateConfigurationNeeded\",\"advisoryIDs\":[\"INTEL-SA-00161\",\"INTEL-SA-00320\",\"INTEL-SA-00329\",\"INTEL-SA-00381\",\"INTEL-SA-00389\",\"INTEL-SA-00477\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":13},{\"svn\":13},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":2},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":9},\"tcbDate\":\"2019-11-13T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00161\",\"INTEL-SA-00320\",\"INTEL-SA-00329\",\"INTEL-SA-00381\",\"INTEL-SA-00389\",\"INTEL-SA-00477\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":13},{\"svn\":13},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":9},\"tcbDate\":\"2019-11-13T00:00:00Z\",\"tcbStatus\":\"OutOfDateConfigurationNeeded\",\"advisoryIDs\":[\"INTEL-SA-00219\",\"INTEL-SA-00161\",\"INTEL-SA-00320\",\"INTEL-SA-00329\",\"INTEL-SA-00381\",\"INTEL-SA-00389\",\"INTEL-SA-00477\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":2},{\"svn\":2},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":7},\"tcbDate\":\"2019-05-15T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00220\",\"INTEL-SA-00270\",\"INTEL-SA-00293\",\"INTEL-SA-00219\",\"INTEL-SA-00161\",\"INTEL-SA-00320\",\"INTEL-SA-00329\",\"INTEL-SA-00381\",\"INTEL-SA-00389\",\"INTEL-SA-00477\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":1},{\"svn\":1},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":7},\"tcbDate\":\"2019-01-09T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00233\",\"INTEL-SA-00220\",\"INTEL-SA-00270\",\"INTEL-SA-00293\",\"INTEL-SA-00219\",\"INTEL-SA-00161\",\"INTEL-SA-00320\",\"INTEL-SA-00329\",\"INTEL-SA-00381\",\"INTEL-SA-00389\",\"INTEL-SA-00477\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":1},{\"svn\":1},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":6},\"tcbDate\":\"2018-08-15T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00203\",\"INTEL-SA-00233\",\"INTEL-SA-00220\",\"INTEL-SA-00270\",\"INTEL-SA-00293\",\"INTEL-SA-00219\",\"INTEL-SA-00161\",\"INTEL-SA-00320\",\"INTEL-SA-00329\",\"INTEL-SA-00381\",\"INTEL-SA-00389\",\"INTEL-SA-00477\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]}]},\"signature\":\"6110be36e7515cd536981fedf215ef6b937de0f4c758b672557395a2dc987d94028eb8c4ee3c065bb5585fb2953233160253064128157a48cac7a76822f6aacb\"}" +} \ No newline at end of file diff --git a/crates/intel-dcap-api/tests/test_data/sgx_tcb_info_early.json b/crates/intel-dcap-api/tests/test_data/sgx_tcb_info_early.json new file mode 100644 index 0000000..b57d7eb --- /dev/null +++ b/crates/intel-dcap-api/tests/test_data/sgx_tcb_info_early.json @@ -0,0 +1,4 @@ +{ + "issuer_chain": "-----BEGIN CERTIFICATE-----\nMIICjTCCAjKgAwIBAgIUfjiC1ftVKUpASY5FhAPpFJG99FUwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTI1MDUwNjA5MjUwMFoXDTMyMDUwNjA5MjUwMFowbDEeMBwG\nA1UEAwwVSW50ZWwgU0dYIFRDQiBTaWduaW5nMRowGAYDVQQKDBFJbnRlbCBDb3Jw\nb3JhdGlvbjEUMBIGA1UEBwwLU2FudGEgQ2xhcmExCzAJBgNVBAgMAkNBMQswCQYD\nVQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABENFG8xzydWRfK92bmGv\nP+mAh91PEyV7Jh6FGJd5ndE9aBH7R3E4A7ubrlh/zN3C4xvpoouGlirMba+W2lju\nypajgbUwgbIwHwYDVR0jBBgwFoAUImUM1lqdNInzg7SVUr9QGzknBqwwUgYDVR0f\nBEswSTBHoEWgQ4ZBaHR0cHM6Ly9jZXJ0aWZpY2F0ZXMudHJ1c3RlZHNlcnZpY2Vz\nLmludGVsLmNvbS9JbnRlbFNHWFJvb3RDQS5kZXIwHQYDVR0OBBYEFH44gtX7VSlK\nQEmORYQD6RSRvfRVMA4GA1UdDwEB/wQEAwIGwDAMBgNVHRMBAf8EAjAAMAoGCCqG\nSM49BAMCA0kAMEYCIQDdmmRuAo3qCO8TC1IoJMITAoOEw4dlgEBHzSz1TuMSTAIh\nAKVTqOkt59+co0O3m3hC+v5Fb00FjYWcgeu3EijOULo5\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIICjzCCAjSgAwIBAgIUImUM1lqdNInzg7SVUr9QGzknBqwwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTE4MDUyMTEwNDUxMFoXDTQ5MTIzMTIzNTk1OVowaDEaMBgG\nA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENvcnBvcmF0\naW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJBgNVBAYT\nAlVTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEC6nEwMDIYZOj/iPWsCzaEKi7\n1OiOSLRFhWGjbnBVJfVnkY4u3IjkDYYL0MxO4mqsyYjlBalTVYxFP2sJBK5zlKOB\nuzCBuDAfBgNVHSMEGDAWgBQiZQzWWp00ifODtJVSv1AbOScGrDBSBgNVHR8ESzBJ\nMEegRaBDhkFodHRwczovL2NlcnRpZmljYXRlcy50cnVzdGVkc2VydmljZXMuaW50\nZWwuY29tL0ludGVsU0dYUm9vdENBLmRlcjAdBgNVHQ4EFgQUImUM1lqdNInzg7SV\nUr9QGzknBqwwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwCgYI\nKoZIzj0EAwIDSQAwRgIhAOW/5QkR+S9CiSDcNoowLuPRLsWGf/Yi7GSX94BgwTwg\nAiEA4J0lrHoMs+Xo5o/sX6O9QWxHRAvZUGOdRQ7cvqRXaqI=\n-----END CERTIFICATE-----\n", + "tcb_info_json": "{\"tcbInfo\":{\"id\":\"SGX\",\"version\":3,\"issueDate\":\"2025-05-27T19:31:08Z\",\"nextUpdate\":\"2025-06-26T19:31:08Z\",\"fmspc\":\"00906ED50000\",\"pceId\":\"0000\",\"tcbType\":0,\"tcbEvaluationDataNumber\":19,\"tcbLevels\":[{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":22},{\"svn\":22},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":14},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":13},\"tcbDate\":\"2025-05-14T00:00:00Z\",\"tcbStatus\":\"SWHardeningNeeded\",\"advisoryIDs\":[\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":22},{\"svn\":22},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":13},\"tcbDate\":\"2025-05-14T00:00:00Z\",\"tcbStatus\":\"ConfigurationAndSWHardeningNeeded\",\"advisoryIDs\":[\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":21},{\"svn\":21},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":14},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":13},\"tcbDate\":\"2024-11-13T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-01153\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":21},{\"svn\":21},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":13},\"tcbDate\":\"2024-11-13T00:00:00Z\",\"tcbStatus\":\"OutOfDateConfigurationNeeded\",\"advisoryIDs\":[\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-01153\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":20},{\"svn\":20},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":14},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":13},\"tcbDate\":\"2023-02-15T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00828\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-01153\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":20},{\"svn\":20},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":13},\"tcbDate\":\"2023-02-15T00:00:00Z\",\"tcbStatus\":\"OutOfDateConfigurationNeeded\",\"advisoryIDs\":[\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-01153\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":19},{\"svn\":19},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":6},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":13},\"tcbDate\":\"2021-11-10T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-01153\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":19},{\"svn\":19},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":13},\"tcbDate\":\"2021-11-10T00:00:00Z\",\"tcbStatus\":\"OutOfDateConfigurationNeeded\",\"advisoryIDs\":[\"INTEL-SA-00161\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-01153\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":17},{\"svn\":17},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":6},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":11},\"tcbDate\":\"2021-11-10T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00161\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-01153\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":17},{\"svn\":17},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":6},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":10},\"tcbDate\":\"2020-11-11T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00161\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-01153\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":17},{\"svn\":17},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":11},\"tcbDate\":\"2021-11-10T00:00:00Z\",\"tcbStatus\":\"OutOfDateConfigurationNeeded\",\"advisoryIDs\":[\"INTEL-SA-00161\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-01153\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":17},{\"svn\":17},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":10},\"tcbDate\":\"2020-11-11T00:00:00Z\",\"tcbStatus\":\"OutOfDateConfigurationNeeded\",\"advisoryIDs\":[\"INTEL-SA-00477\",\"INTEL-SA-00161\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-01153\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":15},{\"svn\":15},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":6},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":10},\"tcbDate\":\"2020-06-10T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00381\",\"INTEL-SA-00389\",\"INTEL-SA-00477\",\"INTEL-SA-00161\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-01153\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":15},{\"svn\":15},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":10},\"tcbDate\":\"2020-06-10T00:00:00Z\",\"tcbStatus\":\"OutOfDateConfigurationNeeded\",\"advisoryIDs\":[\"INTEL-SA-00161\",\"INTEL-SA-00381\",\"INTEL-SA-00389\",\"INTEL-SA-00477\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-01153\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":14},{\"svn\":14},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":6},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":10},\"tcbDate\":\"2019-12-11T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00320\",\"INTEL-SA-00329\",\"INTEL-SA-00161\",\"INTEL-SA-00381\",\"INTEL-SA-00389\",\"INTEL-SA-00477\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-01153\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":14},{\"svn\":14},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":10},\"tcbDate\":\"2019-12-11T00:00:00Z\",\"tcbStatus\":\"OutOfDateConfigurationNeeded\",\"advisoryIDs\":[\"INTEL-SA-00161\",\"INTEL-SA-00320\",\"INTEL-SA-00329\",\"INTEL-SA-00381\",\"INTEL-SA-00389\",\"INTEL-SA-00477\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-01153\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":13},{\"svn\":13},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":2},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":9},\"tcbDate\":\"2019-11-13T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00161\",\"INTEL-SA-00320\",\"INTEL-SA-00329\",\"INTEL-SA-00381\",\"INTEL-SA-00389\",\"INTEL-SA-00477\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00219\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-01153\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":13},{\"svn\":13},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":9},\"tcbDate\":\"2019-11-13T00:00:00Z\",\"tcbStatus\":\"OutOfDateConfigurationNeeded\",\"advisoryIDs\":[\"INTEL-SA-00219\",\"INTEL-SA-00161\",\"INTEL-SA-00320\",\"INTEL-SA-00329\",\"INTEL-SA-00381\",\"INTEL-SA-00389\",\"INTEL-SA-00477\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-01153\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":2},{\"svn\":2},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":7},\"tcbDate\":\"2019-05-15T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00220\",\"INTEL-SA-00270\",\"INTEL-SA-00293\",\"INTEL-SA-00219\",\"INTEL-SA-00161\",\"INTEL-SA-00320\",\"INTEL-SA-00329\",\"INTEL-SA-00381\",\"INTEL-SA-00389\",\"INTEL-SA-00477\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-01153\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":1},{\"svn\":1},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":7},\"tcbDate\":\"2019-01-09T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00233\",\"INTEL-SA-00220\",\"INTEL-SA-00270\",\"INTEL-SA-00293\",\"INTEL-SA-00219\",\"INTEL-SA-00161\",\"INTEL-SA-00320\",\"INTEL-SA-00329\",\"INTEL-SA-00381\",\"INTEL-SA-00389\",\"INTEL-SA-00477\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-01153\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":1},{\"svn\":1},{\"svn\":2},{\"svn\":4},{\"svn\":1},{\"svn\":128},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":6},\"tcbDate\":\"2018-08-15T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00203\",\"INTEL-SA-00233\",\"INTEL-SA-00220\",\"INTEL-SA-00270\",\"INTEL-SA-00293\",\"INTEL-SA-00219\",\"INTEL-SA-00161\",\"INTEL-SA-00320\",\"INTEL-SA-00329\",\"INTEL-SA-00381\",\"INTEL-SA-00389\",\"INTEL-SA-00477\",\"INTEL-SA-00614\",\"INTEL-SA-00617\",\"INTEL-SA-00289\",\"INTEL-SA-00828\",\"INTEL-SA-01153\",\"INTEL-SA-00334\",\"INTEL-SA-00615\"]}]},\"signature\":\"f923da7909b959d047642857106e14d3198da1222fc9bb0d6eb4aab571d55c3c583488eec8b06445666d3c19f02d2ec72cde4c2247886684d93fb70ed1f67efc\"}" +} \ No newline at end of file diff --git a/crates/intel-dcap-api/tests/test_data/sgx_tcb_info_v3.json b/crates/intel-dcap-api/tests/test_data/sgx_tcb_info_v3.json new file mode 100644 index 0000000..16c1925 --- /dev/null +++ b/crates/intel-dcap-api/tests/test_data/sgx_tcb_info_v3.json @@ -0,0 +1,4 @@ +{ + "issuer_chain": "-----BEGIN CERTIFICATE-----\nMIICjTCCAjKgAwIBAgIUfjiC1ftVKUpASY5FhAPpFJG99FUwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTI1MDUwNjA5MjUwMFoXDTMyMDUwNjA5MjUwMFowbDEeMBwG\nA1UEAwwVSW50ZWwgU0dYIFRDQiBTaWduaW5nMRowGAYDVQQKDBFJbnRlbCBDb3Jw\nb3JhdGlvbjEUMBIGA1UEBwwLU2FudGEgQ2xhcmExCzAJBgNVBAgMAkNBMQswCQYD\nVQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABENFG8xzydWRfK92bmGv\nP+mAh91PEyV7Jh6FGJd5ndE9aBH7R3E4A7ubrlh/zN3C4xvpoouGlirMba+W2lju\nypajgbUwgbIwHwYDVR0jBBgwFoAUImUM1lqdNInzg7SVUr9QGzknBqwwUgYDVR0f\nBEswSTBHoEWgQ4ZBaHR0cHM6Ly9jZXJ0aWZpY2F0ZXMudHJ1c3RlZHNlcnZpY2Vz\nLmludGVsLmNvbS9JbnRlbFNHWFJvb3RDQS5kZXIwHQYDVR0OBBYEFH44gtX7VSlK\nQEmORYQD6RSRvfRVMA4GA1UdDwEB/wQEAwIGwDAMBgNVHRMBAf8EAjAAMAoGCCqG\nSM49BAMCA0kAMEYCIQDdmmRuAo3qCO8TC1IoJMITAoOEw4dlgEBHzSz1TuMSTAIh\nAKVTqOkt59+co0O3m3hC+v5Fb00FjYWcgeu3EijOULo5\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIICjzCCAjSgAwIBAgIUImUM1lqdNInzg7SVUr9QGzknBqwwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTE4MDUyMTEwNDUxMFoXDTQ5MTIzMTIzNTk1OVowaDEaMBgG\nA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENvcnBvcmF0\naW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJBgNVBAYT\nAlVTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEC6nEwMDIYZOj/iPWsCzaEKi7\n1OiOSLRFhWGjbnBVJfVnkY4u3IjkDYYL0MxO4mqsyYjlBalTVYxFP2sJBK5zlKOB\nuzCBuDAfBgNVHSMEGDAWgBQiZQzWWp00ifODtJVSv1AbOScGrDBSBgNVHR8ESzBJ\nMEegRaBDhkFodHRwczovL2NlcnRpZmljYXRlcy50cnVzdGVkc2VydmljZXMuaW50\nZWwuY29tL0ludGVsU0dYUm9vdENBLmRlcjAdBgNVHQ4EFgQUImUM1lqdNInzg7SV\nUr9QGzknBqwwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwCgYI\nKoZIzj0EAwIDSQAwRgIhAOW/5QkR+S9CiSDcNoowLuPRLsWGf/Yi7GSX94BgwTwg\nAiEA4J0lrHoMs+Xo5o/sX6O9QWxHRAvZUGOdRQ7cvqRXaqI=\n-----END CERTIFICATE-----\n", + "tcb_info_json": "{\"tcbInfo\":{\"version\":2,\"issueDate\":\"2025-05-27T19:31:07Z\",\"nextUpdate\":\"2025-06-26T19:31:07Z\",\"fmspc\":\"00906ED50000\",\"pceId\":\"0000\",\"tcbType\":0,\"tcbEvaluationDataNumber\":17,\"tcbLevels\":[{\"tcb\":{\"sgxtcbcomp01svn\":21,\"sgxtcbcomp02svn\":21,\"sgxtcbcomp03svn\":2,\"sgxtcbcomp04svn\":4,\"sgxtcbcomp05svn\":1,\"sgxtcbcomp06svn\":128,\"sgxtcbcomp07svn\":14,\"sgxtcbcomp08svn\":0,\"sgxtcbcomp09svn\":0,\"sgxtcbcomp10svn\":0,\"sgxtcbcomp11svn\":0,\"sgxtcbcomp12svn\":0,\"sgxtcbcomp13svn\":0,\"sgxtcbcomp14svn\":0,\"sgxtcbcomp15svn\":0,\"sgxtcbcomp16svn\":0,\"pcesvn\":13},\"tcbDate\":\"2024-03-13T00:00:00Z\",\"tcbStatus\":\"SWHardeningNeeded\"},{\"tcb\":{\"sgxtcbcomp01svn\":21,\"sgxtcbcomp02svn\":21,\"sgxtcbcomp03svn\":2,\"sgxtcbcomp04svn\":4,\"sgxtcbcomp05svn\":1,\"sgxtcbcomp06svn\":128,\"sgxtcbcomp07svn\":0,\"sgxtcbcomp08svn\":0,\"sgxtcbcomp09svn\":0,\"sgxtcbcomp10svn\":0,\"sgxtcbcomp11svn\":0,\"sgxtcbcomp12svn\":0,\"sgxtcbcomp13svn\":0,\"sgxtcbcomp14svn\":0,\"sgxtcbcomp15svn\":0,\"sgxtcbcomp16svn\":0,\"pcesvn\":13},\"tcbDate\":\"2024-03-13T00:00:00Z\",\"tcbStatus\":\"ConfigurationAndSWHardeningNeeded\"},{\"tcb\":{\"sgxtcbcomp01svn\":20,\"sgxtcbcomp02svn\":20,\"sgxtcbcomp03svn\":2,\"sgxtcbcomp04svn\":4,\"sgxtcbcomp05svn\":1,\"sgxtcbcomp06svn\":128,\"sgxtcbcomp07svn\":14,\"sgxtcbcomp08svn\":0,\"sgxtcbcomp09svn\":0,\"sgxtcbcomp10svn\":0,\"sgxtcbcomp11svn\":0,\"sgxtcbcomp12svn\":0,\"sgxtcbcomp13svn\":0,\"sgxtcbcomp14svn\":0,\"sgxtcbcomp15svn\":0,\"sgxtcbcomp16svn\":0,\"pcesvn\":13},\"tcbDate\":\"2023-02-15T00:00:00Z\",\"tcbStatus\":\"OutOfDate\"},{\"tcb\":{\"sgxtcbcomp01svn\":20,\"sgxtcbcomp02svn\":20,\"sgxtcbcomp03svn\":2,\"sgxtcbcomp04svn\":4,\"sgxtcbcomp05svn\":1,\"sgxtcbcomp06svn\":128,\"sgxtcbcomp07svn\":0,\"sgxtcbcomp08svn\":0,\"sgxtcbcomp09svn\":0,\"sgxtcbcomp10svn\":0,\"sgxtcbcomp11svn\":0,\"sgxtcbcomp12svn\":0,\"sgxtcbcomp13svn\":0,\"sgxtcbcomp14svn\":0,\"sgxtcbcomp15svn\":0,\"sgxtcbcomp16svn\":0,\"pcesvn\":13},\"tcbDate\":\"2023-02-15T00:00:00Z\",\"tcbStatus\":\"OutOfDateConfigurationNeeded\"},{\"tcb\":{\"sgxtcbcomp01svn\":19,\"sgxtcbcomp02svn\":19,\"sgxtcbcomp03svn\":2,\"sgxtcbcomp04svn\":4,\"sgxtcbcomp05svn\":1,\"sgxtcbcomp06svn\":128,\"sgxtcbcomp07svn\":6,\"sgxtcbcomp08svn\":0,\"sgxtcbcomp09svn\":0,\"sgxtcbcomp10svn\":0,\"sgxtcbcomp11svn\":0,\"sgxtcbcomp12svn\":0,\"sgxtcbcomp13svn\":0,\"sgxtcbcomp14svn\":0,\"sgxtcbcomp15svn\":0,\"sgxtcbcomp16svn\":0,\"pcesvn\":13},\"tcbDate\":\"2021-11-10T00:00:00Z\",\"tcbStatus\":\"OutOfDate\"},{\"tcb\":{\"sgxtcbcomp01svn\":19,\"sgxtcbcomp02svn\":19,\"sgxtcbcomp03svn\":2,\"sgxtcbcomp04svn\":4,\"sgxtcbcomp05svn\":1,\"sgxtcbcomp06svn\":128,\"sgxtcbcomp07svn\":0,\"sgxtcbcomp08svn\":0,\"sgxtcbcomp09svn\":0,\"sgxtcbcomp10svn\":0,\"sgxtcbcomp11svn\":0,\"sgxtcbcomp12svn\":0,\"sgxtcbcomp13svn\":0,\"sgxtcbcomp14svn\":0,\"sgxtcbcomp15svn\":0,\"sgxtcbcomp16svn\":0,\"pcesvn\":13},\"tcbDate\":\"2021-11-10T00:00:00Z\",\"tcbStatus\":\"OutOfDateConfigurationNeeded\"},{\"tcb\":{\"sgxtcbcomp01svn\":17,\"sgxtcbcomp02svn\":17,\"sgxtcbcomp03svn\":2,\"sgxtcbcomp04svn\":4,\"sgxtcbcomp05svn\":1,\"sgxtcbcomp06svn\":128,\"sgxtcbcomp07svn\":6,\"sgxtcbcomp08svn\":0,\"sgxtcbcomp09svn\":0,\"sgxtcbcomp10svn\":0,\"sgxtcbcomp11svn\":0,\"sgxtcbcomp12svn\":0,\"sgxtcbcomp13svn\":0,\"sgxtcbcomp14svn\":0,\"sgxtcbcomp15svn\":0,\"sgxtcbcomp16svn\":0,\"pcesvn\":11},\"tcbDate\":\"2021-11-10T00:00:00Z\",\"tcbStatus\":\"OutOfDate\"},{\"tcb\":{\"sgxtcbcomp01svn\":17,\"sgxtcbcomp02svn\":17,\"sgxtcbcomp03svn\":2,\"sgxtcbcomp04svn\":4,\"sgxtcbcomp05svn\":1,\"sgxtcbcomp06svn\":128,\"sgxtcbcomp07svn\":6,\"sgxtcbcomp08svn\":0,\"sgxtcbcomp09svn\":0,\"sgxtcbcomp10svn\":0,\"sgxtcbcomp11svn\":0,\"sgxtcbcomp12svn\":0,\"sgxtcbcomp13svn\":0,\"sgxtcbcomp14svn\":0,\"sgxtcbcomp15svn\":0,\"sgxtcbcomp16svn\":0,\"pcesvn\":10},\"tcbDate\":\"2020-11-11T00:00:00Z\",\"tcbStatus\":\"OutOfDate\"},{\"tcb\":{\"sgxtcbcomp01svn\":17,\"sgxtcbcomp02svn\":17,\"sgxtcbcomp03svn\":2,\"sgxtcbcomp04svn\":4,\"sgxtcbcomp05svn\":1,\"sgxtcbcomp06svn\":128,\"sgxtcbcomp07svn\":0,\"sgxtcbcomp08svn\":0,\"sgxtcbcomp09svn\":0,\"sgxtcbcomp10svn\":0,\"sgxtcbcomp11svn\":0,\"sgxtcbcomp12svn\":0,\"sgxtcbcomp13svn\":0,\"sgxtcbcomp14svn\":0,\"sgxtcbcomp15svn\":0,\"sgxtcbcomp16svn\":0,\"pcesvn\":11},\"tcbDate\":\"2021-11-10T00:00:00Z\",\"tcbStatus\":\"OutOfDateConfigurationNeeded\"},{\"tcb\":{\"sgxtcbcomp01svn\":17,\"sgxtcbcomp02svn\":17,\"sgxtcbcomp03svn\":2,\"sgxtcbcomp04svn\":4,\"sgxtcbcomp05svn\":1,\"sgxtcbcomp06svn\":128,\"sgxtcbcomp07svn\":0,\"sgxtcbcomp08svn\":0,\"sgxtcbcomp09svn\":0,\"sgxtcbcomp10svn\":0,\"sgxtcbcomp11svn\":0,\"sgxtcbcomp12svn\":0,\"sgxtcbcomp13svn\":0,\"sgxtcbcomp14svn\":0,\"sgxtcbcomp15svn\":0,\"sgxtcbcomp16svn\":0,\"pcesvn\":10},\"tcbDate\":\"2020-11-11T00:00:00Z\",\"tcbStatus\":\"OutOfDateConfigurationNeeded\"},{\"tcb\":{\"sgxtcbcomp01svn\":15,\"sgxtcbcomp02svn\":15,\"sgxtcbcomp03svn\":2,\"sgxtcbcomp04svn\":4,\"sgxtcbcomp05svn\":1,\"sgxtcbcomp06svn\":128,\"sgxtcbcomp07svn\":6,\"sgxtcbcomp08svn\":0,\"sgxtcbcomp09svn\":0,\"sgxtcbcomp10svn\":0,\"sgxtcbcomp11svn\":0,\"sgxtcbcomp12svn\":0,\"sgxtcbcomp13svn\":0,\"sgxtcbcomp14svn\":0,\"sgxtcbcomp15svn\":0,\"sgxtcbcomp16svn\":0,\"pcesvn\":10},\"tcbDate\":\"2020-06-10T00:00:00Z\",\"tcbStatus\":\"OutOfDate\"},{\"tcb\":{\"sgxtcbcomp01svn\":15,\"sgxtcbcomp02svn\":15,\"sgxtcbcomp03svn\":2,\"sgxtcbcomp04svn\":4,\"sgxtcbcomp05svn\":1,\"sgxtcbcomp06svn\":128,\"sgxtcbcomp07svn\":0,\"sgxtcbcomp08svn\":0,\"sgxtcbcomp09svn\":0,\"sgxtcbcomp10svn\":0,\"sgxtcbcomp11svn\":0,\"sgxtcbcomp12svn\":0,\"sgxtcbcomp13svn\":0,\"sgxtcbcomp14svn\":0,\"sgxtcbcomp15svn\":0,\"sgxtcbcomp16svn\":0,\"pcesvn\":10},\"tcbDate\":\"2020-06-10T00:00:00Z\",\"tcbStatus\":\"OutOfDateConfigurationNeeded\"},{\"tcb\":{\"sgxtcbcomp01svn\":14,\"sgxtcbcomp02svn\":14,\"sgxtcbcomp03svn\":2,\"sgxtcbcomp04svn\":4,\"sgxtcbcomp05svn\":1,\"sgxtcbcomp06svn\":128,\"sgxtcbcomp07svn\":6,\"sgxtcbcomp08svn\":0,\"sgxtcbcomp09svn\":0,\"sgxtcbcomp10svn\":0,\"sgxtcbcomp11svn\":0,\"sgxtcbcomp12svn\":0,\"sgxtcbcomp13svn\":0,\"sgxtcbcomp14svn\":0,\"sgxtcbcomp15svn\":0,\"sgxtcbcomp16svn\":0,\"pcesvn\":10},\"tcbDate\":\"2019-12-11T00:00:00Z\",\"tcbStatus\":\"OutOfDate\"},{\"tcb\":{\"sgxtcbcomp01svn\":14,\"sgxtcbcomp02svn\":14,\"sgxtcbcomp03svn\":2,\"sgxtcbcomp04svn\":4,\"sgxtcbcomp05svn\":1,\"sgxtcbcomp06svn\":128,\"sgxtcbcomp07svn\":0,\"sgxtcbcomp08svn\":0,\"sgxtcbcomp09svn\":0,\"sgxtcbcomp10svn\":0,\"sgxtcbcomp11svn\":0,\"sgxtcbcomp12svn\":0,\"sgxtcbcomp13svn\":0,\"sgxtcbcomp14svn\":0,\"sgxtcbcomp15svn\":0,\"sgxtcbcomp16svn\":0,\"pcesvn\":10},\"tcbDate\":\"2019-12-11T00:00:00Z\",\"tcbStatus\":\"OutOfDateConfigurationNeeded\"},{\"tcb\":{\"sgxtcbcomp01svn\":13,\"sgxtcbcomp02svn\":13,\"sgxtcbcomp03svn\":2,\"sgxtcbcomp04svn\":4,\"sgxtcbcomp05svn\":1,\"sgxtcbcomp06svn\":128,\"sgxtcbcomp07svn\":2,\"sgxtcbcomp08svn\":0,\"sgxtcbcomp09svn\":0,\"sgxtcbcomp10svn\":0,\"sgxtcbcomp11svn\":0,\"sgxtcbcomp12svn\":0,\"sgxtcbcomp13svn\":0,\"sgxtcbcomp14svn\":0,\"sgxtcbcomp15svn\":0,\"sgxtcbcomp16svn\":0,\"pcesvn\":9},\"tcbDate\":\"2019-11-13T00:00:00Z\",\"tcbStatus\":\"OutOfDate\"},{\"tcb\":{\"sgxtcbcomp01svn\":13,\"sgxtcbcomp02svn\":13,\"sgxtcbcomp03svn\":2,\"sgxtcbcomp04svn\":4,\"sgxtcbcomp05svn\":1,\"sgxtcbcomp06svn\":128,\"sgxtcbcomp07svn\":0,\"sgxtcbcomp08svn\":0,\"sgxtcbcomp09svn\":0,\"sgxtcbcomp10svn\":0,\"sgxtcbcomp11svn\":0,\"sgxtcbcomp12svn\":0,\"sgxtcbcomp13svn\":0,\"sgxtcbcomp14svn\":0,\"sgxtcbcomp15svn\":0,\"sgxtcbcomp16svn\":0,\"pcesvn\":9},\"tcbDate\":\"2019-11-13T00:00:00Z\",\"tcbStatus\":\"OutOfDateConfigurationNeeded\"},{\"tcb\":{\"sgxtcbcomp01svn\":2,\"sgxtcbcomp02svn\":2,\"sgxtcbcomp03svn\":2,\"sgxtcbcomp04svn\":4,\"sgxtcbcomp05svn\":1,\"sgxtcbcomp06svn\":128,\"sgxtcbcomp07svn\":0,\"sgxtcbcomp08svn\":0,\"sgxtcbcomp09svn\":0,\"sgxtcbcomp10svn\":0,\"sgxtcbcomp11svn\":0,\"sgxtcbcomp12svn\":0,\"sgxtcbcomp13svn\":0,\"sgxtcbcomp14svn\":0,\"sgxtcbcomp15svn\":0,\"sgxtcbcomp16svn\":0,\"pcesvn\":7},\"tcbDate\":\"2019-05-15T00:00:00Z\",\"tcbStatus\":\"OutOfDate\"},{\"tcb\":{\"sgxtcbcomp01svn\":1,\"sgxtcbcomp02svn\":1,\"sgxtcbcomp03svn\":2,\"sgxtcbcomp04svn\":4,\"sgxtcbcomp05svn\":1,\"sgxtcbcomp06svn\":128,\"sgxtcbcomp07svn\":0,\"sgxtcbcomp08svn\":0,\"sgxtcbcomp09svn\":0,\"sgxtcbcomp10svn\":0,\"sgxtcbcomp11svn\":0,\"sgxtcbcomp12svn\":0,\"sgxtcbcomp13svn\":0,\"sgxtcbcomp14svn\":0,\"sgxtcbcomp15svn\":0,\"sgxtcbcomp16svn\":0,\"pcesvn\":7},\"tcbDate\":\"2019-01-09T00:00:00Z\",\"tcbStatus\":\"OutOfDate\"},{\"tcb\":{\"sgxtcbcomp01svn\":1,\"sgxtcbcomp02svn\":1,\"sgxtcbcomp03svn\":2,\"sgxtcbcomp04svn\":4,\"sgxtcbcomp05svn\":1,\"sgxtcbcomp06svn\":128,\"sgxtcbcomp07svn\":0,\"sgxtcbcomp08svn\":0,\"sgxtcbcomp09svn\":0,\"sgxtcbcomp10svn\":0,\"sgxtcbcomp11svn\":0,\"sgxtcbcomp12svn\":0,\"sgxtcbcomp13svn\":0,\"sgxtcbcomp14svn\":0,\"sgxtcbcomp15svn\":0,\"sgxtcbcomp16svn\":0,\"pcesvn\":6},\"tcbDate\":\"2018-08-15T00:00:00Z\",\"tcbStatus\":\"OutOfDate\"}]},\"signature\":\"fd7fe639c792132bce84469fb9a95648657c4f72c45b71f753b06c2597d09fd01fd8f2619f15f1faf1b1136d9fa5c7f2bb92252730a441090515dbefd60cc4e4\"}" +} \ No newline at end of file diff --git a/crates/intel-dcap-api/tests/test_data/tdx_qe_identity.json b/crates/intel-dcap-api/tests/test_data/tdx_qe_identity.json new file mode 100644 index 0000000..7a77ea3 --- /dev/null +++ b/crates/intel-dcap-api/tests/test_data/tdx_qe_identity.json @@ -0,0 +1,4 @@ +{ + "enclave_identity_json": "{\"enclaveIdentity\":{\"id\":\"TD_QE\",\"version\":2,\"issueDate\":\"2025-05-27T19:22:46Z\",\"nextUpdate\":\"2025-06-26T19:22:46Z\",\"tcbEvaluationDataNumber\":17,\"miscselect\":\"00000000\",\"miscselectMask\":\"FFFFFFFF\",\"attributes\":\"11000000000000000000000000000000\",\"attributesMask\":\"FBFFFFFFFFFFFFFF0000000000000000\",\"mrsigner\":\"DC9E2A7C6F948F17474E34A7FC43ED030F7C1563F1BABDDF6340C82E0E54A8C5\",\"isvprodid\":2,\"tcbLevels\":[{\"tcb\":{\"isvsvn\":4},\"tcbDate\":\"2024-03-13T00:00:00Z\",\"tcbStatus\":\"UpToDate\"}]},\"signature\":\"cba4e80e12e114ac591bcf43c155cabb2f48bc6e629dce6d5aab26127c7c23b1a3eafc52f60bab7ac39aff2866431494315fd553fa73d9688a802383eea4edc9\"}", + "issuer_chain": "-----BEGIN CERTIFICATE-----\nMIICjTCCAjKgAwIBAgIUfjiC1ftVKUpASY5FhAPpFJG99FUwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTI1MDUwNjA5MjUwMFoXDTMyMDUwNjA5MjUwMFowbDEeMBwG\nA1UEAwwVSW50ZWwgU0dYIFRDQiBTaWduaW5nMRowGAYDVQQKDBFJbnRlbCBDb3Jw\nb3JhdGlvbjEUMBIGA1UEBwwLU2FudGEgQ2xhcmExCzAJBgNVBAgMAkNBMQswCQYD\nVQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABENFG8xzydWRfK92bmGv\nP+mAh91PEyV7Jh6FGJd5ndE9aBH7R3E4A7ubrlh/zN3C4xvpoouGlirMba+W2lju\nypajgbUwgbIwHwYDVR0jBBgwFoAUImUM1lqdNInzg7SVUr9QGzknBqwwUgYDVR0f\nBEswSTBHoEWgQ4ZBaHR0cHM6Ly9jZXJ0aWZpY2F0ZXMudHJ1c3RlZHNlcnZpY2Vz\nLmludGVsLmNvbS9JbnRlbFNHWFJvb3RDQS5kZXIwHQYDVR0OBBYEFH44gtX7VSlK\nQEmORYQD6RSRvfRVMA4GA1UdDwEB/wQEAwIGwDAMBgNVHRMBAf8EAjAAMAoGCCqG\nSM49BAMCA0kAMEYCIQDdmmRuAo3qCO8TC1IoJMITAoOEw4dlgEBHzSz1TuMSTAIh\nAKVTqOkt59+co0O3m3hC+v5Fb00FjYWcgeu3EijOULo5\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIICjzCCAjSgAwIBAgIUImUM1lqdNInzg7SVUr9QGzknBqwwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTE4MDUyMTEwNDUxMFoXDTQ5MTIzMTIzNTk1OVowaDEaMBgG\nA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENvcnBvcmF0\naW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJBgNVBAYT\nAlVTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEC6nEwMDIYZOj/iPWsCzaEKi7\n1OiOSLRFhWGjbnBVJfVnkY4u3IjkDYYL0MxO4mqsyYjlBalTVYxFP2sJBK5zlKOB\nuzCBuDAfBgNVHSMEGDAWgBQiZQzWWp00ifODtJVSv1AbOScGrDBSBgNVHR8ESzBJ\nMEegRaBDhkFodHRwczovL2NlcnRpZmljYXRlcy50cnVzdGVkc2VydmljZXMuaW50\nZWwuY29tL0ludGVsU0dYUm9vdENBLmRlcjAdBgNVHQ4EFgQUImUM1lqdNInzg7SV\nUr9QGzknBqwwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwCgYI\nKoZIzj0EAwIDSQAwRgIhAOW/5QkR+S9CiSDcNoowLuPRLsWGf/Yi7GSX94BgwTwg\nAiEA4J0lrHoMs+Xo5o/sX6O9QWxHRAvZUGOdRQ7cvqRXaqI=\n-----END CERTIFICATE-----\n" +} \ No newline at end of file diff --git a/crates/intel-dcap-api/tests/test_data/tdx_tcb_eval_nums.json b/crates/intel-dcap-api/tests/test_data/tdx_tcb_eval_nums.json new file mode 100644 index 0000000..545318e --- /dev/null +++ b/crates/intel-dcap-api/tests/test_data/tdx_tcb_eval_nums.json @@ -0,0 +1,4 @@ +{ + "issuer_chain": "-----BEGIN CERTIFICATE-----\nMIICjTCCAjKgAwIBAgIUfjiC1ftVKUpASY5FhAPpFJG99FUwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTI1MDUwNjA5MjUwMFoXDTMyMDUwNjA5MjUwMFowbDEeMBwG\nA1UEAwwVSW50ZWwgU0dYIFRDQiBTaWduaW5nMRowGAYDVQQKDBFJbnRlbCBDb3Jw\nb3JhdGlvbjEUMBIGA1UEBwwLU2FudGEgQ2xhcmExCzAJBgNVBAgMAkNBMQswCQYD\nVQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABENFG8xzydWRfK92bmGv\nP+mAh91PEyV7Jh6FGJd5ndE9aBH7R3E4A7ubrlh/zN3C4xvpoouGlirMba+W2lju\nypajgbUwgbIwHwYDVR0jBBgwFoAUImUM1lqdNInzg7SVUr9QGzknBqwwUgYDVR0f\nBEswSTBHoEWgQ4ZBaHR0cHM6Ly9jZXJ0aWZpY2F0ZXMudHJ1c3RlZHNlcnZpY2Vz\nLmludGVsLmNvbS9JbnRlbFNHWFJvb3RDQS5kZXIwHQYDVR0OBBYEFH44gtX7VSlK\nQEmORYQD6RSRvfRVMA4GA1UdDwEB/wQEAwIGwDAMBgNVHRMBAf8EAjAAMAoGCCqG\nSM49BAMCA0kAMEYCIQDdmmRuAo3qCO8TC1IoJMITAoOEw4dlgEBHzSz1TuMSTAIh\nAKVTqOkt59+co0O3m3hC+v5Fb00FjYWcgeu3EijOULo5\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIICjzCCAjSgAwIBAgIUImUM1lqdNInzg7SVUr9QGzknBqwwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTE4MDUyMTEwNDUxMFoXDTQ5MTIzMTIzNTk1OVowaDEaMBgG\nA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENvcnBvcmF0\naW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJBgNVBAYT\nAlVTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEC6nEwMDIYZOj/iPWsCzaEKi7\n1OiOSLRFhWGjbnBVJfVnkY4u3IjkDYYL0MxO4mqsyYjlBalTVYxFP2sJBK5zlKOB\nuzCBuDAfBgNVHSMEGDAWgBQiZQzWWp00ifODtJVSv1AbOScGrDBSBgNVHR8ESzBJ\nMEegRaBDhkFodHRwczovL2NlcnRpZmljYXRlcy50cnVzdGVkc2VydmljZXMuaW50\nZWwuY29tL0ludGVsU0dYUm9vdENBLmRlcjAdBgNVHQ4EFgQUImUM1lqdNInzg7SV\nUr9QGzknBqwwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwCgYI\nKoZIzj0EAwIDSQAwRgIhAOW/5QkR+S9CiSDcNoowLuPRLsWGf/Yi7GSX94BgwTwg\nAiEA4J0lrHoMs+Xo5o/sX6O9QWxHRAvZUGOdRQ7cvqRXaqI=\n-----END CERTIFICATE-----\n", + "tcb_evaluation_data_numbers_json": "{\"tcbEvaluationDataNumbers\":{\"id\":\"TDX\",\"version\":1,\"issueDate\":\"2025-05-27T18:50:21Z\",\"nextUpdate\":\"2025-06-26T18:50:21Z\",\"tcbEvalNumbers\":[{\"tcbEvaluationDataNumber\":19,\"tcbRecoveryEventDate\":\"2025-05-13T00:00:00Z\",\"tcbDate\":\"2025-05-14T00:00:00Z\"},{\"tcbEvaluationDataNumber\":18,\"tcbRecoveryEventDate\":\"2024-11-12T00:00:00Z\",\"tcbDate\":\"2024-11-13T00:00:00Z\"},{\"tcbEvaluationDataNumber\":17,\"tcbRecoveryEventDate\":\"2024-03-12T00:00:00Z\",\"tcbDate\":\"2024-03-13T00:00:00Z\"}]},\"signature\":\"507f5f4406a15e9fa311142b41c47da082d10ce35e863491061c49adac188a2e974561b134a7eff9e10f98be2c5bd5e28c18e3dc6327067fd1a5459d48cd1e58\"}" +} \ No newline at end of file diff --git a/crates/intel-dcap-api/tests/test_data/tdx_tcb_info.json b/crates/intel-dcap-api/tests/test_data/tdx_tcb_info.json new file mode 100644 index 0000000..c2e4b43 --- /dev/null +++ b/crates/intel-dcap-api/tests/test_data/tdx_tcb_info.json @@ -0,0 +1,4 @@ +{ + "issuer_chain": "-----BEGIN CERTIFICATE-----\nMIICjTCCAjKgAwIBAgIUfjiC1ftVKUpASY5FhAPpFJG99FUwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTI1MDUwNjA5MjUwMFoXDTMyMDUwNjA5MjUwMFowbDEeMBwG\nA1UEAwwVSW50ZWwgU0dYIFRDQiBTaWduaW5nMRowGAYDVQQKDBFJbnRlbCBDb3Jw\nb3JhdGlvbjEUMBIGA1UEBwwLU2FudGEgQ2xhcmExCzAJBgNVBAgMAkNBMQswCQYD\nVQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABENFG8xzydWRfK92bmGv\nP+mAh91PEyV7Jh6FGJd5ndE9aBH7R3E4A7ubrlh/zN3C4xvpoouGlirMba+W2lju\nypajgbUwgbIwHwYDVR0jBBgwFoAUImUM1lqdNInzg7SVUr9QGzknBqwwUgYDVR0f\nBEswSTBHoEWgQ4ZBaHR0cHM6Ly9jZXJ0aWZpY2F0ZXMudHJ1c3RlZHNlcnZpY2Vz\nLmludGVsLmNvbS9JbnRlbFNHWFJvb3RDQS5kZXIwHQYDVR0OBBYEFH44gtX7VSlK\nQEmORYQD6RSRvfRVMA4GA1UdDwEB/wQEAwIGwDAMBgNVHRMBAf8EAjAAMAoGCCqG\nSM49BAMCA0kAMEYCIQDdmmRuAo3qCO8TC1IoJMITAoOEw4dlgEBHzSz1TuMSTAIh\nAKVTqOkt59+co0O3m3hC+v5Fb00FjYWcgeu3EijOULo5\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIICjzCCAjSgAwIBAgIUImUM1lqdNInzg7SVUr9QGzknBqwwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTE4MDUyMTEwNDUxMFoXDTQ5MTIzMTIzNTk1OVowaDEaMBgG\nA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENvcnBvcmF0\naW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJBgNVBAYT\nAlVTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEC6nEwMDIYZOj/iPWsCzaEKi7\n1OiOSLRFhWGjbnBVJfVnkY4u3IjkDYYL0MxO4mqsyYjlBalTVYxFP2sJBK5zlKOB\nuzCBuDAfBgNVHSMEGDAWgBQiZQzWWp00ifODtJVSv1AbOScGrDBSBgNVHR8ESzBJ\nMEegRaBDhkFodHRwczovL2NlcnRpZmljYXRlcy50cnVzdGVkc2VydmljZXMuaW50\nZWwuY29tL0ludGVsU0dYUm9vdENBLmRlcjAdBgNVHQ4EFgQUImUM1lqdNInzg7SV\nUr9QGzknBqwwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwCgYI\nKoZIzj0EAwIDSQAwRgIhAOW/5QkR+S9CiSDcNoowLuPRLsWGf/Yi7GSX94BgwTwg\nAiEA4J0lrHoMs+Xo5o/sX6O9QWxHRAvZUGOdRQ7cvqRXaqI=\n-----END CERTIFICATE-----\n", + "tcb_info_json": "{\"tcbInfo\":{\"id\":\"TDX\",\"version\":3,\"issueDate\":\"2025-05-27T19:31:43Z\",\"nextUpdate\":\"2025-06-26T19:31:43Z\",\"fmspc\":\"00806F050000\",\"pceId\":\"0000\",\"tcbType\":0,\"tcbEvaluationDataNumber\":17,\"tdxModule\":{\"mrsigner\":\"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"attributes\":\"0000000000000000\",\"attributesMask\":\"FFFFFFFFFFFFFFFF\"},\"tdxModuleIdentities\":[{\"id\":\"TDX_03\",\"mrsigner\":\"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"attributes\":\"0000000000000000\",\"attributesMask\":\"FFFFFFFFFFFFFFFF\",\"tcbLevels\":[{\"tcb\":{\"isvsvn\":3},\"tcbDate\":\"2024-03-13T00:00:00Z\",\"tcbStatus\":\"UpToDate\"}]},{\"id\":\"TDX_01\",\"mrsigner\":\"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"attributes\":\"0000000000000000\",\"attributesMask\":\"FFFFFFFFFFFFFFFF\",\"tcbLevels\":[{\"tcb\":{\"isvsvn\":4},\"tcbDate\":\"2024-03-13T00:00:00Z\",\"tcbStatus\":\"UpToDate\"},{\"tcb\":{\"isvsvn\":2},\"tcbDate\":\"2023-08-09T00:00:00Z\",\"tcbStatus\":\"OutOfDate\"}]}],\"tcbLevels\":[{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":7,\"category\":\"BIOS\",\"type\":\"Early Microcode Update\"},{\"svn\":7,\"category\":\"OS/VMM\",\"type\":\"SGX Late Microcode Update\"},{\"svn\":2,\"category\":\"OS/VMM\",\"type\":\"TXT SINIT\"},{\"svn\":2,\"category\":\"BIOS\"},{\"svn\":3,\"category\":\"BIOS\"},{\"svn\":1,\"category\":\"BIOS\"},{\"svn\":0},{\"svn\":3,\"category\":\"OS/VMM\",\"type\":\"SEAMLDR ACM\"},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":11,\"tdxtcbcomponents\":[{\"svn\":5,\"category\":\"OS/VMM\",\"type\":\"TDX Module\"},{\"svn\":0,\"category\":\"OS/VMM\",\"type\":\"TDX Module\"},{\"svn\":7,\"category\":\"OS/VMM\",\"type\":\"TDX Late Microcode Update\"},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}]},\"tcbDate\":\"2024-03-13T00:00:00Z\",\"tcbStatus\":\"UpToDate\"},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":6,\"category\":\"BIOS\",\"type\":\"Early Microcode Update\"},{\"svn\":6,\"category\":\"OS/VMM\",\"type\":\"SGX Late Microcode Update\"},{\"svn\":2,\"category\":\"OS/VMM\",\"type\":\"TXT SINIT\"},{\"svn\":2,\"category\":\"BIOS\"},{\"svn\":3,\"category\":\"BIOS\"},{\"svn\":1,\"category\":\"BIOS\"},{\"svn\":0},{\"svn\":3,\"category\":\"OS/VMM\",\"type\":\"SEAMLDR ACM\"},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":11,\"tdxtcbcomponents\":[{\"svn\":3,\"category\":\"OS/VMM\",\"type\":\"TDX Module\"},{\"svn\":0,\"category\":\"OS/VMM\",\"type\":\"TDX Module\"},{\"svn\":6,\"category\":\"OS/VMM\",\"type\":\"TDX Late Microcode Update\"},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}]},\"tcbDate\":\"2023-08-09T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00960\",\"INTEL-SA-00982\",\"INTEL-SA-00986\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":5,\"category\":\"BIOS\",\"type\":\"Early Microcode Update\"},{\"svn\":5,\"category\":\"OS/VMM\",\"type\":\"SGX Late Microcode Update\"},{\"svn\":2,\"category\":\"OS/VMM\",\"type\":\"TXT SINIT\"},{\"svn\":2,\"category\":\"BIOS\"},{\"svn\":3,\"category\":\"BIOS\"},{\"svn\":1,\"category\":\"BIOS\"},{\"svn\":0},{\"svn\":3,\"category\":\"OS/VMM\",\"type\":\"SEAMLDR ACM\"},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":11,\"tdxtcbcomponents\":[{\"svn\":3,\"category\":\"OS/VMM\",\"type\":\"TDX Module\"},{\"svn\":0,\"category\":\"OS/VMM\",\"type\":\"TDX Module\"},{\"svn\":5,\"category\":\"OS/VMM\",\"type\":\"TDX Late Microcode Update\"},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}]},\"tcbDate\":\"2023-02-15T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00837\",\"INTEL-SA-00960\",\"INTEL-SA-00982\",\"INTEL-SA-00986\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":5,\"category\":\"BIOS\",\"type\":\"Early Microcode Update\"},{\"svn\":5,\"category\":\"OS/VMM\",\"type\":\"SGX Late Microcode Update\"},{\"svn\":2,\"category\":\"OS/VMM\",\"type\":\"TXT SINIT\"},{\"svn\":2,\"category\":\"BIOS\"},{\"svn\":3,\"category\":\"BIOS\"},{\"svn\":1,\"category\":\"BIOS\"},{\"svn\":0},{\"svn\":3,\"category\":\"OS/VMM\",\"type\":\"SEAMLDR ACM\"},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":5,\"tdxtcbcomponents\":[{\"svn\":3,\"category\":\"OS/VMM\",\"type\":\"TDX Module\"},{\"svn\":0,\"category\":\"OS/VMM\",\"type\":\"TDX Module\"},{\"svn\":5,\"category\":\"OS/VMM\",\"type\":\"TDX Late Microcode Update\"},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}]},\"tcbDate\":\"2018-01-04T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00106\",\"INTEL-SA-00115\",\"INTEL-SA-00135\",\"INTEL-SA-00203\",\"INTEL-SA-00220\",\"INTEL-SA-00233\",\"INTEL-SA-00270\",\"INTEL-SA-00293\",\"INTEL-SA-00320\",\"INTEL-SA-00329\",\"INTEL-SA-00381\",\"INTEL-SA-00389\",\"INTEL-SA-00477\",\"INTEL-SA-00837\",\"INTEL-SA-00960\",\"INTEL-SA-00982\",\"INTEL-SA-00986\"]}]},\"signature\":\"4eb9de091235241a82cdede1eea6ba1e7df3e158e58591ae2b743ff9fc8ab3774bbb68758da9d588486f84df74b00c10081fb49b7aafee980c70a8f54e28b4f2\"}" +} \ No newline at end of file diff --git a/crates/intel-dcap-api/tests/test_data/tdx_tcb_info_00806F050000.json b/crates/intel-dcap-api/tests/test_data/tdx_tcb_info_00806F050000.json new file mode 100644 index 0000000..c313dc4 --- /dev/null +++ b/crates/intel-dcap-api/tests/test_data/tdx_tcb_info_00806F050000.json @@ -0,0 +1,4 @@ +{ + "issuer_chain": "-----BEGIN CERTIFICATE-----\nMIICjTCCAjKgAwIBAgIUfjiC1ftVKUpASY5FhAPpFJG99FUwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTI1MDUwNjA5MjUwMFoXDTMyMDUwNjA5MjUwMFowbDEeMBwG\nA1UEAwwVSW50ZWwgU0dYIFRDQiBTaWduaW5nMRowGAYDVQQKDBFJbnRlbCBDb3Jw\nb3JhdGlvbjEUMBIGA1UEBwwLU2FudGEgQ2xhcmExCzAJBgNVBAgMAkNBMQswCQYD\nVQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABENFG8xzydWRfK92bmGv\nP+mAh91PEyV7Jh6FGJd5ndE9aBH7R3E4A7ubrlh/zN3C4xvpoouGlirMba+W2lju\nypajgbUwgbIwHwYDVR0jBBgwFoAUImUM1lqdNInzg7SVUr9QGzknBqwwUgYDVR0f\nBEswSTBHoEWgQ4ZBaHR0cHM6Ly9jZXJ0aWZpY2F0ZXMudHJ1c3RlZHNlcnZpY2Vz\nLmludGVsLmNvbS9JbnRlbFNHWFJvb3RDQS5kZXIwHQYDVR0OBBYEFH44gtX7VSlK\nQEmORYQD6RSRvfRVMA4GA1UdDwEB/wQEAwIGwDAMBgNVHRMBAf8EAjAAMAoGCCqG\nSM49BAMCA0kAMEYCIQDdmmRuAo3qCO8TC1IoJMITAoOEw4dlgEBHzSz1TuMSTAIh\nAKVTqOkt59+co0O3m3hC+v5Fb00FjYWcgeu3EijOULo5\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIICjzCCAjSgAwIBAgIUImUM1lqdNInzg7SVUr9QGzknBqwwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTE4MDUyMTEwNDUxMFoXDTQ5MTIzMTIzNTk1OVowaDEaMBgG\nA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENvcnBvcmF0\naW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJBgNVBAYT\nAlVTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEC6nEwMDIYZOj/iPWsCzaEKi7\n1OiOSLRFhWGjbnBVJfVnkY4u3IjkDYYL0MxO4mqsyYjlBalTVYxFP2sJBK5zlKOB\nuzCBuDAfBgNVHSMEGDAWgBQiZQzWWp00ifODtJVSv1AbOScGrDBSBgNVHR8ESzBJ\nMEegRaBDhkFodHRwczovL2NlcnRpZmljYXRlcy50cnVzdGVkc2VydmljZXMuaW50\nZWwuY29tL0ludGVsU0dYUm9vdENBLmRlcjAdBgNVHQ4EFgQUImUM1lqdNInzg7SV\nUr9QGzknBqwwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwCgYI\nKoZIzj0EAwIDSQAwRgIhAOW/5QkR+S9CiSDcNoowLuPRLsWGf/Yi7GSX94BgwTwg\nAiEA4J0lrHoMs+Xo5o/sX6O9QWxHRAvZUGOdRQ7cvqRXaqI=\n-----END CERTIFICATE-----\n", + "tcb_info_json": "{\"tcbInfo\":{\"id\":\"TDX\",\"version\":3,\"issueDate\":\"2025-05-27T19:25:02Z\",\"nextUpdate\":\"2025-06-26T19:25:02Z\",\"fmspc\":\"00806F050000\",\"pceId\":\"0000\",\"tcbType\":0,\"tcbEvaluationDataNumber\":17,\"tdxModule\":{\"mrsigner\":\"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"attributes\":\"0000000000000000\",\"attributesMask\":\"FFFFFFFFFFFFFFFF\"},\"tdxModuleIdentities\":[{\"id\":\"TDX_03\",\"mrsigner\":\"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"attributes\":\"0000000000000000\",\"attributesMask\":\"FFFFFFFFFFFFFFFF\",\"tcbLevels\":[{\"tcb\":{\"isvsvn\":3},\"tcbDate\":\"2024-03-13T00:00:00Z\",\"tcbStatus\":\"UpToDate\"}]},{\"id\":\"TDX_01\",\"mrsigner\":\"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"attributes\":\"0000000000000000\",\"attributesMask\":\"FFFFFFFFFFFFFFFF\",\"tcbLevels\":[{\"tcb\":{\"isvsvn\":4},\"tcbDate\":\"2024-03-13T00:00:00Z\",\"tcbStatus\":\"UpToDate\"},{\"tcb\":{\"isvsvn\":2},\"tcbDate\":\"2023-08-09T00:00:00Z\",\"tcbStatus\":\"OutOfDate\"}]}],\"tcbLevels\":[{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":7,\"category\":\"BIOS\",\"type\":\"Early Microcode Update\"},{\"svn\":7,\"category\":\"OS/VMM\",\"type\":\"SGX Late Microcode Update\"},{\"svn\":2,\"category\":\"OS/VMM\",\"type\":\"TXT SINIT\"},{\"svn\":2,\"category\":\"BIOS\"},{\"svn\":3,\"category\":\"BIOS\"},{\"svn\":1,\"category\":\"BIOS\"},{\"svn\":0},{\"svn\":3,\"category\":\"OS/VMM\",\"type\":\"SEAMLDR ACM\"},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":11,\"tdxtcbcomponents\":[{\"svn\":5,\"category\":\"OS/VMM\",\"type\":\"TDX Module\"},{\"svn\":0,\"category\":\"OS/VMM\",\"type\":\"TDX Module\"},{\"svn\":7,\"category\":\"OS/VMM\",\"type\":\"TDX Late Microcode Update\"},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}]},\"tcbDate\":\"2024-03-13T00:00:00Z\",\"tcbStatus\":\"UpToDate\"},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":6,\"category\":\"BIOS\",\"type\":\"Early Microcode Update\"},{\"svn\":6,\"category\":\"OS/VMM\",\"type\":\"SGX Late Microcode Update\"},{\"svn\":2,\"category\":\"OS/VMM\",\"type\":\"TXT SINIT\"},{\"svn\":2,\"category\":\"BIOS\"},{\"svn\":3,\"category\":\"BIOS\"},{\"svn\":1,\"category\":\"BIOS\"},{\"svn\":0},{\"svn\":3,\"category\":\"OS/VMM\",\"type\":\"SEAMLDR ACM\"},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":11,\"tdxtcbcomponents\":[{\"svn\":3,\"category\":\"OS/VMM\",\"type\":\"TDX Module\"},{\"svn\":0,\"category\":\"OS/VMM\",\"type\":\"TDX Module\"},{\"svn\":6,\"category\":\"OS/VMM\",\"type\":\"TDX Late Microcode Update\"},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}]},\"tcbDate\":\"2023-08-09T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00960\",\"INTEL-SA-00982\",\"INTEL-SA-00986\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":5,\"category\":\"BIOS\",\"type\":\"Early Microcode Update\"},{\"svn\":5,\"category\":\"OS/VMM\",\"type\":\"SGX Late Microcode Update\"},{\"svn\":2,\"category\":\"OS/VMM\",\"type\":\"TXT SINIT\"},{\"svn\":2,\"category\":\"BIOS\"},{\"svn\":3,\"category\":\"BIOS\"},{\"svn\":1,\"category\":\"BIOS\"},{\"svn\":0},{\"svn\":3,\"category\":\"OS/VMM\",\"type\":\"SEAMLDR ACM\"},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":11,\"tdxtcbcomponents\":[{\"svn\":3,\"category\":\"OS/VMM\",\"type\":\"TDX Module\"},{\"svn\":0,\"category\":\"OS/VMM\",\"type\":\"TDX Module\"},{\"svn\":5,\"category\":\"OS/VMM\",\"type\":\"TDX Late Microcode Update\"},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}]},\"tcbDate\":\"2023-02-15T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00837\",\"INTEL-SA-00960\",\"INTEL-SA-00982\",\"INTEL-SA-00986\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":5,\"category\":\"BIOS\",\"type\":\"Early Microcode Update\"},{\"svn\":5,\"category\":\"OS/VMM\",\"type\":\"SGX Late Microcode Update\"},{\"svn\":2,\"category\":\"OS/VMM\",\"type\":\"TXT SINIT\"},{\"svn\":2,\"category\":\"BIOS\"},{\"svn\":3,\"category\":\"BIOS\"},{\"svn\":1,\"category\":\"BIOS\"},{\"svn\":0},{\"svn\":3,\"category\":\"OS/VMM\",\"type\":\"SEAMLDR ACM\"},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":5,\"tdxtcbcomponents\":[{\"svn\":3,\"category\":\"OS/VMM\",\"type\":\"TDX Module\"},{\"svn\":0,\"category\":\"OS/VMM\",\"type\":\"TDX Module\"},{\"svn\":5,\"category\":\"OS/VMM\",\"type\":\"TDX Late Microcode Update\"},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}]},\"tcbDate\":\"2018-01-04T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00106\",\"INTEL-SA-00115\",\"INTEL-SA-00135\",\"INTEL-SA-00203\",\"INTEL-SA-00220\",\"INTEL-SA-00233\",\"INTEL-SA-00270\",\"INTEL-SA-00293\",\"INTEL-SA-00320\",\"INTEL-SA-00329\",\"INTEL-SA-00381\",\"INTEL-SA-00389\",\"INTEL-SA-00477\",\"INTEL-SA-00837\",\"INTEL-SA-00960\",\"INTEL-SA-00982\",\"INTEL-SA-00986\"]}]},\"signature\":\"05d350ab0840b40362419623d36b11e5fcfaebcf0926deb6058232a66a2bbd12e347e8dc5e843d13351714144b3aefd23425f396e15b1a1b7fb673415122b82d\"}" +} \ No newline at end of file diff --git a/crates/intel-dcap-api/tests/test_data/tdx_tcb_info_eval17.json b/crates/intel-dcap-api/tests/test_data/tdx_tcb_info_eval17.json new file mode 100644 index 0000000..927484c --- /dev/null +++ b/crates/intel-dcap-api/tests/test_data/tdx_tcb_info_eval17.json @@ -0,0 +1,4 @@ +{ + "issuer_chain": "-----BEGIN CERTIFICATE-----\nMIICjTCCAjKgAwIBAgIUfjiC1ftVKUpASY5FhAPpFJG99FUwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTI1MDUwNjA5MjUwMFoXDTMyMDUwNjA5MjUwMFowbDEeMBwG\nA1UEAwwVSW50ZWwgU0dYIFRDQiBTaWduaW5nMRowGAYDVQQKDBFJbnRlbCBDb3Jw\nb3JhdGlvbjEUMBIGA1UEBwwLU2FudGEgQ2xhcmExCzAJBgNVBAgMAkNBMQswCQYD\nVQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABENFG8xzydWRfK92bmGv\nP+mAh91PEyV7Jh6FGJd5ndE9aBH7R3E4A7ubrlh/zN3C4xvpoouGlirMba+W2lju\nypajgbUwgbIwHwYDVR0jBBgwFoAUImUM1lqdNInzg7SVUr9QGzknBqwwUgYDVR0f\nBEswSTBHoEWgQ4ZBaHR0cHM6Ly9jZXJ0aWZpY2F0ZXMudHJ1c3RlZHNlcnZpY2Vz\nLmludGVsLmNvbS9JbnRlbFNHWFJvb3RDQS5kZXIwHQYDVR0OBBYEFH44gtX7VSlK\nQEmORYQD6RSRvfRVMA4GA1UdDwEB/wQEAwIGwDAMBgNVHRMBAf8EAjAAMAoGCCqG\nSM49BAMCA0kAMEYCIQDdmmRuAo3qCO8TC1IoJMITAoOEw4dlgEBHzSz1TuMSTAIh\nAKVTqOkt59+co0O3m3hC+v5Fb00FjYWcgeu3EijOULo5\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIICjzCCAjSgAwIBAgIUImUM1lqdNInzg7SVUr9QGzknBqwwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTE4MDUyMTEwNDUxMFoXDTQ5MTIzMTIzNTk1OVowaDEaMBgG\nA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENvcnBvcmF0\naW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJBgNVBAYT\nAlVTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEC6nEwMDIYZOj/iPWsCzaEKi7\n1OiOSLRFhWGjbnBVJfVnkY4u3IjkDYYL0MxO4mqsyYjlBalTVYxFP2sJBK5zlKOB\nuzCBuDAfBgNVHSMEGDAWgBQiZQzWWp00ifODtJVSv1AbOScGrDBSBgNVHR8ESzBJ\nMEegRaBDhkFodHRwczovL2NlcnRpZmljYXRlcy50cnVzdGVkc2VydmljZXMuaW50\nZWwuY29tL0ludGVsU0dYUm9vdENBLmRlcjAdBgNVHQ4EFgQUImUM1lqdNInzg7SV\nUr9QGzknBqwwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwCgYI\nKoZIzj0EAwIDSQAwRgIhAOW/5QkR+S9CiSDcNoowLuPRLsWGf/Yi7GSX94BgwTwg\nAiEA4J0lrHoMs+Xo5o/sX6O9QWxHRAvZUGOdRQ7cvqRXaqI=\n-----END CERTIFICATE-----\n", + "tcb_info_json": "{\"tcbInfo\":{\"id\":\"TDX\",\"version\":3,\"issueDate\":\"2025-05-27T19:31:44Z\",\"nextUpdate\":\"2025-06-26T19:31:44Z\",\"fmspc\":\"00806F050000\",\"pceId\":\"0000\",\"tcbType\":0,\"tcbEvaluationDataNumber\":17,\"tdxModule\":{\"mrsigner\":\"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"attributes\":\"0000000000000000\",\"attributesMask\":\"FFFFFFFFFFFFFFFF\"},\"tdxModuleIdentities\":[{\"id\":\"TDX_03\",\"mrsigner\":\"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"attributes\":\"0000000000000000\",\"attributesMask\":\"FFFFFFFFFFFFFFFF\",\"tcbLevels\":[{\"tcb\":{\"isvsvn\":3},\"tcbDate\":\"2024-03-13T00:00:00Z\",\"tcbStatus\":\"UpToDate\"}]},{\"id\":\"TDX_01\",\"mrsigner\":\"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"attributes\":\"0000000000000000\",\"attributesMask\":\"FFFFFFFFFFFFFFFF\",\"tcbLevels\":[{\"tcb\":{\"isvsvn\":4},\"tcbDate\":\"2024-03-13T00:00:00Z\",\"tcbStatus\":\"UpToDate\"},{\"tcb\":{\"isvsvn\":2},\"tcbDate\":\"2023-08-09T00:00:00Z\",\"tcbStatus\":\"OutOfDate\"}]}],\"tcbLevels\":[{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":7,\"category\":\"BIOS\",\"type\":\"Early Microcode Update\"},{\"svn\":7,\"category\":\"OS/VMM\",\"type\":\"SGX Late Microcode Update\"},{\"svn\":2,\"category\":\"OS/VMM\",\"type\":\"TXT SINIT\"},{\"svn\":2,\"category\":\"BIOS\"},{\"svn\":3,\"category\":\"BIOS\"},{\"svn\":1,\"category\":\"BIOS\"},{\"svn\":0},{\"svn\":3,\"category\":\"OS/VMM\",\"type\":\"SEAMLDR ACM\"},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":11,\"tdxtcbcomponents\":[{\"svn\":5,\"category\":\"OS/VMM\",\"type\":\"TDX Module\"},{\"svn\":0,\"category\":\"OS/VMM\",\"type\":\"TDX Module\"},{\"svn\":7,\"category\":\"OS/VMM\",\"type\":\"TDX Late Microcode Update\"},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}]},\"tcbDate\":\"2024-03-13T00:00:00Z\",\"tcbStatus\":\"UpToDate\"},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":6,\"category\":\"BIOS\",\"type\":\"Early Microcode Update\"},{\"svn\":6,\"category\":\"OS/VMM\",\"type\":\"SGX Late Microcode Update\"},{\"svn\":2,\"category\":\"OS/VMM\",\"type\":\"TXT SINIT\"},{\"svn\":2,\"category\":\"BIOS\"},{\"svn\":3,\"category\":\"BIOS\"},{\"svn\":1,\"category\":\"BIOS\"},{\"svn\":0},{\"svn\":3,\"category\":\"OS/VMM\",\"type\":\"SEAMLDR ACM\"},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":11,\"tdxtcbcomponents\":[{\"svn\":3,\"category\":\"OS/VMM\",\"type\":\"TDX Module\"},{\"svn\":0,\"category\":\"OS/VMM\",\"type\":\"TDX Module\"},{\"svn\":6,\"category\":\"OS/VMM\",\"type\":\"TDX Late Microcode Update\"},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}]},\"tcbDate\":\"2023-08-09T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00960\",\"INTEL-SA-00982\",\"INTEL-SA-00986\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":5,\"category\":\"BIOS\",\"type\":\"Early Microcode Update\"},{\"svn\":5,\"category\":\"OS/VMM\",\"type\":\"SGX Late Microcode Update\"},{\"svn\":2,\"category\":\"OS/VMM\",\"type\":\"TXT SINIT\"},{\"svn\":2,\"category\":\"BIOS\"},{\"svn\":3,\"category\":\"BIOS\"},{\"svn\":1,\"category\":\"BIOS\"},{\"svn\":0},{\"svn\":3,\"category\":\"OS/VMM\",\"type\":\"SEAMLDR ACM\"},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":11,\"tdxtcbcomponents\":[{\"svn\":3,\"category\":\"OS/VMM\",\"type\":\"TDX Module\"},{\"svn\":0,\"category\":\"OS/VMM\",\"type\":\"TDX Module\"},{\"svn\":5,\"category\":\"OS/VMM\",\"type\":\"TDX Late Microcode Update\"},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}]},\"tcbDate\":\"2023-02-15T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00837\",\"INTEL-SA-00960\",\"INTEL-SA-00982\",\"INTEL-SA-00986\"]},{\"tcb\":{\"sgxtcbcomponents\":[{\"svn\":5,\"category\":\"BIOS\",\"type\":\"Early Microcode Update\"},{\"svn\":5,\"category\":\"OS/VMM\",\"type\":\"SGX Late Microcode Update\"},{\"svn\":2,\"category\":\"OS/VMM\",\"type\":\"TXT SINIT\"},{\"svn\":2,\"category\":\"BIOS\"},{\"svn\":3,\"category\":\"BIOS\"},{\"svn\":1,\"category\":\"BIOS\"},{\"svn\":0},{\"svn\":3,\"category\":\"OS/VMM\",\"type\":\"SEAMLDR ACM\"},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}],\"pcesvn\":5,\"tdxtcbcomponents\":[{\"svn\":3,\"category\":\"OS/VMM\",\"type\":\"TDX Module\"},{\"svn\":0,\"category\":\"OS/VMM\",\"type\":\"TDX Module\"},{\"svn\":5,\"category\":\"OS/VMM\",\"type\":\"TDX Late Microcode Update\"},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0},{\"svn\":0}]},\"tcbDate\":\"2018-01-04T00:00:00Z\",\"tcbStatus\":\"OutOfDate\",\"advisoryIDs\":[\"INTEL-SA-00106\",\"INTEL-SA-00115\",\"INTEL-SA-00135\",\"INTEL-SA-00203\",\"INTEL-SA-00220\",\"INTEL-SA-00233\",\"INTEL-SA-00270\",\"INTEL-SA-00293\",\"INTEL-SA-00320\",\"INTEL-SA-00329\",\"INTEL-SA-00381\",\"INTEL-SA-00389\",\"INTEL-SA-00477\",\"INTEL-SA-00837\",\"INTEL-SA-00960\",\"INTEL-SA-00982\",\"INTEL-SA-00986\"]}]},\"signature\":\"1c00c4b83ac0c9abe692b11a59df58604c6d638472822c11d7cb7753a5826be5cb3f8201da78bbaca85429c0e15a51255fc56dcbdd5e913f92e658b0cac377b1\"}" +} \ No newline at end of file diff --git a/packages/teepotCrate/default.nix b/packages/teepotCrate/default.nix index 41263c3..07bad66 100644 --- a/packages/teepotCrate/default.nix +++ b/packages/teepotCrate/default.nix @@ -49,6 +49,7 @@ let # Custom test data files (maybeMissing (inputs.src + "/crates/teepot/tests/data")) (maybeMissing (inputs.src + "/crates/teepot-vault/tests/data")) + (maybeMissing (inputs.src + "/crates/intel-dcap-api/tests/test_data")) ]; }; From bb9c5b195e59a87f656814c0b1acc0e9268f3395 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Wed, 28 May 2025 11:00:03 +0200 Subject: [PATCH 2/3] feat(intel-dcap-api): add automatic retry logic for 429 rate limiting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add `max_retries` field to ApiClient with default of 3 retries - Implement `execute_with_retry()` helper method in helpers.rs - Update all HTTP requests to use retry wrapper for automatic 429 handling - Add `TooManyRequests` error variant with request_id and retry_after fields - Respect Retry-After header duration before retrying requests - Add `set_max_retries()` method to configure retry behavior (0 disables) - Update documentation and add handle_rate_limit example - Enhanced error handling in check_status() for 429 responses The client now transparently handles Intel API rate limiting while remaining configurable for users who need different retry behavior or manual handling. ๐Ÿค– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude Signed-off-by: Harald Hoyer --- crates/intel-dcap-api/CLAUDE.md | 17 +++- .../examples/handle_rate_limit.rs | 91 +++++++++++++++++++ crates/intel-dcap-api/src/client/fmspc.rs | 2 +- crates/intel-dcap-api/src/client/helpers.rs | 75 ++++++++++++++- crates/intel-dcap-api/src/client/mod.rs | 16 ++++ crates/intel-dcap-api/src/client/pck_crl.rs | 2 +- .../intel-dcap-api/src/client/registration.rs | 16 ++-- crates/intel-dcap-api/src/error.rs | 55 +++++++++++ crates/intel-dcap-api/src/lib.rs | 8 ++ 9 files changed, 267 insertions(+), 15 deletions(-) create mode 100644 crates/intel-dcap-api/examples/handle_rate_limit.rs diff --git a/crates/intel-dcap-api/CLAUDE.md b/crates/intel-dcap-api/CLAUDE.md index d2a01b3..851b6ae 100644 --- a/crates/intel-dcap-api/CLAUDE.md +++ b/crates/intel-dcap-api/CLAUDE.md @@ -16,6 +16,7 @@ and enclave identity verification. - Type-safe request/response structures - Support for SGX and TDX platforms - Real data integration tests +- **Automatic rate limit handling with configurable retries** ## Development Commands @@ -36,6 +37,7 @@ cargo run --example get_pck_crl # Fetch certificate revocation lists cargo run --example common_usage # Common attestation verification patterns cargo run --example integration_test # Comprehensive test of most API endpoints cargo run --example fetch_test_data # Fetch real data from Intel API for tests +cargo run --example handle_rate_limit # Demonstrate automatic rate limiting handling ``` ## Architecture @@ -45,6 +47,8 @@ cargo run --example fetch_test_data # Fetch real data from Intel API for tests - **ApiClient** (`src/client/mod.rs`): Main entry point supporting API v3/v4 - Base URL: https://api.trustedservices.intel.com - Manages HTTP client and API version selection + - Automatic retry logic for 429 (Too Many Requests) responses + - Default: 3 retries, configurable via `set_max_retries()` ### Key Modules @@ -69,6 +73,7 @@ cargo run --example fetch_test_data # Fetch real data from Intel API for tests - **error.rs**: `IntelApiError` for comprehensive error handling - Extracts error details from Error-Code and Error-Message headers + - **`TooManyRequests` variant for rate limiting (429) after retry exhaustion** - **types.rs**: Enums (CaType, ApiVersion, UpdateType, etc.) - **requests.rs**: Request structures - **responses.rs**: Response structures with JSON and certificate data @@ -78,10 +83,18 @@ cargo run --example fetch_test_data # Fetch real data from Intel API for tests All client methods follow this pattern: 1. Build request with query parameters -2. Send HTTP request with proper headers +2. Send HTTP request with proper headers (with automatic retry on 429) 3. Parse response (JSON + certificate chains) 4. Return typed response or error +### Rate Limiting & Retry Logic + +- **Automatic Retries**: All HTTP requests automatically retry on 429 (Too Many Requests) responses +- **Retry Configuration**: Default 3 retries, configurable via `ApiClient::set_max_retries()` +- **Retry-After Handling**: Waits for duration specified in Retry-After header before retrying +- **Error Handling**: `IntelApiError::TooManyRequests` returned only after all retries exhausted +- **Implementation**: `execute_with_retry()` in `src/client/helpers.rs` handles retry logic + ### Testing Strategy - **Mock Tests**: Two test suites using mockito for HTTP mocking @@ -114,6 +127,8 @@ All client methods follow this pattern: 1. **Mockito Header Encoding**: Always URL-encode headers containing newlines/special characters 2. **API Version Selection**: Some endpoints are V4-only and will return errors on V3 +3. **Rate Limiting**: Client automatically retries 429 responses; disable with `set_max_retries(0)` if manual handling + needed 4. **Platform Filters**: Only certain values are valid (All, Client, E3, E5) 5. **Test Data**: PCK certificate endpoints require valid platform data and often need subscription keys 6. **Issuer Chain Validation**: Always check that `issuer_chain` is non-empty - it's critical for signature verification diff --git a/crates/intel-dcap-api/examples/handle_rate_limit.rs b/crates/intel-dcap-api/examples/handle_rate_limit.rs new file mode 100644 index 0000000..def5af6 --- /dev/null +++ b/crates/intel-dcap-api/examples/handle_rate_limit.rs @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright (c) 2025 Matter Labs + +//! Example demonstrating automatic rate limit handling +//! +//! The Intel DCAP API client now automatically handles 429 Too Many Requests responses +//! by retrying up to 3 times by default. This example shows how to configure the retry +//! behavior and handle cases where all retries are exhausted. + +use intel_dcap_api::{ApiClient, IntelApiError}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create API client with default settings (3 retries) + let mut client = ApiClient::new()?; + + println!("Example 1: Default behavior (automatic retries)"); + println!("================================================"); + + // Example FMSPC value + let fmspc = "00606A000000"; + + // The client will automatically retry up to 3 times if rate limited + match client.get_sgx_tcb_info(fmspc, None, None).await { + Ok(tcb_info) => { + println!("โœ“ Successfully retrieved TCB info"); + println!( + " TCB Info JSON length: {} bytes", + tcb_info.tcb_info_json.len() + ); + println!( + " Issuer Chain length: {} bytes", + tcb_info.issuer_chain.len() + ); + } + Err(IntelApiError::TooManyRequests { + request_id, + retry_after, + }) => { + println!("โœ— Rate limited even after 3 automatic retries"); + println!(" Request ID: {}", request_id); + println!(" Last retry-after was: {} seconds", retry_after); + } + Err(e) => { + eprintln!("โœ— Other error: {}", e); + } + } + + println!("\nExample 2: Custom retry configuration"); + println!("====================================="); + + // Configure client to retry up to 5 times + client.set_max_retries(5); + println!("Set max retries to 5"); + + match client.get_sgx_tcb_info(fmspc, None, None).await { + Ok(_) => println!("โœ“ Request succeeded"), + Err(IntelApiError::TooManyRequests { .. }) => { + println!("โœ— Still rate limited after 5 retries") + } + Err(e) => eprintln!("โœ— Error: {}", e), + } + + println!("\nExample 3: Disable automatic retries"); + println!("===================================="); + + // Disable automatic retries + client.set_max_retries(0); + println!("Disabled automatic retries"); + + match client.get_sgx_tcb_info(fmspc, None, None).await { + Ok(_) => println!("โœ“ Request succeeded on first attempt"), + Err(IntelApiError::TooManyRequests { + request_id, + retry_after, + }) => { + println!("โœ— Rate limited (no automatic retry)"); + println!(" Request ID: {}", request_id); + println!(" Retry after: {} seconds", retry_after); + println!(" You would need to implement manual retry logic here"); + } + Err(e) => eprintln!("โœ— Error: {}", e), + } + + println!("\nNote: The client handles rate limiting automatically!"); + println!("You only need to handle TooManyRequests errors if:"); + println!("- You disable automatic retries (set_max_retries(0))"); + println!("- All automatic retries are exhausted"); + + Ok(()) +} diff --git a/crates/intel-dcap-api/src/client/fmspc.rs b/crates/intel-dcap-api/src/client/fmspc.rs index 3963f1f..c515ac9 100644 --- a/crates/intel-dcap-api/src/client/fmspc.rs +++ b/crates/intel-dcap-api/src/client/fmspc.rs @@ -46,7 +46,7 @@ impl ApiClient { } let request_builder = self.client.get(url); - let response = request_builder.send().await?; + let response = self.execute_with_retry(request_builder).await?; let response = check_status(response, &[StatusCode::OK]).await?; let fmspcs_json = response.text().await?; diff --git a/crates/intel-dcap-api/src/client/helpers.rs b/crates/intel-dcap-api/src/client/helpers.rs index ee53cc3..ba86545 100644 --- a/crates/intel-dcap-api/src/client/helpers.rs +++ b/crates/intel-dcap-api/src/client/helpers.rs @@ -12,6 +12,8 @@ use crate::{ use percent_encoding::percent_decode_str; use reqwest::{RequestBuilder, Response, StatusCode}; use std::io; +use std::time::Duration; +use tokio::time::sleep; impl ApiClient { /// Helper to construct API paths dynamically based on version and technology (SGX/TDX). @@ -84,7 +86,7 @@ impl ApiClient { &self, request_builder: RequestBuilder, ) -> Result { - let response = request_builder.send().await?; + let response = self.execute_with_retry(request_builder).await?; let response = check_status(response, &[StatusCode::OK]).await?; let issuer_chain = self.get_required_header( @@ -109,7 +111,7 @@ impl ApiClient { &self, request_builder: RequestBuilder, ) -> Result { - let response = request_builder.send().await?; + let response = self.execute_with_retry(request_builder).await?; let response = check_status(response, &[StatusCode::OK]).await?; let issuer_chain = self.get_required_header( @@ -134,7 +136,7 @@ impl ApiClient { v4_issuer_chain_header: &'static str, v3_issuer_chain_header: Option<&'static str>, ) -> Result<(String, String), IntelApiError> { - let response = request_builder.send().await?; + let response = self.execute_with_retry(request_builder).await?; let response = check_status(response, &[StatusCode::OK]).await?; let issuer_chain = @@ -158,7 +160,7 @@ impl ApiClient { )) })?; - let response = builder_clone.send().await?; + let response = self.execute_with_retry(builder_clone).await?; let status = response.status(); if status == StatusCode::NOT_FOUND || status == StatusCode::GONE { @@ -224,4 +226,69 @@ impl ApiClient { Ok(()) } } + + /// Executes a request with automatic retry logic for rate limiting (429 responses). + /// + /// This method will automatically retry the request up to `max_retries` times + /// when receiving a 429 Too Many Requests response, waiting for the duration + /// specified in the Retry-After header. + pub(super) async fn execute_with_retry( + &self, + request_builder: RequestBuilder, + ) -> Result { + let mut retries = 0; + + loop { + // Clone the request builder for retry attempts + let builder = request_builder.try_clone().ok_or_else(|| { + IntelApiError::Io(io::Error::new( + io::ErrorKind::Other, + "Failed to clone request builder for retry", + )) + })?; + + let response = builder.send().await?; + let status = response.status(); + + if status != StatusCode::TOO_MANY_REQUESTS { + // Not a rate limit error, return the response + return Ok(response); + } + + // Handle 429 Too Many Requests + if retries >= self.max_retries { + // No more retries, return the error + let request_id = response + .headers() + .get("Request-ID") + .and_then(|v| v.to_str().ok()) + .unwrap_or("Unknown") + .to_string(); + + let retry_after = response + .headers() + .get("Retry-After") + .and_then(|v| v.to_str().ok()) + .and_then(|v| v.parse::().ok()) + .unwrap_or(60); + + return Err(IntelApiError::TooManyRequests { + request_id, + retry_after, + }); + } + + // Parse Retry-After header + let retry_after_secs = response + .headers() + .get("Retry-After") + .and_then(|v| v.to_str().ok()) + .and_then(|v| v.parse::().ok()) + .unwrap_or(60); // Default to 60 seconds + + // Wait before retrying + sleep(Duration::from_secs(retry_after_secs)).await; + retries += 1; + } + } } diff --git a/crates/intel-dcap-api/src/client/mod.rs b/crates/intel-dcap-api/src/client/mod.rs index d2d618d..3e71d5d 100644 --- a/crates/intel-dcap-api/src/client/mod.rs +++ b/crates/intel-dcap-api/src/client/mod.rs @@ -45,6 +45,8 @@ pub struct ApiClient { client: Client, base_url: Url, api_version: ApiVersion, + /// Maximum number of automatic retries for rate-limited requests (429 responses) + max_retries: u32, } impl ApiClient { @@ -114,6 +116,20 @@ impl ApiClient { .build()?, base_url: base_url.into_url()?, api_version, + max_retries: 3, // Default to 3 retries }) } + + /// Sets the maximum number of automatic retries for rate-limited requests. + /// + /// When the API returns a 429 (Too Many Requests) response, the client will + /// automatically wait for the duration specified in the Retry-After header + /// and retry the request up to this many times. + /// + /// # Arguments + /// + /// * `max_retries` - Maximum number of retries (0 disables automatic retries) + pub fn set_max_retries(&mut self, max_retries: u32) { + self.max_retries = max_retries; + } } diff --git a/crates/intel-dcap-api/src/client/pck_crl.rs b/crates/intel-dcap-api/src/client/pck_crl.rs index 0226b11..d5d0c6e 100644 --- a/crates/intel-dcap-api/src/client/pck_crl.rs +++ b/crates/intel-dcap-api/src/client/pck_crl.rs @@ -49,7 +49,7 @@ impl ApiClient { } let request_builder = self.client.get(url); - let response = request_builder.send().await?; + let response = self.execute_with_retry(request_builder).await?; let response = check_status(response, &[StatusCode::OK]).await?; let issuer_chain = self.get_required_header( diff --git a/crates/intel-dcap-api/src/client/registration.rs b/crates/intel-dcap-api/src/client/registration.rs index 136c8c0..d510649 100644 --- a/crates/intel-dcap-api/src/client/registration.rs +++ b/crates/intel-dcap-api/src/client/registration.rs @@ -36,13 +36,13 @@ impl ApiClient { let path = self.build_api_path("sgx", "registration", "platform")?; let url = self.base_url.join(&path)?; - let response = self + let request_builder = self .client .post(url) .header(header::CONTENT_TYPE, "application/octet-stream") - .body(platform_manifest) - .send() - .await?; + .body(platform_manifest); + + let response = self.execute_with_retry(request_builder).await?; let response = check_status(response, &[StatusCode::CREATED]).await?; @@ -81,14 +81,14 @@ impl ApiClient { let path = self.build_api_path("sgx", "registration", "package")?; let url = self.base_url.join(&path)?; - let response = self + let request_builder = self .client .post(url) .header("Ocp-Apim-Subscription-Key", subscription_key) .header(header::CONTENT_TYPE, "application/octet-stream") - .body(add_package_request) - .send() - .await?; + .body(add_package_request); + + let response = self.execute_with_retry(request_builder).await?; let response = check_status(response, &[StatusCode::OK]).await?; diff --git a/crates/intel-dcap-api/src/error.rs b/crates/intel-dcap-api/src/error.rs index 564bbd2..4e07216 100644 --- a/crates/intel-dcap-api/src/error.rs +++ b/crates/intel-dcap-api/src/error.rs @@ -59,6 +59,40 @@ pub enum IntelApiError { /// Indicates an invalid parameter was provided. #[error("Invalid parameter value: {0}")] InvalidParameter(&'static str), + + /// Indicates that the API rate limit has been exceeded (HTTP 429). + /// + /// This error is returned after the client has exhausted all automatic retry attempts + /// for a rate-limited request. The `retry_after` field contains the number of seconds + /// that was specified in the last Retry-After header. By default, the client automatically + /// retries rate-limited requests up to 3 times. + /// + /// # Example + /// + /// ```rust,no_run + /// use intel_dcap_api::{ApiClient, IntelApiError}; + /// + /// # async fn example() -> Result<(), Box> { + /// let mut client = ApiClient::new()?; + /// client.set_max_retries(0); // Disable automatic retries + /// + /// match client.get_sgx_tcb_info("00606A000000", None, None).await { + /// Ok(tcb_info) => println!("Success"), + /// Err(IntelApiError::TooManyRequests { request_id, retry_after }) => { + /// println!("Rate limited after all retries. Last retry-after was {} seconds.", retry_after); + /// } + /// Err(e) => eprintln!("Other error: {}", e), + /// } + /// # Ok(()) + /// # } + /// ``` + #[error("Too many requests. Retry after {retry_after} seconds")] + TooManyRequests { + /// The unique request identifier for tracing. + request_id: String, + /// Number of seconds to wait before retrying, from Retry-After header. + retry_after: u64, + }, } /// Extracts common API error details from response headers. @@ -92,6 +126,27 @@ pub(crate) async fn check_status( let status = response.status(); if expected_statuses.contains(&status) { Ok(response) + } else if status == StatusCode::TOO_MANY_REQUESTS { + // Handle 429 Too Many Requests with Retry-After header + let request_id = response + .headers() + .get("Request-ID") + .and_then(|v| v.to_str().ok()) + .unwrap_or("Unknown") + .to_string(); + + // Parse Retry-After header (can be in seconds or HTTP date format) + let retry_after = response + .headers() + .get("Retry-After") + .and_then(|v| v.to_str().ok()) + .and_then(|v| v.parse::().ok()) + .unwrap_or(60); // Default to 60 seconds if header is missing or invalid + + Err(IntelApiError::TooManyRequests { + request_id, + retry_after, + }) } else { let (request_id, error_code, error_message) = extract_api_error_details(&response); Err(IntelApiError::ApiError { diff --git a/crates/intel-dcap-api/src/lib.rs b/crates/intel-dcap-api/src/lib.rs index a0d9e20..f6f4ea4 100644 --- a/crates/intel-dcap-api/src/lib.rs +++ b/crates/intel-dcap-api/src/lib.rs @@ -8,6 +8,14 @@ //! //! Create an [`ApiClient`] to interface with the Intel API. //! +//! # Rate Limiting +//! +//! The Intel API implements rate limiting and may return HTTP 429 (Too Many Requests) responses. +//! This client automatically handles rate limiting by retrying requests up to 3 times by default, +//! waiting for the duration specified in the `Retry-After` header. You can configure the retry +//! behavior using [`ApiClient::set_max_retries`]. If all retries are exhausted, the client +//! returns an [`IntelApiError::TooManyRequests`] error. +//! //! Example //! ```rust,no_run //! use intel_dcap_api::{ApiClient, IntelApiError, TcbInfoResponse}; From 7c133c4e4b568a17b798bf0c0c4551969cd76622 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Wed, 28 May 2025 13:31:15 +0200 Subject: [PATCH 3/3] ci(nix): disable sandbox in nix-non-x86 workflow otherwise the mockito tests fail, because it cannot bind to 127.0.0.1 0 - Updated `nix build` command to include `--no-sandbox` flag. --- .github/workflows/nix-non-x86.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nix-non-x86.yml b/.github/workflows/nix-non-x86.yml index 0872032..b80cf6a 100644 --- a/.github/workflows/nix-non-x86.yml +++ b/.github/workflows/nix-non-x86.yml @@ -34,5 +34,5 @@ jobs: # FIXME: this prevents it from running on macos # https://github.com/NixOS/nix/pull/12570 # run: nix run github:nixos/nixpkgs/nixos-24.11#nixci -- build - run: nix build -L .#teepot + run: nix build -L .#teepot --no-sandbox