mirror of
https://github.com/matter-labs/teepot.git
synced 2025-07-21 23:23:57 +02:00
feat(api): add Intel DCAP API client module
Introduced a new `intel-dcap-api` crate for interacting with Intel's DCAP APIs. - Implemented various API client functionalities for SGX/TDX attestation services. - Added support for registration, certification, enclave identity, and FMSPC retrieval. Signed-off-by: Harald Hoyer <harald@matterlabs.dev>
This commit is contained in:
parent
93c35dad38
commit
ed84a424db
11 changed files with 1939 additions and 1 deletions
78
crates/intel-dcap-api/examples/example.rs
Normal file
78
crates/intel-dcap-api/examples/example.rs
Normal file
|
@ -0,0 +1,78 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright (c) 2025 Matter Labs
|
||||
|
||||
use intel_dcap_api::{
|
||||
ApiClient, ApiVersion, CaType, CrlEncoding, EnclaveIdentityResponse, IntelApiError,
|
||||
PckCrlResponse, PlatformFilter, TcbInfoResponse,
|
||||
};
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), IntelApiError> {
|
||||
for api_version in [ApiVersion::V3, ApiVersion::V4] {
|
||||
println!("Using API version: {}", api_version);
|
||||
|
||||
let client = ApiClient::new_with_version(api_version)?;
|
||||
|
||||
// Example: Get SGX TCB Info
|
||||
let fmspc_example = "00606A000000"; // Example FMSPC from docs
|
||||
match client.get_sgx_tcb_info(fmspc_example, None, None).await {
|
||||
Ok(TcbInfoResponse {
|
||||
tcb_info_json,
|
||||
issuer_chain,
|
||||
}) => println!(
|
||||
"SGX TCB Info for {}:\n{}\nIssuer Chain: {}",
|
||||
fmspc_example, tcb_info_json, issuer_chain
|
||||
),
|
||||
Err(e) => eprintln!("Error getting SGX TCB info: {}", e),
|
||||
}
|
||||
|
||||
// Example: Get FMSPCs
|
||||
match client.get_fmspcs(Some(PlatformFilter::E3)).await {
|
||||
// Filter for E3 platform type [cite: 230]
|
||||
Ok(fmspc_list) => println!("\nE3 FMSPCs:\n{}", fmspc_list),
|
||||
Err(e) => eprintln!("Error getting FMSPCs: {}", e),
|
||||
}
|
||||
|
||||
// Example: Get SGX QE Identity
|
||||
match client.get_sgx_qe_identity(None, None).await {
|
||||
Ok(EnclaveIdentityResponse {
|
||||
enclave_identity_json,
|
||||
issuer_chain,
|
||||
}) => {
|
||||
println!(
|
||||
"\nSGX QE Identity:\n{}\nIssuer Chain: {}",
|
||||
enclave_identity_json, issuer_chain
|
||||
)
|
||||
}
|
||||
Err(e) => eprintln!("Error getting SGX QE Identity: {}", e),
|
||||
}
|
||||
|
||||
// Example: Get PCK CRL (Platform CA, PEM encoding)
|
||||
match client
|
||||
.get_pck_crl(CaType::Platform, Some(CrlEncoding::Pem))
|
||||
.await
|
||||
{
|
||||
// [cite: 118, 119]
|
||||
Ok(PckCrlResponse {
|
||||
crl_data,
|
||||
issuer_chain,
|
||||
}) => {
|
||||
// Attempt to decode PEM for display, otherwise show byte count
|
||||
match String::from_utf8(crl_data.clone()) {
|
||||
Ok(pem_string) => println!(
|
||||
"\nPlatform PCK CRL (PEM):\n{}\nIssuer Chain: {}",
|
||||
pem_string, issuer_chain
|
||||
),
|
||||
Err(_) => println!(
|
||||
"\nPlatform PCK CRL ({} bytes, likely DER):\nIssuer Chain: {}",
|
||||
crl_data.len(),
|
||||
issuer_chain
|
||||
),
|
||||
}
|
||||
}
|
||||
Err(e) => eprintln!("Error getting PCK CRL: {}", e),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
75
crates/intel-dcap-api/examples/get_pck_crl.rs
Normal file
75
crates/intel-dcap-api/examples/get_pck_crl.rs
Normal file
|
@ -0,0 +1,75 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright (c) 2025 Matter Labs
|
||||
|
||||
use intel_dcap_api::{ApiClient, CaType, CrlEncoding, IntelApiError, PckCrlResponse};
|
||||
use x509_cert::{
|
||||
der::{oid::AssociatedOid, Decode, SliceReader},
|
||||
ext::pkix::{
|
||||
crl::dp::DistributionPoint,
|
||||
name::{DistributionPointName, GeneralName},
|
||||
CrlDistributionPoints,
|
||||
},
|
||||
};
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), IntelApiError> {
|
||||
let client = ApiClient::new()?;
|
||||
|
||||
let PckCrlResponse {
|
||||
crl_data,
|
||||
issuer_chain,
|
||||
} = client
|
||||
.get_pck_crl(CaType::Platform, Some(CrlEncoding::Der))
|
||||
.await?;
|
||||
|
||||
let certs = x509_cert::certificate::CertificateInner::<
|
||||
x509_cert::certificate::Rfc5280
|
||||
>::load_pem_chain(issuer_chain.as_bytes()).map_err(
|
||||
|_| IntelApiError::InvalidParameter("Could not load a PEM chain")
|
||||
)?;
|
||||
|
||||
for cert in certs {
|
||||
println!("Issuer: {}", cert.tbs_certificate.issuer);
|
||||
println!("Subject: {}", cert.tbs_certificate.subject);
|
||||
println!("Serial Number: {}", cert.tbs_certificate.serial_number);
|
||||
println!("Not Before: {}", cert.tbs_certificate.validity.not_before);
|
||||
println!("Not After: {}", cert.tbs_certificate.validity.not_after);
|
||||
|
||||
// Extract and print CRL distribution points
|
||||
if let Some(extensions) = &cert.tbs_certificate.extensions {
|
||||
for ext in extensions.iter() {
|
||||
if ext.extn_id == CrlDistributionPoints::OID {
|
||||
// Create a SliceReader from the byte slice
|
||||
let mut reader = SliceReader::new(ext.extn_value.as_bytes()).map_err(|_| {
|
||||
IntelApiError::InvalidParameter(
|
||||
"Could not create reader from extension value",
|
||||
)
|
||||
})?;
|
||||
|
||||
// Now pass the reader to decode_value
|
||||
if let Ok(dist_points) = Vec::<DistributionPoint>::decode(&mut reader) {
|
||||
for point in dist_points {
|
||||
if let Some(DistributionPointName::FullName(names)) =
|
||||
point.distribution_point
|
||||
{
|
||||
for name in names {
|
||||
if let GeneralName::UniformResourceIdentifier(uri) = name {
|
||||
let uri = uri.as_str();
|
||||
let crl_bytes = reqwest::get(uri).await?.bytes().await?;
|
||||
println!("CRL bytes (hex): {}", hex::encode(&crl_bytes));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
println!("Could not decode CRL distribution points");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println!("CRL bytes (hex): {}", hex::encode(&crl_data));
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue