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