From 59ae10b3323f88354d3b74c7492874f5dc65a4d4 Mon Sep 17 00:00:00 2001 From: Amanjeev Sethi Date: Tue, 21 May 2024 10:44:21 -0400 Subject: [PATCH] Add revocation support for hashes Ticket: https://ferroussystems.clickup.com/t/86947z6fp --- Cargo.lock | 1 + crates/criticaltrust/src/keys/public.rs | 2 ++ crates/criticaltrust/src/manifests.rs | 15 +++++++++++++++ crates/mock-download-server/Cargo.toml | 1 + crates/mock-download-server/src/handlers.rs | 9 ++++++++- crates/mock-download-server/src/lib.rs | 9 ++++++++- 6 files changed, 35 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 446f857e..ea4dcd81 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1354,6 +1354,7 @@ dependencies = [ "criticaltrust", "serde", "serde_json", + "time", "tiny_http", ] diff --git a/crates/criticaltrust/src/keys/public.rs b/crates/criticaltrust/src/keys/public.rs index 62deda3c..d03fc199 100644 --- a/crates/criticaltrust/src/keys/public.rs +++ b/crates/criticaltrust/src/keys/public.rs @@ -86,6 +86,8 @@ pub enum KeyRole { Packages, /// `redirects` key role, used to sign dynamic server redirects. Redirects, + /// `revocation` key role, used to sign revoked content hashes. + Revocation, /// `root` key role, used to sign other keys. Root, #[serde(other)] diff --git a/crates/criticaltrust/src/manifests.rs b/crates/criticaltrust/src/manifests.rs index 32803728..c8c974aa 100644 --- a/crates/criticaltrust/src/manifests.rs +++ b/crates/criticaltrust/src/manifests.rs @@ -7,6 +7,7 @@ use crate::keys::{KeyRole, PublicKey}; use crate::signatures::{Signable, SignedPayload}; use serde::de::Error as _; use serde::{Deserialize, Serialize}; +use time::OffsetDateTime; /// Typed representation of a manifest version number. /// @@ -154,12 +155,26 @@ pub struct PackageFile { pub needs_proxy: bool, } +// Revocations + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] +pub struct RevocationInfo { + pub revoked_content_sha256: Vec, + pub expires_at: OffsetDateTime, +} + +impl Signable for RevocationInfo { + const SIGNED_BY_ROLE: KeyRole = KeyRole::Revocation; +} + // Keys #[derive(Debug, Serialize, Deserialize)] pub struct KeysManifest { pub version: ManifestVersion<1>, pub keys: Vec>, + pub revoked_signatures: SignedPayload, } #[cfg(test)] diff --git a/crates/mock-download-server/Cargo.toml b/crates/mock-download-server/Cargo.toml index 4439e22d..b28626a5 100644 --- a/crates/mock-download-server/Cargo.toml +++ b/crates/mock-download-server/Cargo.toml @@ -12,3 +12,4 @@ criticaltrust = { path = "../criticaltrust" } serde = { version = "1.0.136", features = ["derive"] } serde_json = "1.0.79" tiny_http = { version = "0.12.0", default-features = false, features = ["rustls"] } +time = { version = "0.3.7", features = ["std", "serde", "serde-well-known"] } diff --git a/crates/mock-download-server/src/handlers.rs b/crates/mock-download-server/src/handlers.rs index 1fbaa306..fc54cd0c 100644 --- a/crates/mock-download-server/src/handlers.rs +++ b/crates/mock-download-server/src/handlers.rs @@ -3,7 +3,9 @@ use crate::Serialize; use crate::{AuthenticationToken, Data}; -use criticaltrust::manifests::ManifestVersion; +use criticaltrust::manifests::{ManifestVersion, RevocationInfo}; +use criticaltrust::signatures::SignedPayload; +use time::{Duration, OffsetDateTime}; use tiny_http::{Header, Method, Request, Response, ResponseBox, StatusCode}; pub(crate) fn handle_request(data: &Data, req: &Request) -> ResponseBox { @@ -39,6 +41,11 @@ fn handle_v1_keys(data: &Data) -> Result { Ok(Resp::json(&criticaltrust::manifests::KeysManifest { version: ManifestVersion, keys: data.keys.clone(), + revoked_signatures: SignedPayload::new(&RevocationInfo { + revoked_content_sha256: Vec::new(), + expires_at: OffsetDateTime::now_utc() + Duration::days(99), + }) + .unwrap(), })) } diff --git a/crates/mock-download-server/src/lib.rs b/crates/mock-download-server/src/lib.rs index ee96347a..9b053df8 100644 --- a/crates/mock-download-server/src/lib.rs +++ b/crates/mock-download-server/src/lib.rs @@ -6,11 +6,12 @@ mod server; pub use crate::server::MockServer; use criticaltrust::keys::PublicKey; -use criticaltrust::manifests::ReleaseManifest; +use criticaltrust::manifests::{ReleaseManifest, RevocationInfo}; use criticaltrust::signatures::SignedPayload; use serde::Serialize; use std::borrow::Cow; use std::collections::HashMap; +use time::{Duration, OffsetDateTime}; #[derive(Serialize, Clone)] #[serde(rename_all = "kebab-case")] @@ -23,6 +24,7 @@ pub struct AuthenticationToken { pub struct Data { pub tokens: HashMap, pub keys: Vec>, + pub revoked_signatures: SignedPayload, pub release_manifests: HashMap<(String, String), ReleaseManifest>, } @@ -31,6 +33,11 @@ pub fn new() -> Builder { data: Data { tokens: HashMap::new(), keys: Vec::new(), + revoked_signatures: SignedPayload::new(&RevocationInfo { + revoked_content_sha256: Vec::new(), + expires_at: OffsetDateTime::now_utc() + Duration::days(99), + }) + .unwrap(), release_manifests: HashMap::new(), }, }