20260418 优化去掉冗余存储repo object,mix quick最快170s
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user