20261015_4 修复Manifest编号与改名抗重放校验
This commit is contained in:
@@ -27,10 +27,45 @@ impl<'a> Rpkiv1PublicationPointRunner<'a> {
|
||||
let snapshot_prepare_started = std::time::Instant::now();
|
||||
let issuer_ca_der = ca_certificate_der_for_validation(ca, self.store, self.timing.as_ref())
|
||||
.map_err(|detail| FreshPublicationPointStageError {
|
||||
warnings: Vec::new(),
|
||||
error: ManifestFreshError::IssuerCaLoadFailed { detail },
|
||||
snapshot_prepare_ms: snapshot_prepare_started.elapsed().as_millis() as u64,
|
||||
})?;
|
||||
let issuer_ca_der: Arc<[u8]> = Arc::from(issuer_ca_der.as_ref());
|
||||
let identity = ResourceCertificate::decode_der(&issuer_ca_der)
|
||||
.map(|cert| {
|
||||
crate::repository::storage::CaIdentity::from_spki(
|
||||
ca.anchor_namespace,
|
||||
&cert.tbs.subject_public_key_info,
|
||||
)
|
||||
})
|
||||
.map_err(|e| FreshPublicationPointStageError {
|
||||
warnings: Vec::new(),
|
||||
error: ManifestFreshError::IssuerCaLoadFailed {
|
||||
detail: e.to_string(),
|
||||
},
|
||||
snapshot_prepare_ms: snapshot_prepare_started.elapsed().as_millis() as u64,
|
||||
})?;
|
||||
let rename_warnings: Vec<Warning> = crate::validation::manifest::manifest_rename_warning(
|
||||
self.store,
|
||||
&identity,
|
||||
&ca.manifest_sia_uris,
|
||||
&ca.manifest_rsync_uri,
|
||||
)
|
||||
.map_err(|error| FreshPublicationPointStageError {
|
||||
warnings: Vec::new(),
|
||||
error,
|
||||
snapshot_prepare_ms: snapshot_prepare_started.elapsed().as_millis() as u64,
|
||||
})?
|
||||
.into_iter()
|
||||
.collect();
|
||||
for warning in &rename_warnings {
|
||||
crate::logging::emit(
|
||||
crate::logging::Level::Warn,
|
||||
"manifest_filename_changed",
|
||||
|| serde_json::json!({"manifest_rsync_uri": ca.manifest_rsync_uri, "message": warning.message, "candidate_accepted": null}),
|
||||
);
|
||||
}
|
||||
let fresh_publication_point = {
|
||||
let _manifest_total = self
|
||||
.timing
|
||||
@@ -38,6 +73,7 @@ impl<'a> Rpkiv1PublicationPointRunner<'a> {
|
||||
.map(|t| t.span_phase("manifest_processing_total"));
|
||||
process_manifest_publication_point_fresh_after_repo_sync_with_timing(
|
||||
self.store,
|
||||
&ca.anchor_namespace,
|
||||
&ca.manifest_rsync_uri,
|
||||
&ca.publication_point_rsync_uri,
|
||||
self.current_repo_index.as_ref(),
|
||||
@@ -51,6 +87,16 @@ impl<'a> Rpkiv1PublicationPointRunner<'a> {
|
||||
let snapshot_prepare_ms = snapshot_prepare_started.elapsed().as_millis() as u64;
|
||||
let (fresh_point, snapshot_prepare_timing) =
|
||||
fresh_publication_point.map_err(|error| FreshPublicationPointStageError {
|
||||
warnings: rename_warnings
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(|mut warning| {
|
||||
warning
|
||||
.message
|
||||
.push_str(&format!(" candidate_accepted=false reason={error}"));
|
||||
warning
|
||||
})
|
||||
.collect(),
|
||||
error,
|
||||
snapshot_prepare_ms,
|
||||
})?;
|
||||
@@ -152,7 +198,7 @@ impl<'a> Rpkiv1PublicationPointRunner<'a> {
|
||||
self.policy,
|
||||
)
|
||||
};
|
||||
let (discovered_children, child_audits, discovered_router_keys, warnings) = match out {
|
||||
let (discovered_children, child_audits, discovered_router_keys, mut warnings) = match out {
|
||||
Ok(out) => (out.children, out.audits, out.router_keys, Vec::new()),
|
||||
Err(e) => (
|
||||
Vec::new(),
|
||||
@@ -188,6 +234,7 @@ impl<'a> Rpkiv1PublicationPointRunner<'a> {
|
||||
child_discovery_ms,
|
||||
);
|
||||
|
||||
warnings.extend(rename_warnings);
|
||||
Ok(FreshPublicationPointStage {
|
||||
fresh_point,
|
||||
issuer_ca_der,
|
||||
@@ -205,7 +252,7 @@ impl<'a> Rpkiv1PublicationPointRunner<'a> {
|
||||
&self,
|
||||
ca: &CaInstanceHandle,
|
||||
fresh_point: &FreshValidatedPublicationPoint,
|
||||
warnings: Vec<Warning>,
|
||||
mut warnings: Vec<Warning>,
|
||||
objects: crate::validation::objects::ObjectsOutput,
|
||||
child_audits: Vec<ObjectAuditEntry>,
|
||||
discovered_children: Vec<DiscoveredChildCaInstance>,
|
||||
@@ -229,6 +276,7 @@ impl<'a> Rpkiv1PublicationPointRunner<'a> {
|
||||
snapshot_pack_ms,
|
||||
);
|
||||
|
||||
let mut ccr_projection = None;
|
||||
let mut ccr_projection_build_ms = 0;
|
||||
let mut ccr_append_ms = 0;
|
||||
if self.ccr_accumulator.is_some() {
|
||||
@@ -254,9 +302,30 @@ impl<'a> Rpkiv1PublicationPointRunner<'a> {
|
||||
let ccr_manifest_projection =
|
||||
crate::ccr::projection::from_snapshot(ca, &pack, subordinate_skis)?;
|
||||
ccr_projection_build_ms = ccr_projection_build_started.elapsed().as_millis() as u64;
|
||||
let ccr_append_started = std::time::Instant::now();
|
||||
self.append_ccr_manifest_projection(&ccr_manifest_projection)?;
|
||||
ccr_append_ms = ccr_append_started.elapsed().as_millis() as u64;
|
||||
ccr_projection = Some(ccr_manifest_projection);
|
||||
}
|
||||
let (_, commit_warning) = crate::validation::manifest::commit_manifest_history(
|
||||
self.store,
|
||||
&fresh_point.history_candidate,
|
||||
)
|
||||
.map_err(|error| format!("persist manifest freshness failed: {error}"))?;
|
||||
if let Some(warning) = commit_warning {
|
||||
warnings.retain(|item| !item.message.starts_with("manifest filename changed:"));
|
||||
warnings.push(warning);
|
||||
}
|
||||
for warning in &mut warnings {
|
||||
if warning.message.starts_with("manifest filename changed:") {
|
||||
warning.message.push_str(&format!(
|
||||
" new_number={} new_this_update={} candidate_accepted=true",
|
||||
hex::encode_upper(&pack.manifest_number_be),
|
||||
pack.this_update.rfc3339_utc
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(projection) = ccr_projection {
|
||||
let started = std::time::Instant::now();
|
||||
self.append_ccr_manifest_projection(&projection)?;
|
||||
ccr_append_ms = started.elapsed().as_millis() as u64;
|
||||
}
|
||||
if let Some(timing) = self.timing.as_ref() {
|
||||
timing.record_phase_nanos(
|
||||
@@ -305,21 +374,6 @@ impl<'a> Rpkiv1PublicationPointRunner<'a> {
|
||||
audit_build_ms,
|
||||
);
|
||||
|
||||
// Commit protocol freshness only after successful publication-point
|
||||
// validation/finalization, independently of optional CCR output.
|
||||
self.store
|
||||
.put_manifest_anti_rollback_meta(
|
||||
&crate::repository::storage::ManifestAntiRollbackMeta {
|
||||
manifest_rsync_uri: pack.manifest_rsync_uri.clone(),
|
||||
manifest_number_be: pack.manifest_number_be.clone(),
|
||||
manifest_this_update: pack.this_update.clone(),
|
||||
manifest_sha256: <sha2::Sha256 as sha2::Digest>::digest(&pack.manifest_bytes)
|
||||
.to_vec(),
|
||||
updated_at_validation_time: pack.verified_at.clone(),
|
||||
},
|
||||
)
|
||||
.map_err(|error| format!("persist manifest freshness failed: {error}"))?;
|
||||
|
||||
Ok(FreshPublicationPointFinalizeOutput {
|
||||
result: PublicationPointRunResult {
|
||||
source: PublicationPointSource::Fresh,
|
||||
|
||||
Reference in New Issue
Block a user