ic_backup/ops/persistence/download_journal/integrity/
mod.rs1use super::super::json::read_record;
4use super::{DownloadJournalError, DownloadJournalGuard};
5use crate::{
6 model::{
7 artifacts::ChecksumError,
8 download_journal::{DownloadJournalRecord, MAX_DOWNLOAD_JOURNAL_BYTES},
9 operation_plan::OperationPlanRecord,
10 },
11 ops::{
12 artifacts::{ArtifactError, checksum_directory},
13 persistence::{OperationPlanPersistenceError, PersistenceError, read_operation_plan},
14 },
15 policy::download_integrity::{DownloadIntegrityPolicyError, validate},
16};
17use thiserror::Error;
18
19impl DownloadJournalGuard<'_> {
20 pub(super) fn verify_manifest_source(
22 &self,
23 plan: &OperationPlanRecord,
24 ) -> Result<(), DownloadIntegrityError> {
25 self.admit_integrity_original(plan)?;
26 let expected = validate(plan, &self.record)?;
27 self.check_artifact_parent()?;
28 let path = self
29 .layout
30 .root()
31 .join(self.record.artifacts()[0].artifact_path());
32 checksum_directory(&path)?.verify(expected.hash())?;
33 self.admit_integrity_original(plan)?;
36 Ok(())
37 }
38
39 pub(super) fn admit_integrity_original(
42 &self,
43 plan: &OperationPlanRecord,
44 ) -> Result<(), DownloadIntegrityError> {
45 self.check_usable()?;
46 read_operation_plan(self.layout, &plan.digest())?;
47 self.require_unchanged_integrity_journal()
48 }
49
50 pub(super) fn require_unchanged_integrity_journal(&self) -> Result<(), DownloadIntegrityError> {
51 let retained: DownloadJournalRecord =
52 read_record(&self.path(), MAX_DOWNLOAD_JOURNAL_BYTES)?;
53 if retained != self.record {
54 return Err(DownloadIntegrityError::JournalChanged);
55 }
56 Ok(())
57 }
58}
59
60#[derive(Debug, Error)]
62pub enum DownloadIntegrityError {
63 #[error("retained download journal changed during integrity verification")]
65 JournalChanged,
66 #[error(transparent)]
68 Journal(#[from] DownloadJournalError),
69 #[error(transparent)]
71 Plan(#[from] OperationPlanPersistenceError),
72 #[error(transparent)]
74 Policy(#[from] DownloadIntegrityPolicyError),
75 #[error(transparent)]
77 Persistence(#[from] PersistenceError),
78 #[error(transparent)]
80 Artifact(#[from] ArtifactError),
81 #[error(transparent)]
83 Checksum(#[from] ChecksumError),
84}
85
86#[cfg(all(test, unix))]
87mod tests;