初始化 Panda RPKI v0.1.0 开源候选版本
This commit is contained in:
606
src/validation/manifest/tests.rs
Normal file
606
src/validation/manifest/tests.rs
Normal file
@@ -0,0 +1,606 @@
|
||||
//! Manifest processing regression tests.
|
||||
use super::*;
|
||||
use crate::repository::current_repo_index::CurrentRepoIndex;
|
||||
use crate::repository::storage::{RawByHashEntry, RocksStore};
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn fixture_repository() -> PathBuf {
|
||||
crate::test_support::synthetic_repository().case_repository("baseline-v1")
|
||||
}
|
||||
|
||||
fn manifest_fixture_path() -> PathBuf {
|
||||
fixture_repository().join("child/child.mft")
|
||||
}
|
||||
|
||||
fn issuer_ca_fixture_der() -> Vec<u8> {
|
||||
std::fs::read(fixture_repository().join("root/child.cer")).expect("read synthetic issuer CA")
|
||||
}
|
||||
|
||||
fn issuer_ca_rsync_uri() -> &'static str {
|
||||
"rsync://rpki-local-rsync:873/custom/root/child.cer"
|
||||
}
|
||||
|
||||
fn load_manifest_fixture() -> (
|
||||
ManifestObject,
|
||||
Vec<u8>,
|
||||
String,
|
||||
String,
|
||||
time::OffsetDateTime,
|
||||
) {
|
||||
let manifest_path = manifest_fixture_path();
|
||||
let manifest_bytes = std::fs::read(&manifest_path).expect("read synthetic manifest");
|
||||
let manifest = ManifestObject::decode_der(&manifest_bytes).expect("decode synthetic manifest");
|
||||
let manifest_rsync_uri = "rsync://rpki-local-rsync:873/custom/child/child.mft".to_string();
|
||||
let publication_point_rsync_uri = "rsync://rpki-local-rsync:873/custom/child/".to_string();
|
||||
let validation_time = manifest.manifest.this_update + time::Duration::seconds(1);
|
||||
(
|
||||
manifest,
|
||||
manifest_bytes,
|
||||
manifest_rsync_uri,
|
||||
publication_point_rsync_uri,
|
||||
validation_time,
|
||||
)
|
||||
}
|
||||
|
||||
fn raw_by_hash_entry(uri: &str, bytes: Vec<u8>, object_type: &str) -> RawByHashEntry {
|
||||
let mut entry = RawByHashEntry::from_bytes(hex::encode(sha2::Sha256::digest(&bytes)), bytes);
|
||||
entry.origin_uris.push(uri.to_string());
|
||||
entry.object_type = Some(object_type.to_string());
|
||||
entry.encoding = Some("der".to_string());
|
||||
entry
|
||||
}
|
||||
|
||||
fn put_current_object(store: &RocksStore, rsync_uri: &str, bytes: Vec<u8>, object_type: &str) {
|
||||
let hash = hex::encode(sha2::Sha256::digest(&bytes));
|
||||
store
|
||||
.put_raw_by_hash_entry(&raw_by_hash_entry(rsync_uri, bytes, object_type))
|
||||
.expect("put raw_by_hash entry");
|
||||
store
|
||||
.put_repository_view_entry(&crate::repository::storage::RepositoryViewEntry {
|
||||
rsync_uri: rsync_uri.to_string(),
|
||||
current_hash: Some(hash),
|
||||
repository_source: Some("https://example.test/notification.xml".to_string()),
|
||||
object_type: Some(object_type.to_string()),
|
||||
state: crate::repository::storage::RepositoryViewState::Present,
|
||||
})
|
||||
.expect("put repository view entry");
|
||||
}
|
||||
|
||||
fn put_complete_publication_point_current_objects(
|
||||
store: &RocksStore,
|
||||
manifest: &ManifestObject,
|
||||
manifest_rsync_uri: &str,
|
||||
manifest_bytes: Vec<u8>,
|
||||
publication_point_rsync_uri: &str,
|
||||
) {
|
||||
put_current_object(store, manifest_rsync_uri, manifest_bytes, "mft");
|
||||
for entry in manifest.manifest.parse_files().expect("parse files") {
|
||||
let file_path = manifest_fixture_path()
|
||||
.parent()
|
||||
.unwrap()
|
||||
.join(entry.file_name.as_str());
|
||||
let bytes = std::fs::read(&file_path).expect("read fixture file");
|
||||
let rsync_uri = format!("{publication_point_rsync_uri}{}", entry.file_name);
|
||||
let object_type = rsync_uri.rsplit('.').next().unwrap_or("bin");
|
||||
put_current_object(store, &rsync_uri, bytes, object_type);
|
||||
}
|
||||
}
|
||||
|
||||
fn put_raw_only(store: &RocksStore, rsync_uri: &str, bytes: Vec<u8>, object_type: &str) {
|
||||
store
|
||||
.put_raw_by_hash_entry(&raw_by_hash_entry(rsync_uri, bytes, object_type))
|
||||
.expect("put raw_by_hash entry");
|
||||
}
|
||||
|
||||
fn locked_files_for_manifest(
|
||||
manifest: &ManifestObject,
|
||||
publication_point_rsync_uri: &str,
|
||||
) -> Vec<PackFile> {
|
||||
let manifest_path = manifest_fixture_path();
|
||||
manifest
|
||||
.manifest
|
||||
.parse_files()
|
||||
.expect("parse files")
|
||||
.into_iter()
|
||||
.map(|entry| {
|
||||
let file_path = manifest_path
|
||||
.parent()
|
||||
.unwrap()
|
||||
.join(entry.file_name.as_str());
|
||||
let bytes = std::fs::read(&file_path).unwrap_or_else(|_| {
|
||||
panic!("read fixture file referenced by manifest: {file_path:?}")
|
||||
});
|
||||
PackFile::from_bytes_compute_sha256(
|
||||
format!("{publication_point_rsync_uri}{}", entry.file_name),
|
||||
bytes,
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn try_build_fresh_publication_point_rejects_manifest_outside_publication_point() {
|
||||
let temp = tempfile::tempdir().expect("tempdir");
|
||||
let store = RocksStore::open(temp.path()).expect("open rocksdb");
|
||||
let (_, _, manifest_rsync_uri, _, validation_time) = load_manifest_fixture();
|
||||
let err = try_build_fresh_publication_point(
|
||||
&store,
|
||||
&manifest_rsync_uri,
|
||||
"rsync://example.test/other/",
|
||||
&issuer_ca_fixture_der(),
|
||||
Some(issuer_ca_rsync_uri()),
|
||||
validation_time,
|
||||
)
|
||||
.unwrap_err();
|
||||
assert!(
|
||||
matches!(
|
||||
err,
|
||||
ManifestFreshError::ManifestOutsidePublicationPoint { .. }
|
||||
),
|
||||
"{err}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn try_build_fresh_publication_point_reports_missing_manifest_when_raw_store_is_empty() {
|
||||
let temp = tempfile::tempdir().expect("tempdir");
|
||||
let store = RocksStore::open(temp.path()).expect("open rocksdb");
|
||||
let (_, _, manifest_rsync_uri, publication_point_rsync_uri, validation_time) =
|
||||
load_manifest_fixture();
|
||||
let err = try_build_fresh_publication_point(
|
||||
&store,
|
||||
&manifest_rsync_uri,
|
||||
&publication_point_rsync_uri,
|
||||
&issuer_ca_fixture_der(),
|
||||
Some(issuer_ca_rsync_uri()),
|
||||
validation_time,
|
||||
)
|
||||
.unwrap_err();
|
||||
assert!(
|
||||
matches!(err, ManifestFreshError::MissingManifest { .. }),
|
||||
"{err}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn try_build_fresh_publication_point_reports_missing_locked_file() {
|
||||
let temp = tempfile::tempdir().expect("tempdir");
|
||||
let store = RocksStore::open(temp.path()).expect("open rocksdb");
|
||||
let (
|
||||
manifest,
|
||||
manifest_bytes,
|
||||
manifest_rsync_uri,
|
||||
publication_point_rsync_uri,
|
||||
validation_time,
|
||||
) = load_manifest_fixture();
|
||||
put_current_object(&store, &manifest_rsync_uri, manifest_bytes, "mft");
|
||||
let first_non_crl = manifest
|
||||
.manifest
|
||||
.parse_files()
|
||||
.expect("parse files")
|
||||
.into_iter()
|
||||
.find(|entry| !entry.file_name.ends_with(".crl"))
|
||||
.expect("fixture non-crl entry");
|
||||
let file_path = manifest_fixture_path()
|
||||
.parent()
|
||||
.unwrap()
|
||||
.join(first_non_crl.file_name.as_str());
|
||||
let bytes = std::fs::read(&file_path).expect("read fixture file");
|
||||
let rsync_uri = format!("{publication_point_rsync_uri}{}", first_non_crl.file_name);
|
||||
let object_type = rsync_uri.rsplit('.').next().unwrap_or("bin");
|
||||
put_current_object(&store, &rsync_uri, bytes, object_type);
|
||||
|
||||
let err = try_build_fresh_publication_point(
|
||||
&store,
|
||||
&manifest_rsync_uri,
|
||||
&publication_point_rsync_uri,
|
||||
&issuer_ca_fixture_der(),
|
||||
Some(issuer_ca_rsync_uri()),
|
||||
validation_time,
|
||||
)
|
||||
.unwrap_err();
|
||||
assert!(
|
||||
matches!(err, ManifestFreshError::MissingFile { .. }),
|
||||
"{err}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn try_build_fresh_publication_point_detects_hash_mismatch_via_repository_view_hash() {
|
||||
let temp = tempfile::tempdir().expect("tempdir");
|
||||
let store = RocksStore::open(temp.path()).expect("open rocksdb");
|
||||
let (
|
||||
manifest,
|
||||
manifest_bytes,
|
||||
manifest_rsync_uri,
|
||||
publication_point_rsync_uri,
|
||||
validation_time,
|
||||
) = load_manifest_fixture();
|
||||
put_current_object(&store, &manifest_rsync_uri, manifest_bytes, "mft");
|
||||
|
||||
let entries = manifest
|
||||
.manifest
|
||||
.parse_files()
|
||||
.expect("parse files")
|
||||
.into_iter()
|
||||
.collect::<Vec<_>>();
|
||||
let first = entries
|
||||
.iter()
|
||||
.find(|entry| !entry.file_name.ends_with(".crl"))
|
||||
.expect("synthetic manifest non-CRL entry");
|
||||
|
||||
let first_uri = format!("{publication_point_rsync_uri}{}", first.file_name);
|
||||
let object_type = first_uri.rsplit('.').next().unwrap_or("bin");
|
||||
put_current_object(
|
||||
&store,
|
||||
&first_uri,
|
||||
b"wrong object bytes".to_vec(),
|
||||
object_type,
|
||||
);
|
||||
|
||||
for entry in entries
|
||||
.iter()
|
||||
.filter(|entry| entry.file_name != first.file_name)
|
||||
{
|
||||
let file_path = manifest_fixture_path()
|
||||
.parent()
|
||||
.unwrap()
|
||||
.join(entry.file_name.as_str());
|
||||
let bytes = std::fs::read(&file_path).expect("read fixture file");
|
||||
let rsync_uri = format!("{publication_point_rsync_uri}{}", entry.file_name);
|
||||
let object_type = rsync_uri.rsplit('.').next().unwrap_or("bin");
|
||||
put_current_object(&store, &rsync_uri, bytes, object_type);
|
||||
}
|
||||
|
||||
let err = try_build_fresh_publication_point(
|
||||
&store,
|
||||
&manifest_rsync_uri,
|
||||
&publication_point_rsync_uri,
|
||||
&issuer_ca_fixture_der(),
|
||||
Some(issuer_ca_rsync_uri()),
|
||||
validation_time,
|
||||
)
|
||||
.unwrap_err();
|
||||
assert!(
|
||||
matches!(err, ManifestFreshError::HashMismatch { .. }),
|
||||
"{err}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn try_build_fresh_publication_point_uses_current_repo_index_without_repository_view() {
|
||||
let temp = tempfile::tempdir().expect("tempdir");
|
||||
let store = RocksStore::open(temp.path()).expect("open rocksdb");
|
||||
let (
|
||||
manifest,
|
||||
manifest_bytes,
|
||||
manifest_rsync_uri,
|
||||
publication_point_rsync_uri,
|
||||
validation_time,
|
||||
) = load_manifest_fixture();
|
||||
|
||||
put_raw_only(&store, &manifest_rsync_uri, manifest_bytes.clone(), "mft");
|
||||
let current_index = CurrentRepoIndex::shared();
|
||||
let mut entries = vec![crate::repository::storage::RepositoryViewEntry {
|
||||
rsync_uri: manifest_rsync_uri.clone(),
|
||||
current_hash: Some(hex::encode(sha2::Sha256::digest(&manifest_bytes))),
|
||||
repository_source: Some("https://example.test/notification.xml".to_string()),
|
||||
object_type: Some("mft".to_string()),
|
||||
state: crate::repository::storage::RepositoryViewState::Present,
|
||||
}];
|
||||
|
||||
for entry in manifest.manifest.parse_files().expect("parse files") {
|
||||
let file_path = manifest_fixture_path()
|
||||
.parent()
|
||||
.unwrap()
|
||||
.join(entry.file_name.as_str());
|
||||
let bytes = std::fs::read(&file_path).expect("read fixture file");
|
||||
let rsync_uri = format!("{publication_point_rsync_uri}{}", entry.file_name);
|
||||
let object_type = rsync_uri.rsplit('.').next().unwrap_or("bin").to_string();
|
||||
put_raw_only(&store, &rsync_uri, bytes.clone(), &object_type);
|
||||
entries.push(crate::repository::storage::RepositoryViewEntry {
|
||||
rsync_uri,
|
||||
current_hash: Some(hex::encode(sha2::Sha256::digest(&bytes))),
|
||||
repository_source: Some("https://example.test/notification.xml".to_string()),
|
||||
object_type: Some(object_type),
|
||||
state: crate::repository::storage::RepositoryViewState::Present,
|
||||
});
|
||||
}
|
||||
|
||||
current_index
|
||||
.write()
|
||||
.expect("index write lock")
|
||||
.apply_repository_view_entries(&entries)
|
||||
.expect("apply current index");
|
||||
|
||||
assert!(
|
||||
store
|
||||
.get_repository_view_entry(&manifest_rsync_uri)
|
||||
.expect("get repository view")
|
||||
.is_none()
|
||||
);
|
||||
|
||||
let (fresh, _timing) = try_build_fresh_publication_point_with_timing(
|
||||
&store,
|
||||
&manifest_rsync_uri,
|
||||
&publication_point_rsync_uri,
|
||||
Some(¤t_index),
|
||||
&issuer_ca_fixture_der(),
|
||||
Some(issuer_ca_rsync_uri()),
|
||||
validation_time,
|
||||
)
|
||||
.expect("fresh publication point via current index");
|
||||
|
||||
assert_eq!(fresh.manifest_rsync_uri, manifest_rsync_uri);
|
||||
assert_eq!(fresh.files.len(), manifest.manifest.file_count());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn try_build_fresh_publication_point_records_anti_rollback_meta_miss() {
|
||||
let temp = tempfile::tempdir().expect("tempdir");
|
||||
let store = RocksStore::open(temp.path()).expect("open rocksdb");
|
||||
let (
|
||||
manifest,
|
||||
manifest_bytes,
|
||||
manifest_rsync_uri,
|
||||
publication_point_rsync_uri,
|
||||
validation_time,
|
||||
) = load_manifest_fixture();
|
||||
put_complete_publication_point_current_objects(
|
||||
&store,
|
||||
&manifest,
|
||||
&manifest_rsync_uri,
|
||||
manifest_bytes,
|
||||
&publication_point_rsync_uri,
|
||||
);
|
||||
|
||||
let (_fresh, timing) = try_build_fresh_publication_point_with_timing(
|
||||
&store,
|
||||
&manifest_rsync_uri,
|
||||
&publication_point_rsync_uri,
|
||||
None,
|
||||
&issuer_ca_fixture_der(),
|
||||
Some(issuer_ca_rsync_uri()),
|
||||
validation_time,
|
||||
)
|
||||
.expect("fresh publication point without freshness metadata");
|
||||
|
||||
assert!(timing.anti_rollback_meta_miss);
|
||||
assert!(!timing.anti_rollback_meta_hit);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn try_build_fresh_publication_point_uses_anti_rollback_meta_hit_for_same_manifest() {
|
||||
let temp = tempfile::tempdir().expect("tempdir");
|
||||
let store = RocksStore::open(temp.path()).expect("open rocksdb");
|
||||
let (
|
||||
manifest,
|
||||
manifest_bytes,
|
||||
manifest_rsync_uri,
|
||||
publication_point_rsync_uri,
|
||||
validation_time,
|
||||
) = load_manifest_fixture();
|
||||
let previous_meta = sample_manifest_meta(
|
||||
&manifest,
|
||||
&manifest_rsync_uri,
|
||||
&publication_point_rsync_uri,
|
||||
&manifest_bytes,
|
||||
validation_time,
|
||||
);
|
||||
store
|
||||
.put_manifest_anti_rollback_meta(&previous_meta)
|
||||
.expect("persist freshness");
|
||||
put_complete_publication_point_current_objects(
|
||||
&store,
|
||||
&manifest,
|
||||
&manifest_rsync_uri,
|
||||
manifest_bytes,
|
||||
&publication_point_rsync_uri,
|
||||
);
|
||||
|
||||
let (_fresh, timing) = try_build_fresh_publication_point_with_timing(
|
||||
&store,
|
||||
&manifest_rsync_uri,
|
||||
&publication_point_rsync_uri,
|
||||
None,
|
||||
&issuer_ca_fixture_der(),
|
||||
Some(issuer_ca_rsync_uri()),
|
||||
validation_time,
|
||||
)
|
||||
.expect("fresh publication point with matching freshness metadata");
|
||||
|
||||
assert!(timing.anti_rollback_meta_hit);
|
||||
assert!(!timing.anti_rollback_meta_miss);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn validate_manifest_embedded_ee_cert_path_rejects_missing_crl_files() {
|
||||
let (manifest, _, _, publication_point_rsync_uri, validation_time) = load_manifest_fixture();
|
||||
let files = locked_files_for_manifest(&manifest, &publication_point_rsync_uri)
|
||||
.into_iter()
|
||||
.filter(|f| !f.rsync_uri.ends_with(".crl"))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let err = validate_manifest_embedded_ee_cert_path(
|
||||
&manifest,
|
||||
&files,
|
||||
&issuer_ca_fixture_der(),
|
||||
Some(issuer_ca_rsync_uri()),
|
||||
validation_time,
|
||||
)
|
||||
.unwrap_err();
|
||||
assert!(matches!(err, ManifestFreshError::NoCrlFiles), "{err}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn validate_manifest_embedded_ee_cert_path_rejects_missing_ee_crldp() {
|
||||
let (mut manifest, _, _, publication_point_rsync_uri, validation_time) =
|
||||
load_manifest_fixture();
|
||||
manifest.signed_object.signed_data.certificates[0]
|
||||
.resource_cert
|
||||
.tbs
|
||||
.extensions
|
||||
.crl_distribution_points_uris = None;
|
||||
let files = locked_files_for_manifest(&manifest, &publication_point_rsync_uri);
|
||||
|
||||
let err = validate_manifest_embedded_ee_cert_path(
|
||||
&manifest,
|
||||
&files,
|
||||
&issuer_ca_fixture_der(),
|
||||
Some(issuer_ca_rsync_uri()),
|
||||
validation_time,
|
||||
)
|
||||
.unwrap_err();
|
||||
assert!(matches!(err, ManifestFreshError::EeCrlDpMissing), "{err}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn validate_manifest_embedded_ee_cert_path_rejects_unlisted_crldp_uri() {
|
||||
let (manifest, _, _, publication_point_rsync_uri, validation_time) = load_manifest_fixture();
|
||||
let mut files = locked_files_for_manifest(&manifest, &publication_point_rsync_uri)
|
||||
.into_iter()
|
||||
.filter(|f| !f.rsync_uri.ends_with(".crl"))
|
||||
.collect::<Vec<_>>();
|
||||
files.push(PackFile::from_bytes_compute_sha256(
|
||||
"rsync://example.test/repo/unrelated.crl",
|
||||
b"dummy".to_vec(),
|
||||
));
|
||||
|
||||
let err = validate_manifest_embedded_ee_cert_path(
|
||||
&manifest,
|
||||
&files,
|
||||
&issuer_ca_fixture_der(),
|
||||
Some(issuer_ca_rsync_uri()),
|
||||
validation_time,
|
||||
)
|
||||
.unwrap_err();
|
||||
assert!(matches!(err, ManifestFreshError::EeCrlNotFound(_)), "{err}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn validate_manifest_embedded_ee_cert_path_rejects_expired_crl() {
|
||||
let (manifest, _, _, publication_point_rsync_uri, _) = load_manifest_fixture();
|
||||
let files = locked_files_for_manifest(&manifest, &publication_point_rsync_uri);
|
||||
let ee = &manifest.signed_object.signed_data.certificates[0];
|
||||
let crldp_uri = ee
|
||||
.resource_cert
|
||||
.tbs
|
||||
.extensions
|
||||
.crl_distribution_points_uris
|
||||
.as_ref()
|
||||
.and_then(|uris| uris.first())
|
||||
.expect("fixture manifest EE CRLDP")
|
||||
.as_str()
|
||||
.to_string();
|
||||
let crl_file = files
|
||||
.iter()
|
||||
.find(|file| file.rsync_uri == crldp_uri)
|
||||
.expect("fixture CRL referenced by manifest EE");
|
||||
let crl =
|
||||
crate::model::crl::RpkixCrl::decode_der(crl_file.bytes().expect("read fixture crl bytes"))
|
||||
.expect("decode fixture crl");
|
||||
let validation_time = crl.next_update.utc;
|
||||
|
||||
let err = validate_manifest_embedded_ee_cert_path(
|
||||
&manifest,
|
||||
&files,
|
||||
&issuer_ca_fixture_der(),
|
||||
Some(issuer_ca_rsync_uri()),
|
||||
validation_time,
|
||||
)
|
||||
.unwrap_err();
|
||||
|
||||
assert!(
|
||||
matches!(
|
||||
err,
|
||||
ManifestFreshError::EeCertPath(
|
||||
crate::validation::cert_path::CertPathError::CrlNotValidAtTime
|
||||
)
|
||||
),
|
||||
"{err}"
|
||||
);
|
||||
}
|
||||
|
||||
fn sample_manifest_meta(
|
||||
manifest: &ManifestObject,
|
||||
uri: &str,
|
||||
_base: &str,
|
||||
bytes: &[u8],
|
||||
now: time::OffsetDateTime,
|
||||
) -> crate::repository::storage::ManifestAntiRollbackMeta {
|
||||
crate::repository::storage::ManifestAntiRollbackMeta {
|
||||
manifest_rsync_uri: uri.into(),
|
||||
manifest_number_be: manifest.manifest.manifest_number.bytes_be.clone(),
|
||||
manifest_this_update: PackTime::from_utc_offset_datetime(manifest.manifest.this_update),
|
||||
manifest_sha256: sha2::Sha256::digest(bytes).to_vec(),
|
||||
updated_at_validation_time: PackTime::from_utc_offset_datetime(now),
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn history_survives_restart_and_rejects_rollback_without_advancing() {
|
||||
for case in 0..4 {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let (manifest, bytes, uri, base, now) = load_manifest_fixture();
|
||||
let mut meta = sample_manifest_meta(&manifest, &uri, &base, &bytes, now);
|
||||
match case {
|
||||
0 => {}
|
||||
1 => {
|
||||
meta.manifest_number_be = vec![0x7f; 20];
|
||||
}
|
||||
2 => {
|
||||
meta.manifest_sha256 = vec![0x55; 32];
|
||||
}
|
||||
3 => {
|
||||
meta.manifest_number_be = vec![0];
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
{
|
||||
let store = RocksStore::open(dir.path()).unwrap();
|
||||
store.put_manifest_anti_rollback_meta(&meta).unwrap();
|
||||
put_complete_publication_point_current_objects(
|
||||
&store,
|
||||
&manifest,
|
||||
&uri,
|
||||
bytes.clone(),
|
||||
&base,
|
||||
);
|
||||
}
|
||||
let store = RocksStore::open(dir.path()).unwrap();
|
||||
assert_eq!(
|
||||
store.get_manifest_anti_rollback_meta(&uri).unwrap(),
|
||||
Some(meta.clone())
|
||||
);
|
||||
let result = try_build_fresh_publication_point_with_timing(
|
||||
&store,
|
||||
&uri,
|
||||
&base,
|
||||
None,
|
||||
&issuer_ca_fixture_der(),
|
||||
Some(issuer_ca_rsync_uri()),
|
||||
now,
|
||||
);
|
||||
match case {
|
||||
0 => {
|
||||
assert!(result.unwrap().1.anti_rollback_meta_hit);
|
||||
}
|
||||
1 | 2 => {
|
||||
assert!(matches!(
|
||||
result,
|
||||
Err(ManifestFreshError::ManifestNumberNotIncreasing { .. })
|
||||
));
|
||||
}
|
||||
3 => {
|
||||
assert!(matches!(
|
||||
result,
|
||||
Err(ManifestFreshError::ThisUpdateNotIncreasing { .. })
|
||||
));
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
assert_eq!(
|
||||
store.get_manifest_anti_rollback_meta(&uri).unwrap(),
|
||||
Some(meta)
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user