Skip to main content

vault_client_rs/types/
transit.rs

1use std::collections::HashMap;
2use std::fmt;
3
4use secrecy::{ExposeSecret, SecretString};
5use serde::{Deserialize, Serialize};
6use zeroize::{Zeroize, ZeroizeOnDrop};
7
8use super::redaction::{RedactionLevel, redact, redaction_level};
9
10#[derive(Debug, Serialize, Default, Clone)]
11pub struct TransitKeyParams {
12    #[serde(rename = "type", skip_serializing_if = "Option::is_none")]
13    pub key_type: Option<String>,
14    #[serde(skip_serializing_if = "Option::is_none")]
15    pub derived: Option<bool>,
16    #[serde(skip_serializing_if = "Option::is_none")]
17    pub convergent_encryption: Option<bool>,
18    #[serde(skip_serializing_if = "Option::is_none")]
19    pub exportable: Option<bool>,
20    #[serde(skip_serializing_if = "Option::is_none")]
21    pub allow_plaintext_backup: Option<bool>,
22    #[serde(skip_serializing_if = "Option::is_none")]
23    pub auto_rotate_period: Option<String>,
24    #[serde(skip_serializing_if = "Option::is_none")]
25    pub key_size: Option<u32>,
26}
27
28#[derive(Debug, Deserialize, Clone)]
29#[non_exhaustive]
30pub struct TransitKeyInfo {
31    #[serde(rename = "type")]
32    pub key_type: String,
33    pub deletion_allowed: bool,
34    pub derived: bool,
35    pub exportable: bool,
36    pub allow_plaintext_backup: bool,
37    #[serde(default)]
38    pub keys: HashMap<String, serde_json::Value>,
39    pub min_decryption_version: u64,
40    pub min_encryption_version: u64,
41    pub name: String,
42    pub supports_encryption: bool,
43    pub supports_decryption: bool,
44    pub supports_derivation: bool,
45    pub supports_signing: bool,
46    #[serde(default)]
47    pub auto_rotate_period: u64,
48    pub latest_version: u64,
49}
50
51#[derive(Debug, Serialize, Default, Clone)]
52pub struct TransitKeyConfig {
53    #[serde(skip_serializing_if = "Option::is_none")]
54    pub min_decryption_version: Option<u64>,
55    #[serde(skip_serializing_if = "Option::is_none")]
56    pub min_encryption_version: Option<u64>,
57    #[serde(skip_serializing_if = "Option::is_none")]
58    pub deletion_allowed: Option<bool>,
59    #[serde(skip_serializing_if = "Option::is_none")]
60    pub exportable: Option<bool>,
61    #[serde(skip_serializing_if = "Option::is_none")]
62    pub allow_plaintext_backup: Option<bool>,
63    #[serde(skip_serializing_if = "Option::is_none")]
64    pub auto_rotate_period: Option<String>,
65}
66
67#[derive(Debug, Deserialize)]
68pub(crate) struct TransitEncryptResponse {
69    pub ciphertext: String,
70}
71
72#[derive(Deserialize, Zeroize, ZeroizeOnDrop)]
73pub(crate) struct TransitDecryptResponse {
74    pub plaintext: SecretString,
75}
76
77impl fmt::Debug for TransitDecryptResponse {
78    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79        f.debug_struct("TransitDecryptResponse")
80            .field("plaintext", &redact(self.plaintext.expose_secret()))
81            .finish()
82    }
83}
84
85#[derive(Debug, Deserialize)]
86pub(crate) struct TransitRewrapResponse {
87    pub ciphertext: String,
88}
89
90#[derive(Serialize, Zeroize, ZeroizeOnDrop)]
91pub struct TransitBatchPlaintext {
92    #[serde(serialize_with = "super::serde_secret::serialize")]
93    pub plaintext: SecretString,
94    #[serde(skip_serializing_if = "Option::is_none")]
95    pub context: Option<String>,
96}
97
98impl Clone for TransitBatchPlaintext {
99    fn clone(&self) -> Self {
100        Self {
101            plaintext: self.plaintext.clone(),
102            context: self.context.clone(),
103        }
104    }
105}
106
107impl fmt::Debug for TransitBatchPlaintext {
108    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109        f.debug_struct("TransitBatchPlaintext")
110            .field("plaintext", &"[REDACTED]")
111            .field("context", &self.context)
112            .finish()
113    }
114}
115
116#[derive(Debug, Deserialize, Serialize, Clone)]
117pub struct TransitBatchCiphertext {
118    pub ciphertext: String,
119    #[serde(default, skip_serializing_if = "String::is_empty")]
120    pub error: String,
121}
122
123#[derive(Debug, Serialize, Default, Clone)]
124pub struct TransitSignParams {
125    #[serde(skip_serializing_if = "Option::is_none")]
126    pub hash_algorithm: Option<String>,
127    #[serde(skip_serializing_if = "Option::is_none")]
128    pub signature_algorithm: Option<String>,
129    #[serde(skip_serializing_if = "Option::is_none")]
130    pub marshaling_algorithm: Option<String>,
131    #[serde(skip_serializing_if = "Option::is_none")]
132    pub prehashed: Option<bool>,
133    #[serde(skip_serializing_if = "Option::is_none")]
134    pub salt_length: Option<String>,
135}
136
137#[derive(Debug, Deserialize)]
138pub(crate) struct TransitSignResponse {
139    pub signature: String,
140}
141
142#[derive(Debug, Deserialize)]
143pub(crate) struct TransitVerifyResponse {
144    pub valid: bool,
145}
146
147#[derive(Debug, Deserialize)]
148pub(crate) struct TransitHashResponse {
149    pub sum: String,
150}
151
152#[derive(Debug, Deserialize)]
153pub(crate) struct TransitHmacResponse {
154    pub hmac: String,
155}
156
157#[derive(Debug, Deserialize)]
158pub(crate) struct TransitRandomResponse {
159    pub random_bytes: String,
160}
161
162#[derive(Deserialize, Zeroize, ZeroizeOnDrop)]
163#[non_exhaustive]
164pub struct TransitDataKey {
165    pub ciphertext: String,
166    pub plaintext: Option<SecretString>,
167}
168
169impl Clone for TransitDataKey {
170    fn clone(&self) -> Self {
171        Self {
172            ciphertext: self.ciphertext.clone(),
173            plaintext: self.plaintext.clone(),
174        }
175    }
176}
177
178impl fmt::Debug for TransitDataKey {
179    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
180        f.debug_struct("TransitDataKey")
181            .field("ciphertext", &self.ciphertext)
182            .field(
183                "plaintext",
184                &self.plaintext.as_ref().map(|s| redact(s.expose_secret())),
185            )
186            .finish()
187    }
188}
189
190#[derive(Deserialize, Zeroize, ZeroizeOnDrop)]
191#[non_exhaustive]
192pub struct TransitExportedKey {
193    pub name: String,
194    #[zeroize(skip)]
195    pub keys: HashMap<String, SecretString>,
196    #[serde(rename = "type")]
197    pub key_type: String,
198}
199
200impl Clone for TransitExportedKey {
201    fn clone(&self) -> Self {
202        Self {
203            name: self.name.clone(),
204            keys: self.keys.clone(),
205            key_type: self.key_type.clone(),
206        }
207    }
208}
209
210impl fmt::Debug for TransitExportedKey {
211    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
212        match redaction_level() {
213            RedactionLevel::Full => {
214                let summary = format!("[REDACTED; {} versions]", self.keys.len());
215                f.debug_struct("TransitExportedKey")
216                    .field("name", &self.name)
217                    .field("keys", &summary)
218                    .field("key_type", &self.key_type)
219                    .finish()
220            }
221            _ => {
222                let map: HashMap<String, String> = self
223                    .keys
224                    .iter()
225                    .map(|(k, v)| (k.clone(), redact(v.expose_secret())))
226                    .collect();
227                f.debug_struct("TransitExportedKey")
228                    .field("name", &self.name)
229                    .field("keys", &map)
230                    .field("key_type", &self.key_type)
231                    .finish()
232            }
233        }
234    }
235}
236
237#[derive(Debug, Deserialize, Clone)]
238#[non_exhaustive]
239pub struct TransitCacheConfig {
240    pub size: u64,
241}
242
243#[derive(Debug, Deserialize)]
244pub(crate) struct TransitBatchEncryptResponse {
245    #[serde(default)]
246    pub batch_results: Vec<TransitBatchCiphertext>,
247}
248
249#[derive(Debug, Deserialize)]
250pub(crate) struct TransitBatchDecryptResponse {
251    #[serde(default)]
252    pub batch_results: Vec<TransitBatchDecryptItem>,
253}
254
255#[derive(Deserialize, Zeroize, ZeroizeOnDrop)]
256#[non_exhaustive]
257pub struct TransitBatchDecryptItem {
258    pub plaintext: Option<SecretString>,
259    #[serde(default)]
260    pub error: String,
261}
262
263impl Clone for TransitBatchDecryptItem {
264    fn clone(&self) -> Self {
265        Self {
266            plaintext: self.plaintext.clone(),
267            error: self.error.clone(),
268        }
269    }
270}
271
272impl fmt::Debug for TransitBatchDecryptItem {
273    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
274        f.debug_struct("TransitBatchDecryptItem")
275            .field(
276                "plaintext",
277                &self.plaintext.as_ref().map(|s| redact(s.expose_secret())),
278            )
279            .field("error", &self.error)
280            .finish()
281    }
282}
283
284#[derive(Deserialize, Zeroize, ZeroizeOnDrop)]
285pub(crate) struct TransitBackupResponse {
286    pub backup: SecretString,
287}
288
289impl fmt::Debug for TransitBackupResponse {
290    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
291        f.debug_struct("TransitBackupResponse")
292            .field("backup", &redact(self.backup.expose_secret()))
293            .finish()
294    }
295}
296
297// --- Batch sign/verify ---
298
299#[derive(Debug, Serialize, Clone)]
300pub struct TransitBatchSignInput {
301    pub input: String,
302    #[serde(skip_serializing_if = "Option::is_none")]
303    pub context: Option<String>,
304}
305
306#[derive(Debug, Deserialize, Clone)]
307#[non_exhaustive]
308pub struct TransitBatchSignResult {
309    pub signature: String,
310    #[serde(default)]
311    pub error: String,
312}
313
314#[derive(Debug, Serialize, Clone)]
315pub struct TransitBatchVerifyInput {
316    pub input: String,
317    pub signature: String,
318    #[serde(skip_serializing_if = "Option::is_none")]
319    pub context: Option<String>,
320}
321
322#[derive(Debug, Deserialize, Clone)]
323#[non_exhaustive]
324pub struct TransitBatchVerifyResult {
325    pub valid: bool,
326    #[serde(default)]
327    pub error: String,
328}
329
330#[derive(Debug, Deserialize)]
331pub(crate) struct TransitBatchSignResponse {
332    #[serde(default)]
333    pub batch_results: Vec<TransitBatchSignResult>,
334}
335
336#[derive(Debug, Deserialize)]
337pub(crate) struct TransitBatchVerifyResponse {
338    #[serde(default)]
339    pub batch_results: Vec<TransitBatchVerifyResult>,
340}