1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
14pub enum KeyType {
15 #[serde(rename = "ed25519")]
17 Ed25519,
18 #[serde(rename = "ed25519-nkey")]
20 Ed25519Nkey,
21 #[serde(rename = "rsa-2048")]
23 Rsa2048,
24 #[serde(rename = "ecdsa-p256")]
26 EcdsaP256,
27 #[serde(rename = "ecdsa-p384")]
29 EcdsaP384,
30 #[serde(rename = "ecdsa-p521")]
32 EcdsaP521,
33 #[serde(rename = "ml-dsa-44")]
35 MlDsa44,
36 #[serde(rename = "ml-dsa-65")]
38 MlDsa65,
39 #[serde(rename = "ml-dsa-87")]
41 MlDsa87,
42 #[serde(rename = "ml-kem-512")]
44 MlKem512,
45 #[serde(rename = "ml-kem-768")]
47 MlKem768,
48 #[serde(rename = "ml-kem-1024")]
50 MlKem1024,
51}
52
53impl std::fmt::Display for KeyType {
54 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
55 f.write_str(match self {
56 Self::Ed25519 => "ed25519",
57 Self::Ed25519Nkey => "ed25519-nkey",
58 Self::Rsa2048 => "rsa-2048",
59 Self::EcdsaP256 => "ecdsa-p256",
60 Self::EcdsaP384 => "ecdsa-p384",
61 Self::EcdsaP521 => "ecdsa-p521",
62 Self::MlDsa44 => "ml-dsa-44",
63 Self::MlDsa65 => "ml-dsa-65",
64 Self::MlDsa87 => "ml-dsa-87",
65 Self::MlKem512 => "ml-kem-512",
66 Self::MlKem768 => "ml-kem-768",
67 Self::MlKem1024 => "ml-kem-1024",
68 })
69 }
70}
71
72#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
74pub enum AeadAlgorithm {
75 #[serde(rename = "chacha20-poly1305")]
77 Chacha20Poly1305,
78 #[serde(rename = "aes-256-gcm")]
80 Aes256Gcm,
81}
82
83impl std::fmt::Display for AeadAlgorithm {
84 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
85 f.write_str(match self {
86 Self::Chacha20Poly1305 => "chacha20-poly1305",
87 Self::Aes256Gcm => "aes-256-gcm",
88 })
89 }
90}
91
92#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
94#[serde(rename_all = "snake_case")]
95pub enum CatalogKind {
96 Signing,
98 Value,
100 Encryption,
102}
103
104#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
106#[serde(rename_all = "snake_case")]
107pub enum KeyMaterial {
108 Ed25519Seed(#[serde(with = "serde_bytes")] Vec<u8>),
110 Pkcs8Der(#[serde(with = "serde_bytes")] Vec<u8>),
112}
113
114#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
117pub struct CiphertextEnvelope {
118 pub alg: AeadAlgorithm,
120 pub key_version: u32,
122 #[serde(with = "serde_bytes")]
124 pub nonce: Vec<u8>,
125 #[serde(with = "serde_bytes")]
127 pub ciphertext: Vec<u8>,
128}
129
130#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
132pub struct CatalogEntry {
133 pub name: String,
135 pub kind: CatalogKind,
137 #[serde(default, skip_serializing_if = "Option::is_none")]
139 pub key_type: Option<KeyType>,
140 pub latest_version: u32,
142}
143
144#[cfg(test)]
145mod tests {
146 use super::{AeadAlgorithm, KeyMaterial, KeyType};
147 use serde_json::json;
148
149 #[test]
150 fn key_type_and_algorithm_wire_spellings() {
151 assert_eq!(
152 serde_json::to_value(KeyType::Ed25519).unwrap(),
153 json!("ed25519")
154 );
155 assert_eq!(
156 serde_json::to_value(KeyType::Ed25519Nkey).unwrap(),
157 json!("ed25519-nkey")
158 );
159 assert_eq!(
160 serde_json::to_value(KeyType::Rsa2048).unwrap(),
161 json!("rsa-2048")
162 );
163 assert_eq!(
164 serde_json::to_value(KeyType::EcdsaP256).unwrap(),
165 json!("ecdsa-p256")
166 );
167 assert_eq!(
168 serde_json::to_value(KeyType::EcdsaP384).unwrap(),
169 json!("ecdsa-p384")
170 );
171 assert_eq!(
172 serde_json::to_value(KeyType::EcdsaP521).unwrap(),
173 json!("ecdsa-p521")
174 );
175 assert_eq!(
176 serde_json::to_value(KeyType::MlDsa65).unwrap(),
177 json!("ml-dsa-65")
178 );
179 assert_eq!(
180 serde_json::to_value(KeyType::MlKem768).unwrap(),
181 json!("ml-kem-768")
182 );
183 assert_eq!(
184 serde_json::from_value::<KeyType>(json!("ml-dsa-44")).unwrap(),
185 KeyType::MlDsa44
186 );
187 assert_eq!(
188 serde_json::from_value::<KeyType>(json!("ml-kem-1024")).unwrap(),
189 KeyType::MlKem1024
190 );
191 assert_eq!(
192 serde_json::to_value(AeadAlgorithm::Aes256Gcm).unwrap(),
193 json!("aes-256-gcm")
194 );
195 assert_eq!(
196 serde_json::to_value(AeadAlgorithm::Chacha20Poly1305).unwrap(),
197 json!("chacha20-poly1305")
198 );
199 }
200
201 #[test]
202 fn key_material_is_tagged_union() {
203 let v = serde_json::to_value(KeyMaterial::Ed25519Seed(vec![1, 2, 3])).unwrap();
204 assert_eq!(v, json!({"ed25519_seed":[1,2,3]}));
205 let back: KeyMaterial = serde_json::from_value(v).unwrap();
206 assert_eq!(back, KeyMaterial::Ed25519Seed(vec![1, 2, 3]));
207 }
208}