pic_continuity/artifacts/mod.rs
1/*
2 * Copyright Nitro Agility S.r.l.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//! Profile 0.2 artifacts, one file per protocol object:
18//!
19//! - [`pca`] — PIC PCA COSE, the signed trusted authority checkpoint;
20//! - [`continuity`] — PIC Continuity COSE, the signed continuity container;
21//! - [`transition`] — PIC Continuity Transition COSE, the workload-signed
22//! causal authority transition;
23//! - [`token`] — the PIC Token JWT external envelope.
24//!
25//! Every signed-artifact hash in Profile 0.2 (`root.pca_hash`,
26//! `predecessor.hash`) is SHA-256 over the **exact signed artifact bytes** —
27//! never over a decoded payload or a re-serialized structure. The helpers
28//! here only accept raw byte slices, so the API shape enforces the rule.
29
30pub mod continuity;
31pub mod pca;
32pub mod token;
33pub mod transition;
34
35pub use continuity::{ContinuityRoot, PicContinuityCose, PicContinuityPayload};
36pub use pca::{PcaChallenge, PicPcaCose, PicPcaPayload};
37pub use transition::{
38 AttenuationsWire, BitmapAttenuation, ContractAdditions, PicTransitionCose,
39 PicTransitionPayload, Predecessor, ProofOfRelationship, TransitionChallenge,
40};
41
42use crate::error::RejectReason;
43use sha2::{Digest, Sha256};
44
45/// SHA-256 over exact signed artifact bytes.
46pub fn artifact_sha256(exact_signed_bytes: &[u8]) -> Vec<u8> {
47 Sha256::digest(exact_signed_bytes).to_vec()
48}
49
50/// Rejects a payload whose `profile` member is not [`crate::PROFILE_0_2`].
51fn check_profile(artifact: &'static str, got: &str) -> Result<(), RejectReason> {
52 if got == crate::PROFILE_0_2 {
53 Ok(())
54 } else {
55 Err(RejectReason::ProfileMismatch {
56 artifact,
57 expected: crate::PROFILE_0_2.to_string(),
58 got: got.to_string(),
59 })
60 }
61}