teepot/crates/intel-dcap-api/src/client/pck_crl.rs
Harald Hoyer bb9c5b195e
feat(intel-dcap-api): add automatic retry logic for 429 rate limiting
- 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 <noreply@anthropic.com>
Signed-off-by: Harald Hoyer <harald@matterlabs.dev>
2025-05-28 11:52:32 +02:00

69 lines
2.2 KiB
Rust

// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2025 Matter Labs
//! PCK Certificate Revocation List
use super::ApiClient; // Import from parent module
use crate::{
error::{check_status, IntelApiError},
responses::PckCrlResponse,
types::{CaType, CrlEncoding},
};
use reqwest::StatusCode;
impl ApiClient {
/// GET /sgx/certification/{v3,v4}/pckcrl
/// Retrieves the PCK Certificate Revocation List (CRL) for a specified CA type.
///
/// Optionally takes an `encoding` parameter indicating whether the CRL should be
/// returned as PEM or DER. Defaults to PEM if not specified.
///
/// # Arguments
///
/// * `ca_type` - The type of CA to retrieve the CRL for (e.g., "processor" or "platform").
/// * `encoding` - An optional [`CrlEncoding`] (PEM or DER).
///
/// # Returns
///
/// A [`PckCrlResponse`] containing the CRL data and the issuer chain.
///
/// # Errors
///
/// Returns an `IntelApiError` if the request fails or if the response status
/// is not `200 OK`.
/// Optional 'encoding' parameter ("pem" or "der").
/// Returns CRL data (PEM or DER) and Issuer Chain header.
pub async fn get_pck_crl(
&self,
ca_type: CaType,
encoding: Option<CrlEncoding>,
) -> Result<PckCrlResponse, IntelApiError> {
let path = self.build_api_path("sgx", "", "pckcrl")?;
let mut url = self.base_url.join(&path)?;
url.query_pairs_mut()
.append_pair("ca", &ca_type.to_string());
if let Some(enc) = encoding {
url.query_pairs_mut()
.append_pair("encoding", &enc.to_string());
}
let request_builder = self.client.get(url);
let response = self.execute_with_retry(request_builder).await?;
let response = check_status(response, &[StatusCode::OK]).await?;
let issuer_chain = self.get_required_header(
&response,
"SGX-PCK-CRL-Issuer-Chain",
Some("SGX-PCK-CRL-Issuer-Chain"),
)?;
// Response body is PEM or DER CRL
let crl_data = response.bytes().await?.to_vec();
Ok(PckCrlResponse {
crl_data,
issuer_chain,
})
}
}