pub mod observation;
use crate::fleet_ensure::{
model::release::FleetReleaseReviewRecord,
policy::release::{FleetReleaseError, validate_review},
view::release::FleetReleaseObservation,
};
use sha2_host::{Digest, Sha256};
pub fn prepare_review(
mut review: FleetReleaseReviewRecord,
observed: &FleetReleaseObservation,
) -> Result<FleetReleaseReviewRecord, FleetReleaseError> {
validate_review(&review, observed)?;
review.review_sha256 = [0; 32];
review.review_sha256 = digest(&review)?;
Ok(review)
}
pub fn verify_review(
review: &FleetReleaseReviewRecord,
observed: &FleetReleaseObservation,
) -> Result<(), FleetReleaseError> {
verify_digest(review)?;
validate_review(review, observed)
}
pub fn verify_reset_custody(
review: &FleetReleaseReviewRecord,
observed: &FleetReleaseObservation,
) -> Result<(), FleetReleaseError> {
verify_digest(review)?;
crate::fleet_ensure::policy::release::validate_reset_custody(review, observed)
}
pub fn verify_held_capacity(
review: &FleetReleaseReviewRecord,
observed: &FleetReleaseObservation,
) -> Result<(), FleetReleaseError> {
verify_digest(review)?;
crate::fleet_ensure::policy::release::validate_held_capacity(review, observed)
}
fn verify_digest(review: &FleetReleaseReviewRecord) -> Result<(), FleetReleaseError> {
let mut unsigned = review.clone();
unsigned.review_sha256 = [0; 32];
if review.review_sha256 != digest(&unsigned)? {
return Err(FleetReleaseError::Authority);
}
Ok(())
}
fn digest(review: &FleetReleaseReviewRecord) -> Result<[u8; 32], FleetReleaseError> {
let mut hash = Sha256::new();
hash.update(b"canic.fleet-release.review.v1\0");
hash.update(serde_json::to_vec(review).map_err(|_| FleetReleaseError::Authority)?);
Ok(hash.finalize().into())
}