20260722 新增密码学签名验证缓存(#126):5个验签收口点接入独立缓存,observe-only/enable双开关默认关闭,消融脚本新增crypto-sig等case set,verification contract补crypto_signature字段

This commit is contained in:
2026-07-22 12:14:13 +08:00
parent f86fbd4939
commit 3d772f748c
11 changed files with 1313 additions and 22 deletions

View File

@@ -485,9 +485,17 @@ fn verify_child_signature(
child: &X509Certificate<'_>,
issuer_spki: &SubjectPublicKeyInfo<'_>,
) -> Result<(), CaPathError> {
child
.verify_signature(Some(issuer_spki))
.map_err(|e| CaPathError::ChildSignatureInvalid(e.to_string()))
crate::crypto_sig_cache::verify_with_cache(
crate::crypto_sig_cache::CryptoSigVerifyPoint::ChildCaCert,
child.tbs_certificate.as_ref(),
child.signature_value.data.as_ref(),
issuer_spki.raw,
|| {
child
.verify_signature(Some(issuer_spki))
.map_err(|e| CaPathError::ChildSignatureInvalid(e.to_string()))
},
)
}
fn validate_child_aki_matches_issuer_ski(
@@ -2118,6 +2126,53 @@ mod tests {
);
}
#[test]
fn signature_cache_stores_real_verify_success_and_skips_on_hit() {
let _guard = crate::crypto_sig_cache::GLOBAL_TEST_LOCK.lock().expect("test lock");
crate::crypto_sig_cache::clear_global();
let td = tempfile::tempdir().expect("tempdir");
let (issuer, child, other) = gen_issuer_and_child_der(td.path());
let issuer_cert = parse_x509_cert(&issuer).expect("x509 parse issuer");
let child_cert = parse_x509_cert(&child).expect("x509 parse child");
let other_cert = parse_x509_cert(&other).expect("x509 parse other");
let cache_dir = tempfile::tempdir().expect("tempdir");
let cache = std::sync::Arc::new(crate::crypto_sig_cache::CryptoSigCache::load_or_rebuild(
cache_dir.path().join("work-db.crypto-sig-cache"),
true,
));
crate::crypto_sig_cache::install_global(std::sync::Arc::clone(&cache));
// Miss -> real verification runs and passes -> positive conclusion written.
verify_child_signature(&child_cert, &issuer_cert.tbs_certificate.subject_pki)
.expect("signature ok");
// Hit -> skipped (a second execution would also pass, so assert via stats).
verify_child_signature(&child_cert, &issuer_cert.tbs_certificate.subject_pki)
.expect("signature ok");
// Wrong issuer: real verification fails, nothing is written (no negative caching),
// so a retry executes the real verification again instead of inheriting anything.
for _ in 0..2 {
let err = verify_child_signature(&child_cert, &other_cert.tbs_certificate.subject_pki)
.unwrap_err();
assert!(
matches!(err, CaPathError::ChildSignatureInvalid(_)),
"{err}"
);
}
let summary = cache.summary();
let stats = summary
.per_point
.get("child_ca_cert")
.expect("child_ca_cert stats");
assert_eq!(stats.calls, 4);
assert_eq!(stats.would_hit, 1);
assert_eq!(stats.new_keys, 3);
assert_eq!(stats.verify_executed, 3);
assert_eq!(stats.verify_skipped, 1);
crate::crypto_sig_cache::clear_global();
}
#[test]
fn issuer_effective_resources_index_and_indexed_resolvers_cover_success_and_failure_paths() {
use crate::data_model::rc::{AsIdOrRange, IpPrefix};