mirror of
https://github.com/matter-labs/teepot.git
synced 2025-07-21 07:03:56 +02:00
refactor: prefer inline format args
This commit is contained in:
parent
71a04ad4e2
commit
2dea589c0e
18 changed files with 42 additions and 62 deletions
|
@ -61,13 +61,11 @@ pub fn extend_sha384(base: &str, extend: &str) -> Result<String> {
|
||||||
let mut hasher = sha2::Sha384::new();
|
let mut hasher = sha2::Sha384::new();
|
||||||
|
|
||||||
hasher.update(pad::<48>(&hex::decode(base).context(format!(
|
hasher.update(pad::<48>(&hex::decode(base).context(format!(
|
||||||
"Failed to decode base digest '{}' - expected hex string",
|
"Failed to decode base digest '{base}' - expected hex string",
|
||||||
base
|
|
||||||
))?)?);
|
))?)?);
|
||||||
|
|
||||||
hasher.update(pad::<48>(&hex::decode(extend).context(format!(
|
hasher.update(pad::<48>(&hex::decode(extend).context(format!(
|
||||||
"Failed to decode extend digest '{}' - expected hex string",
|
"Failed to decode extend digest '{extend}' - expected hex string",
|
||||||
extend
|
|
||||||
))?)?);
|
))?)?);
|
||||||
|
|
||||||
Ok(hex::encode(hasher.finalize()))
|
Ok(hex::encode(hasher.finalize()))
|
||||||
|
|
|
@ -26,7 +26,7 @@ async fn main() -> Result<()> {
|
||||||
.context("failed to get quote and collateral")?;
|
.context("failed to get quote and collateral")?;
|
||||||
|
|
||||||
let base64_string = general_purpose::STANDARD.encode(report.quote.as_ref());
|
let base64_string = general_purpose::STANDARD.encode(report.quote.as_ref());
|
||||||
print!("{}", base64_string);
|
print!("{base64_string}");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,7 @@ fn print_quote_verification_summary(quote_verification_result: &QuoteVerificatio
|
||||||
for advisory in advisories {
|
for advisory in advisories {
|
||||||
println!("\tInfo: Advisory ID: {advisory}");
|
println!("\tInfo: Advisory ID: {advisory}");
|
||||||
}
|
}
|
||||||
println!("Quote verification result: {}", tcblevel);
|
println!("Quote verification result: {tcblevel}");
|
||||||
|
|
||||||
println!("{:#}", "e.report);
|
println!("{:#}", "e.report);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,12 +26,10 @@ impl MainNodeClient {
|
||||||
/// Create a new client for the main node
|
/// Create a new client for the main node
|
||||||
pub fn new(rpc_url: Url, chain_id: u64) -> error::Result<Self> {
|
pub fn new(rpc_url: Url, chain_id: u64) -> error::Result<Self> {
|
||||||
let chain_id = L2ChainId::try_from(chain_id)
|
let chain_id = L2ChainId::try_from(chain_id)
|
||||||
.map_err(|e| error::Error::Internal(format!("Invalid chain ID: {}", e)))?;
|
.map_err(|e| error::Error::Internal(format!("Invalid chain ID: {e}")))?;
|
||||||
|
|
||||||
let node_client = NodeClient::http(rpc_url.into())
|
let node_client = NodeClient::http(rpc_url.into())
|
||||||
.map_err(|e| {
|
.map_err(|e| error::Error::Internal(format!("Failed to create JSON-RPC client: {e}")))?
|
||||||
error::Error::Internal(format!("Failed to create JSON-RPC client: {}", e))
|
|
||||||
})?
|
|
||||||
.for_network(chain_id.into())
|
.for_network(chain_id.into())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
@ -46,13 +44,13 @@ impl JsonRpcClient for MainNodeClient {
|
||||||
.get_l1_batch_details(batch_number)
|
.get_l1_batch_details(batch_number)
|
||||||
.rpc_context("get_l1_batch_details")
|
.rpc_context("get_l1_batch_details")
|
||||||
.await
|
.await
|
||||||
.map_err(|e| error::Error::JsonRpc(format!("Failed to get batch details: {}", e)))?
|
.map_err(|e| error::Error::JsonRpc(format!("Failed to get batch details: {e}")))?
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
error::Error::JsonRpc(format!("No details found for batch #{}", batch_number))
|
error::Error::JsonRpc(format!("No details found for batch #{batch_number}"))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
batch_details.base.root_hash.ok_or_else(|| {
|
batch_details.base.root_hash.ok_or_else(|| {
|
||||||
error::Error::JsonRpc(format!("No root hash found for batch #{}", batch_number))
|
error::Error::JsonRpc(format!("No root hash found for batch #{batch_number}"))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -190,15 +190,12 @@ impl VerifierConfig {
|
||||||
pub fn new(args: VerifierConfigArgs) -> error::Result<Self> {
|
pub fn new(args: VerifierConfigArgs) -> error::Result<Self> {
|
||||||
let policy = if let Some(path) = &args.attestation_policy_file {
|
let policy = if let Some(path) = &args.attestation_policy_file {
|
||||||
let policy_content = fs::read_to_string(path).map_err(|e| {
|
let policy_content = fs::read_to_string(path).map_err(|e| {
|
||||||
error::Error::internal(format!("Failed to read attestation policy file: {}", e))
|
error::Error::internal(format!("Failed to read attestation policy file: {e}"))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let policy_config: AttestationPolicyConfig = serde_yaml::from_str(&policy_content)
|
let policy_config: AttestationPolicyConfig = serde_yaml::from_str(&policy_content)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
error::Error::internal(format!(
|
error::Error::internal(format!("Failed to parse attestation policy file: {e}"))
|
||||||
"Failed to parse attestation policy file: {}",
|
|
||||||
e
|
|
||||||
))
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
tracing::info!("Loaded attestation policy from file: {:?}", path);
|
tracing::info!("Loaded attestation policy from file: {:?}", path);
|
||||||
|
|
|
@ -31,13 +31,13 @@ impl fmt::Display for VerifierMode {
|
||||||
end_batch,
|
end_batch,
|
||||||
} => {
|
} => {
|
||||||
if start_batch == end_batch {
|
if start_batch == end_batch {
|
||||||
write!(f, "one-shot mode (batch {})", start_batch)
|
write!(f, "one-shot mode (batch {start_batch})")
|
||||||
} else {
|
} else {
|
||||||
write!(f, "one-shot mode (batches {}-{})", start_batch, end_batch)
|
write!(f, "one-shot mode (batches {start_batch}-{end_batch})")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
VerifierMode::Continuous { start_batch } => {
|
VerifierMode::Continuous { start_batch } => {
|
||||||
write!(f, "continuous mode (starting from batch {})", start_batch)
|
write!(f, "continuous mode (starting from batch {start_batch})")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,8 +89,7 @@ impl fmt::Display for VerificationResult {
|
||||||
} => {
|
} => {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"Partial Success ({} verified, {} failed)",
|
"Partial Success ({verified_count} verified, {unverified_count} failed)"
|
||||||
verified_count, unverified_count
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
VerificationResult::Failure => write!(f, "Failure"),
|
VerificationResult::Failure => write!(f, "Failure"),
|
||||||
|
|
|
@ -74,7 +74,7 @@ async fn main() -> Result<()> {
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
tracing::error!("Task panicked: {}", e);
|
tracing::error!("Task panicked: {}", e);
|
||||||
Err(Error::internal(format!("Task panicked: {}", e)))
|
Err(Error::internal(format!("Task panicked: {e}")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -21,7 +21,7 @@ impl ProofResponseParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Err(error::Error::JsonRpc(format!("JSONRPC error: {:?}", error)));
|
return Err(error::Error::JsonRpc(format!("JSONRPC error: {error:?}")));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract proofs from the result
|
// Extract proofs from the result
|
||||||
|
|
|
@ -17,7 +17,7 @@ impl AttestationVerifier {
|
||||||
// Get current time for verification
|
// Get current time for verification
|
||||||
let unix_time: i64 = std::time::SystemTime::now()
|
let unix_time: i64 = std::time::SystemTime::now()
|
||||||
.duration_since(std::time::UNIX_EPOCH)
|
.duration_since(std::time::UNIX_EPOCH)
|
||||||
.map_err(|e| error::Error::internal(format!("Failed to get system time: {}", e)))?
|
.map_err(|e| error::Error::internal(format!("Failed to get system time: {e}")))?
|
||||||
.as_secs() as _;
|
.as_secs() as _;
|
||||||
|
|
||||||
// Verify the quote with the collateral
|
// Verify the quote with the collateral
|
||||||
|
|
|
@ -107,8 +107,7 @@ impl PolicyEnforcer {
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
if !allowed_levels.contains(actual_level) {
|
if !allowed_levels.contains(actual_level) {
|
||||||
let error_msg = format!(
|
let error_msg = format!(
|
||||||
"Quote verification failed: TCB level mismatch (expected one of: {:?}, actual: {})",
|
"Quote verification failed: TCB level mismatch (expected one of: {allowed_levels:?}, actual: {actual_level})",
|
||||||
allowed_levels, actual_level
|
|
||||||
);
|
);
|
||||||
return Err(Error::policy_violation(error_msg));
|
return Err(Error::policy_violation(error_msg));
|
||||||
}
|
}
|
||||||
|
@ -152,8 +151,7 @@ impl PolicyEnforcer {
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(", ");
|
.join(", ");
|
||||||
let error_msg = format!(
|
let error_msg = format!(
|
||||||
"Quote verification failed: {} mismatch (expected one of: [ {} ], actual: {:x})",
|
"Quote verification failed: {field_name} mismatch (expected one of: [ {valid_values} ], actual: {actual_value:x})"
|
||||||
field_name, valid_values, actual_value
|
|
||||||
);
|
);
|
||||||
return Err(Error::policy_violation(error_msg));
|
return Err(Error::policy_violation(error_msg));
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,9 +30,8 @@ impl SignatureVerifier {
|
||||||
let report_data_bytes = quote_verification_result.quote.get_report_data();
|
let report_data_bytes = quote_verification_result.quote.get_report_data();
|
||||||
tracing::trace!(?report_data_bytes);
|
tracing::trace!(?report_data_bytes);
|
||||||
|
|
||||||
let report_data = ReportData::try_from(report_data_bytes).map_err(|e| {
|
let report_data = ReportData::try_from(report_data_bytes)
|
||||||
error::Error::internal(format!("Could not convert to ReportData: {}", e))
|
.map_err(|e| error::Error::internal(format!("Could not convert to ReportData: {e}")))?;
|
||||||
})?;
|
|
||||||
|
|
||||||
Self::verify(&report_data, &root_hash, signature)
|
Self::verify(&report_data, &root_hash, signature)
|
||||||
}
|
}
|
||||||
|
@ -100,7 +99,7 @@ impl SignatureVerifier {
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
recover_signer(&signature_bytes, &root_hash_msg).map_err(|e| {
|
recover_signer(&signature_bytes, &root_hash_msg).map_err(|e| {
|
||||||
error::Error::signature_verification(format!("Failed to recover signer: {}", e))
|
error::Error::signature_verification(format!("Failed to recover signer: {e}"))
|
||||||
})?
|
})?
|
||||||
}
|
}
|
||||||
// Any other length is invalid
|
// Any other length is invalid
|
||||||
|
|
|
@ -25,20 +25,18 @@ impl ApiClient {
|
||||||
|
|
||||||
if technology == "tdx" && self.api_version == ApiVersion::V3 {
|
if technology == "tdx" && self.api_version == ApiVersion::V3 {
|
||||||
return Err(IntelApiError::UnsupportedApiVersion(format!(
|
return Err(IntelApiError::UnsupportedApiVersion(format!(
|
||||||
"TDX endpoint /{}/{}/{} requires API v4",
|
"TDX endpoint /{service}/{endpoint}/{technology} requires API v4",
|
||||||
service, endpoint, technology
|
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
if technology == "sgx" && service == "registration" {
|
if technology == "sgx" && service == "registration" {
|
||||||
// Registration paths are fixed at v1 regardless of client's api_version
|
// Registration paths are fixed at v1 regardless of client's api_version
|
||||||
return Ok(format!("/sgx/registration/v1/{}", endpoint).replace("//", "/"));
|
return Ok(format!("/sgx/registration/v1/{endpoint}").replace("//", "/"));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(format!(
|
Ok(
|
||||||
"/{}/certification/{}/{}/{}",
|
format!("/{technology}/certification/{api_segment}/{service}/{endpoint}")
|
||||||
technology, api_segment, service, endpoint
|
.replace("//", "/"),
|
||||||
)
|
)
|
||||||
.replace("//", "/"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper to add an optional header if the string is non-empty.
|
/// Helper to add an optional header if the string is non-empty.
|
||||||
|
@ -187,13 +185,11 @@ impl ApiClient {
|
||||||
/// Ensures the client is configured for API v4, otherwise returns an error.
|
/// Ensures the client is configured for API v4, otherwise returns an error.
|
||||||
pub(super) fn ensure_v4_api(&self, function_name: &str) -> Result<(), IntelApiError> {
|
pub(super) fn ensure_v4_api(&self, function_name: &str) -> Result<(), IntelApiError> {
|
||||||
if self.api_version != ApiVersion::V4 {
|
if self.api_version != ApiVersion::V4 {
|
||||||
Err(IntelApiError::UnsupportedApiVersion(format!(
|
return Err(IntelApiError::UnsupportedApiVersion(format!(
|
||||||
"{} requires API v4",
|
"{function_name} requires API v4",
|
||||||
function_name
|
)));
|
||||||
)))
|
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if a V4-only parameter is provided with a V3 API version.
|
/// Checks if a V4-only parameter is provided with a V3 API version.
|
||||||
|
@ -204,8 +200,7 @@ impl ApiClient {
|
||||||
) -> Result<(), IntelApiError> {
|
) -> Result<(), IntelApiError> {
|
||||||
if self.api_version == ApiVersion::V3 && param_value.is_some() {
|
if self.api_version == ApiVersion::V3 && param_value.is_some() {
|
||||||
Err(IntelApiError::UnsupportedApiVersion(format!(
|
Err(IntelApiError::UnsupportedApiVersion(format!(
|
||||||
"'{}' parameter requires API v4",
|
"'{param_name}' parameter requires API v4",
|
||||||
param_name
|
|
||||||
)))
|
)))
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -53,10 +53,7 @@ pub fn setup_logging(
|
||||||
.try_from_env()
|
.try_from_env()
|
||||||
.unwrap_or(match *log_level {
|
.unwrap_or(match *log_level {
|
||||||
LevelFilter::OFF => EnvFilter::new("off"),
|
LevelFilter::OFF => EnvFilter::new("off"),
|
||||||
_ => EnvFilter::new(format!(
|
_ => EnvFilter::new(format!("warn,{crate_name}={log_level},teepot={log_level}")),
|
||||||
"warn,{crate_name}={log_level},teepot={log_level}",
|
|
||||||
log_level = log_level
|
|
||||||
)),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let fmt_layer = tracing_subscriber::fmt::layer()
|
let fmt_layer = tracing_subscriber::fmt::layer()
|
||||||
|
|
|
@ -37,8 +37,7 @@ pub enum ReportData {
|
||||||
fn report_data_to_bytes(data: &[u8], version: u8) -> [u8; REPORT_DATA_LENGTH] {
|
fn report_data_to_bytes(data: &[u8], version: u8) -> [u8; REPORT_DATA_LENGTH] {
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
data.len() < REPORT_DATA_LENGTH, // Ensure there is space for the version byte
|
data.len() < REPORT_DATA_LENGTH, // Ensure there is space for the version byte
|
||||||
"Data length exceeds maximum of {} bytes",
|
"Data length exceeds maximum of {REPORT_DATA_LENGTH} bytes",
|
||||||
REPORT_DATA_LENGTH
|
|
||||||
);
|
);
|
||||||
let mut bytes = [0u8; REPORT_DATA_LENGTH];
|
let mut bytes = [0u8; REPORT_DATA_LENGTH];
|
||||||
bytes[..data.len()].copy_from_slice(data);
|
bytes[..data.len()].copy_from_slice(data);
|
||||||
|
|
|
@ -104,7 +104,7 @@ pub trait QuoteContextErr {
|
||||||
impl<T, E: std::fmt::Display> QuoteContextErr for Result<T, E> {
|
impl<T, E: std::fmt::Display> QuoteContextErr for Result<T, E> {
|
||||||
type Ok = T;
|
type Ok = T;
|
||||||
fn str_context<I: std::fmt::Display>(self, msg: I) -> Result<T, QuoteError> {
|
fn str_context<I: std::fmt::Display>(self, msg: I) -> Result<T, QuoteError> {
|
||||||
self.map_err(|e| QuoteError::Unexpected(format!("{}: {}", msg, e)))
|
self.map_err(|e| QuoteError::Unexpected(format!("{msg}: {e}")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -583,7 +583,7 @@ impl Display for TEEType {
|
||||||
TEEType::TDX => "tdx",
|
TEEType::TDX => "tdx",
|
||||||
TEEType::SNP => "snp",
|
TEEType::SNP => "snp",
|
||||||
};
|
};
|
||||||
write!(f, "{}", str)
|
write!(f, "{str}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -134,14 +134,14 @@ fn convert_to_collateral(
|
||||||
/// Split the last zero byte
|
/// Split the last zero byte
|
||||||
fn get_str_from_bytes(bytes: &[u8], context: &str) -> Result<String, QuoteError> {
|
fn get_str_from_bytes(bytes: &[u8], context: &str) -> Result<String, QuoteError> {
|
||||||
let c_str = CStr::from_bytes_until_nul(bytes)
|
let c_str = CStr::from_bytes_until_nul(bytes)
|
||||||
.str_context(format!("Failed to extract CString: {}", context))?;
|
.str_context(format!("Failed to extract CString: {context}"))?;
|
||||||
Ok(c_str.to_string_lossy().into_owned())
|
Ok(c_str.to_string_lossy().into_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse JSON field from collateral data
|
/// Parse JSON field from collateral data
|
||||||
fn parse_json_field(data: &[u8], context: &str) -> Result<serde_json::Value, QuoteError> {
|
fn parse_json_field(data: &[u8], context: &str) -> Result<serde_json::Value, QuoteError> {
|
||||||
serde_json::from_str(&get_str_from_bytes(data, context)?)
|
serde_json::from_str(&get_str_from_bytes(data, context)?)
|
||||||
.str_context(format!("Failed to parse JSON: {}", context))
|
.str_context(format!("Failed to parse JSON: {context}"))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert Collateral to QuoteCollateralV3
|
/// Convert Collateral to QuoteCollateralV3
|
||||||
|
|
|
@ -46,7 +46,7 @@ impl FromStr for TcbLevel {
|
||||||
"outofdate" => Ok(TcbLevel::OutOfDate),
|
"outofdate" => Ok(TcbLevel::OutOfDate),
|
||||||
"outofdateconfigneeded" => Ok(TcbLevel::OutOfDateConfigNeeded),
|
"outofdateconfigneeded" => Ok(TcbLevel::OutOfDateConfigNeeded),
|
||||||
"invalid" => Ok(TcbLevel::Invalid),
|
"invalid" => Ok(TcbLevel::Invalid),
|
||||||
_ => Err(format!("Invalid TCB level: {}", s)),
|
_ => Err(format!("Invalid TCB level: {s}")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,8 +72,8 @@ pub fn parse_tcb_levels(
|
||||||
let mut set = EnumSet::new();
|
let mut set = EnumSet::new();
|
||||||
for level_str in s.split(',') {
|
for level_str in s.split(',') {
|
||||||
let level_str = level_str.trim();
|
let level_str = level_str.trim();
|
||||||
let level = TcbLevel::from_str(level_str)
|
let level =
|
||||||
.map_err(|_| format!("Invalid TCB level: {}", level_str))?;
|
TcbLevel::from_str(level_str).map_err(|_| format!("Invalid TCB level: {level_str}"))?;
|
||||||
set.insert(level);
|
set.insert(level);
|
||||||
}
|
}
|
||||||
Ok(set)
|
Ok(set)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue