20260418 优化去掉冗余存储repo object,mix quick最快170s

This commit is contained in:
2026-04-18 14:10:47 +08:00
parent f485786470
commit 417c82bef6
34 changed files with 1482 additions and 328 deletions

View File

@@ -3,6 +3,8 @@ use crate::data_model::crl::{CrlDecodeError, CrlVerifyError, RpkixCrl};
use crate::data_model::rc::{
ResourceCertKind, ResourceCertificate, ResourceCertificateDecodeError,
};
use crate::data_model::signed_object::{EeKeyUsageSummary, ResourceEeCertificate};
use ring::signature;
use x509_parser::prelude::{FromDer, X509Certificate};
use crate::validation::x509_name::x509_names_equivalent;
@@ -63,6 +65,9 @@ pub enum CertPathError {
#[error("EE KeyUsage must have only digitalSignature set (RFC 6487 §4.8.4)")]
KeyUsageInvalidBits,
#[error("EE KeyUsage parse failed: {0} (RFC 6487 §4.8.4; RFC 5280 §4.2.1.3)")]
KeyUsageParse(String),
#[error("issuer CA subjectKeyIdentifier missing (RFC 6487 §4.8.2)")]
IssuerSkiMissing,
@@ -235,6 +240,34 @@ pub fn validate_ee_cert_path_with_predecoded_ee(
)
}
/// Validate a signed-object embedded EE certificate path using signed-object cached fields.
///
/// This avoids reparsing the EE certificate as `X509Certificate` and bypasses the
/// x509-parser signature wrapper by verifying the cached TBS/signature bytes directly.
pub fn validate_signed_object_ee_cert_path_fast(
ee: &ResourceEeCertificate,
issuer_ca: &ResourceCertificate,
issuer_spki: &SubjectPublicKeyInfo<'_>,
issuer_crl: &RpkixCrl,
issuer_crl_revoked_serials: &HashSet<Vec<u8>>,
issuer_ca_rsync_uri: Option<&str>,
issuer_crl_rsync_uri: Option<&str>,
validation_time: time::OffsetDateTime,
) -> Result<(), CertPathError> {
validate_ee_cert_path_bindings_and_status(
&ee.resource_cert,
issuer_ca,
issuer_crl,
issuer_crl_revoked_serials,
issuer_ca_rsync_uri,
issuer_crl_rsync_uri,
validation_time,
)?;
validate_ee_key_usage_summary(&ee.key_usage_summary)?;
verify_ee_cert_signature_fast(&ee.tbs_certificate_der, &ee.signature_bytes, issuer_spki)?;
Ok(())
}
fn validate_ee_cert_path_components(
ee: &ResourceCertificate,
ee_cert_der: &[u8],
@@ -245,6 +278,32 @@ fn validate_ee_cert_path_components(
issuer_ca_rsync_uri: Option<&str>,
issuer_crl_rsync_uri: Option<&str>,
validation_time: time::OffsetDateTime,
) -> Result<(), CertPathError> {
validate_ee_cert_path_bindings_and_status(
ee,
issuer_ca,
issuer_crl,
issuer_crl_revoked_serials,
issuer_ca_rsync_uri,
issuer_crl_rsync_uri,
validation_time,
)?;
let ee_x509 = parse_x509_cert(ee_cert_der)?;
verify_ee_cert_signature(&ee_x509, issuer_spki)?;
validate_ee_key_usage(&ee_x509)?;
Ok(())
}
fn validate_ee_cert_path_bindings_and_status(
ee: &ResourceCertificate,
issuer_ca: &ResourceCertificate,
issuer_crl: &RpkixCrl,
issuer_crl_revoked_serials: &HashSet<Vec<u8>>,
issuer_ca_rsync_uri: Option<&str>,
issuer_crl_rsync_uri: Option<&str>,
validation_time: time::OffsetDateTime,
) -> Result<(), CertPathError> {
if ee.kind != ResourceCertKind::Ee {
return Err(CertPathError::EeNotEe);
@@ -280,10 +339,6 @@ fn validate_ee_cert_path_components(
return Err(CertPathError::CertificateNotValidAtTime);
}
let ee_x509 = parse_x509_cert(ee_cert_der)?;
verify_ee_cert_signature(&ee_x509, issuer_spki)?;
validate_ee_key_usage(&ee_x509)?;
if !crl_valid_at_time(issuer_crl, validation_time) {
return Err(CertPathError::CrlNotValidAtTime);
}
@@ -324,6 +379,19 @@ fn verify_ee_cert_signature(
.map_err(|e| CertPathError::EeSignatureInvalid(e.to_string()))
}
fn verify_ee_cert_signature_fast(
ee_tbs_der: &[u8],
ee_signature_bytes: &[u8],
issuer_spki: &SubjectPublicKeyInfo<'_>,
) -> Result<(), CertPathError> {
let key = signature::UnparsedPublicKey::new(
&signature::RSA_PKCS1_2048_8192_SHA256,
&issuer_spki.subject_public_key.data,
);
key.verify(ee_tbs_der, ee_signature_bytes)
.map_err(|e| CertPathError::EeSignatureInvalid(e.to_string()))
}
fn validate_ee_aki_matches_issuer_ski(
ee: &ResourceCertificate,
issuer_ca: &ResourceCertificate,
@@ -408,6 +476,16 @@ fn validate_ee_key_usage(cert: &X509Certificate<'_>) -> Result<(), CertPathError
Ok(())
}
fn validate_ee_key_usage_summary(summary: &EeKeyUsageSummary) -> Result<(), CertPathError> {
match summary {
EeKeyUsageSummary::DigitalSignatureOnly => Ok(()),
EeKeyUsageSummary::Missing => Err(CertPathError::KeyUsageMissing),
EeKeyUsageSummary::NotCritical => Err(CertPathError::KeyUsageNotCritical),
EeKeyUsageSummary::InvalidBits => Err(CertPathError::KeyUsageInvalidBits),
EeKeyUsageSummary::ParseError(err) => Err(CertPathError::KeyUsageParse(err.clone())),
}
}
fn time_within_validity(
t: time::OffsetDateTime,
not_before: time::OffsetDateTime,