canon_protocol/
signature.rs1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use std::collections::HashMap;
4
5#[derive(Debug, Serialize, Deserialize)]
8pub struct CanonSignature {
9 pub signature_version: String,
10 pub manifest_hash: String,
11 pub signature: SignatureData,
12 #[serde(skip_serializing_if = "Option::is_none")]
13 pub metadata: Option<SignatureMetadata>,
14}
15
16#[derive(Debug, Clone, Serialize, Deserialize)]
18#[serde(rename_all = "kebab-case")]
19pub enum SignatureAlgorithm {
20 #[serde(rename = "ed25519")]
21 Ed25519,
22 #[serde(rename = "rsa-4096")]
23 Rsa4096,
24}
25
26#[derive(Debug, Serialize, Deserialize)]
27pub struct SignatureData {
28 pub algorithm: SignatureAlgorithm,
29 pub key_id: String, pub signature: String,
31 pub signed_at: DateTime<Utc>,
32}
33
34#[derive(Debug, Serialize, Deserialize)]
36pub struct SignatureMetadata {
37 #[serde(skip_serializing_if = "Option::is_none")]
38 pub tool: Option<String>,
39 #[serde(skip_serializing_if = "Option::is_none")]
40 pub environment: Option<SignatureEnvironment>,
41 #[serde(skip_serializing_if = "Option::is_none")]
42 pub notes: Option<String>,
43}
44
45#[derive(Debug, Clone, Serialize, Deserialize)]
47#[serde(rename_all = "lowercase")]
48pub enum SignatureEnvironment {
49 Development,
50 Staging,
51 Production,
52}
53
54#[derive(Debug, Serialize, Deserialize)]
57pub struct PublisherKeys {
58 pub version: String,
59 pub keys: HashMap<String, PublicKey>,
60 #[serde(skip_serializing_if = "Option::is_none")]
61 pub revoked_keys: Option<HashMap<String, RevokedKey>>,
62 #[serde(skip_serializing_if = "Option::is_none")]
63 pub contact: Option<SecurityContact>,
64 #[serde(skip_serializing_if = "Option::is_none")]
65 pub metadata: Option<KeysMetadata>,
66}
67
68#[derive(Debug, Clone, Serialize, Deserialize)]
70#[serde(rename_all = "kebab-case")]
71pub enum KeyAlgorithm {
72 #[serde(rename = "ed25519")]
73 Ed25519,
74 #[serde(rename = "rsa-4096")]
75 Rsa4096,
76}
77
78#[derive(Debug, Clone, Serialize, Deserialize)]
80#[serde(rename_all = "lowercase")]
81pub enum KeyUsage {
82 Signing,
83 Encryption,
84 Both,
85}
86
87#[derive(Debug, Serialize, Deserialize)]
88pub struct PublicKey {
89 pub algorithm: KeyAlgorithm,
90 pub public_key: String,
91 pub created_at: DateTime<Utc>,
92 #[serde(skip_serializing_if = "Option::is_none")]
93 pub expires_at: Option<DateTime<Utc>>,
94 #[serde(default)]
95 pub revoked: bool,
96 pub usage: KeyUsage,
97 #[serde(skip_serializing_if = "Option::is_none")]
98 pub comment: Option<String>,
99}
100
101#[derive(Debug, Serialize, Deserialize)]
103pub struct RevokedKey {
104 pub revoked_at: DateTime<Utc>,
105 pub reason: RevocationReason,
106 #[serde(skip_serializing_if = "Option::is_none")]
107 pub comment: Option<String>,
108}
109
110#[derive(Debug, Clone, Serialize, Deserialize)]
112#[serde(rename_all = "snake_case")]
113pub enum RevocationReason {
114 KeyRotation,
115 Compromise,
116 Superseded,
117 Cessation,
118 Other,
119}
120
121#[derive(Debug, Serialize, Deserialize)]
123pub struct SecurityContact {
124 #[serde(skip_serializing_if = "Option::is_none")]
125 pub email: Option<String>,
126 #[serde(skip_serializing_if = "Option::is_none")]
127 pub url: Option<String>,
128}
129
130#[derive(Debug, Serialize, Deserialize)]
132pub struct KeysMetadata {
133 #[serde(skip_serializing_if = "Option::is_none")]
134 pub rotation_policy: Option<String>,
135 #[serde(skip_serializing_if = "Option::is_none")]
136 pub backup_keys: Option<Vec<String>>,
137}
138
139pub use PublicKey as PublisherKey;