1use bitflags::bitflags;
4use serde::{
5 de::{self, Deserialize, Deserializer, Visitor},
6 ser::{Serialize, Serializer},
7};
8use std::{
9 fmt::{self, Display},
10 str::{self, FromStr},
11};
12
13bitflags! {
14 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
18 pub struct Capability: u64 {
19 const DERIVE_ECDH = 0x800;
21
22 const DECRYPT_OAEP = 0x400;
24
25 const DECRYPT_PKCS = 0x200;
27
28 const GENERATE_ASYMMETRIC_KEY = 0x10;
30
31 const SIGN_ECDSA = 0x80;
33
34 const SIGN_EDDSA = 0x100;
36
37 const SIGN_PKCS = 0x20;
39
40 const SIGN_PSS = 0x40;
42
43 const SIGN_ATTESTATION_CERTIFICATE = 0x4_0000_0000;
46
47 const GET_LOG_ENTRIES = 0x100_0000;
49
50 const DELETE_ASYMMETRIC_KEY = 0x200_0000_0000;
52
53 const DELETE_AUTHENTICATION_KEY = 0x100_0000_0000;
55
56 const DELETE_HMAC_KEY = 0x800_0000_0000;
58
59 const DELETE_OPAQUE = 0x80_0000_0000;
61
62 const DELETE_OTP_AEAD_KEY = 0x2000_0000_0000;
64
65 const DELETE_TEMPLATE = 0x1000_0000_0000;
67
68 const DELETE_WRAP_KEY = 0x400_0000_0000;
70
71 const EXPORTABLE_UNDER_WRAP = 0x1_0000;
73
74 const EXPORT_WRAPPED = 0x1000;
76
77 const GENERATE_OTP_AEAD_KEY = 0x10_0000_0000;
79
80 const GENERATE_WRAP_KEY = 0x8000;
82
83 const GET_OPAQUE = 0x1;
85
86 const GET_OPTION = 0x4_0000;
88
89 const GET_PSEUDO_RANDOM = 0x8_0000;
91
92 const GET_TEMPLATE = 0x400_0000;
94
95 const GENERATE_HMAC_KEY = 0x20_0000;
97
98 const SIGN_HMAC = 0x40_0000;
100
101 const VERIFY_HMAC = 0x80_0000;
103
104 const IMPORT_WRAPPED = 0x2000;
106
107 const CREATE_OTP_AEAD = 0x4000_0000;
109
110 const RANDOMIZE_OTP_AEAD = 0x8000_0000;
112
113 const REWRAP_FROM_OTP_AEAD_KEY = 0x1_0000_0000;
115
116 const REWRAP_TO_OTP_AEAD_KEY = 0x2_0000_0000;
118
119 const DECRYPT_OTP = 0x2000_0000;
121
122 const PUT_ASYMMETRIC_KEY = 0x8;
124
125 const PUT_AUTHENTICATION_KEY = 0x4;
127
128 const PUT_HMAC_KEY = 0x10_0000;
130
131 const PUT_OPAQUE = 0x2;
133
134 const PUT_OPTION = 0x2_0000;
136
137 const PUT_OTP_AEAD_KEY = 0x8_0000_0000;
139
140 const PUT_TEMPLATE = 0x800_0000;
142
143 const PUT_WRAP_KEY = 0x4000;
145
146 const RESET_DEVICE = 0x1000_0000;
148
149 const SIGN_SSH_CERTIFICATE = 0x200_0000;
151
152 const UNWRAP_DATA = 0x40_0000_0000;
154
155 const WRAP_DATA = 0x20_0000_0000;
157
158 const CHANGE_AUTHENTICATION_KEY = 0x4000_0000_0000;
160
161 const UNKNOWN_CAPABILITY_47 = 0x8000_0000_0000;
163
164 const UNKNOWN_CAPABILITY_48 = 0x1_0000_0000_0000;
166
167 const UNKNOWN_CAPABILITY_49 = 0x2_0000_0000_0000;
169
170 const UNKNOWN_CAPABILITY_50 = 0x4_0000_0000_0000;
172
173 const UNKNOWN_CAPABILITY_51 = 0x8_0000_0000_0000;
175
176 const UNKNOWN_CAPABILITY_52 = 0x10_0000_0000_0000;
178
179 const UNKNOWN_CAPABILITY_53 = 0x20_0000_0000_0000;
181
182 const UNKNOWN_CAPABILITY_54 = 0x40_0000_0000_0000;
184
185 const UNKNOWN_CAPABILITY_55 = 0x80_0000_0000_0000;
187
188 const UNKNOWN_CAPABILITY_56 = 0x100_0000_0000_0000;
190
191 const UNKNOWN_CAPABILITY_57 = 0x200_0000_0000_0000;
193
194 const UNKNOWN_CAPABILITY_58 = 0x400_0000_0000_0000;
196
197 const UNKNOWN_CAPABILITY_59 = 0x800_0000_0000_0000;
199
200 const UNKNOWN_CAPABILITY_60 = 0x1000_0000_0000_0000;
202
203 const UNKNOWN_CAPABILITY_61 = 0x2000_0000_0000_0000;
205
206 const UNKNOWN_CAPABILITY_62 = 0x4000_0000_0000_0000;
208
209 const UNKNOWN_CAPABILITY_63 = 0x8000_0000_0000_0000;
211 }
212}
213
214impl Default for Capability {
215 fn default() -> Self {
216 Capability::empty()
217 }
218}
219
220impl Display for Capability {
221 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
222 let s = match *self {
223 Capability::DERIVE_ECDH => "derive-ecdh",
224 Capability::DECRYPT_OAEP => "decrypt-oaep",
225 Capability::DECRYPT_PKCS => "decrypt-pkcs",
226 Capability::GENERATE_ASYMMETRIC_KEY => "generate-asymmetric-key",
227 Capability::SIGN_ECDSA => "sign-ecdsa",
228 Capability::SIGN_EDDSA => "sign-eddsa",
229 Capability::SIGN_PKCS => "sign-pkcs",
230 Capability::SIGN_PSS => "sign-pss",
231 Capability::SIGN_ATTESTATION_CERTIFICATE => "sign-attestation-certificate",
232 Capability::GET_LOG_ENTRIES => "get-log-entries",
233 Capability::DELETE_ASYMMETRIC_KEY => "delete-asymmetric-key",
234 Capability::DELETE_AUTHENTICATION_KEY => "delete-authentication-key",
235 Capability::DELETE_HMAC_KEY => "delete-hmac-key",
236 Capability::DELETE_OPAQUE => "delete-opaque",
237 Capability::DELETE_OTP_AEAD_KEY => "delete-otp-aead-key",
238 Capability::DELETE_TEMPLATE => "delete-template",
239 Capability::DELETE_WRAP_KEY => "delete-wrap-key",
240 Capability::EXPORTABLE_UNDER_WRAP => "exportable-under-wrap",
241 Capability::EXPORT_WRAPPED => "export-wrapped",
242 Capability::GENERATE_OTP_AEAD_KEY => "generate-otp-aead-key",
243 Capability::GENERATE_WRAP_KEY => "generate-wrap-key",
244 Capability::GET_OPAQUE => "get-opaque",
245 Capability::GET_OPTION => "get-option",
246 Capability::GET_PSEUDO_RANDOM => "get-pseudo-random",
247 Capability::GET_TEMPLATE => "get-template",
248 Capability::GENERATE_HMAC_KEY => "generate-hmac-key",
249 Capability::SIGN_HMAC => "sign-hmac",
250 Capability::VERIFY_HMAC => "verify-hmac",
251 Capability::IMPORT_WRAPPED => "import-wrapped",
252 Capability::CREATE_OTP_AEAD => "create-otp-aead",
253 Capability::RANDOMIZE_OTP_AEAD => "randomize-otp-aead",
254 Capability::REWRAP_FROM_OTP_AEAD_KEY => "rewrap-from-otp-aead-key",
255 Capability::REWRAP_TO_OTP_AEAD_KEY => "rewrap-to-otp-aead-key",
256 Capability::DECRYPT_OTP => "decrypt-otp",
257 Capability::PUT_ASYMMETRIC_KEY => "put-asymmetric-key",
258 Capability::PUT_AUTHENTICATION_KEY => "put-authentication-key",
259 Capability::PUT_HMAC_KEY => "put-hmac-key",
260 Capability::PUT_OPAQUE => "put-opaque",
261 Capability::PUT_OPTION => "set-option",
262 Capability::PUT_OTP_AEAD_KEY => "put-otp-aead-key",
263 Capability::PUT_TEMPLATE => "put-template",
264 Capability::PUT_WRAP_KEY => "put-wrap-key",
265 Capability::RESET_DEVICE => "reset-device",
266 Capability::SIGN_SSH_CERTIFICATE => "sign-ssh-certificate",
267 Capability::UNWRAP_DATA => "unwrap-data",
268 Capability::WRAP_DATA => "wrap-data",
269 Capability::CHANGE_AUTHENTICATION_KEY => "change-authentication-key",
270 _ => return Err(fmt::Error), };
272
273 write!(f, "{s}")
274 }
275}
276
277impl FromStr for Capability {
278 type Err = ();
279
280 fn from_str(s: &str) -> Result<Capability, ()> {
281 Ok(match s {
282 "derive-ecdh" => Capability::DERIVE_ECDH,
283 "decrypt-oaep" => Capability::DECRYPT_OAEP,
284 "decrypt-pkcs" => Capability::DECRYPT_PKCS,
285 "generate-asymmetric-key" => Capability::GENERATE_ASYMMETRIC_KEY,
286 "sign-ecdsa" => Capability::SIGN_ECDSA,
287 "sign-eddsa" => Capability::SIGN_EDDSA,
288 "sign-pkcs" => Capability::SIGN_PKCS,
289 "sign-pss" => Capability::SIGN_PSS,
290 "sign-attestation-certificate" => Capability::SIGN_ATTESTATION_CERTIFICATE,
291 "get-log-entries" => Capability::GET_LOG_ENTRIES,
292 "delete-asymmetric-key" => Capability::DELETE_ASYMMETRIC_KEY,
293 "delete-authentication-key" => Capability::DELETE_AUTHENTICATION_KEY,
294 "delete-hmac-key" => Capability::DELETE_HMAC_KEY,
295 "delete-opaque" => Capability::DELETE_OPAQUE,
296 "delete-otp-aead-key" => Capability::DELETE_OTP_AEAD_KEY,
297 "delete-template" => Capability::DELETE_TEMPLATE,
298 "delete-wrap-key" => Capability::DELETE_WRAP_KEY,
299 "exportable-under-wrap" => Capability::EXPORTABLE_UNDER_WRAP,
300 "export-wrapped" => Capability::EXPORT_WRAPPED,
301 "generate-otp-aead-key" => Capability::GENERATE_OTP_AEAD_KEY,
302 "generate-wrap-key" => Capability::GENERATE_WRAP_KEY,
303 "get-opaque" => Capability::GET_OPAQUE,
304 "get-option" => Capability::GET_OPTION,
305 "get-pseudo-random" => Capability::GET_PSEUDO_RANDOM,
306 "get-template" => Capability::GET_TEMPLATE,
307 "generate-hmac-key" => Capability::GENERATE_HMAC_KEY,
308 "sign-hmac" => Capability::SIGN_HMAC,
309 "verify-hmac" => Capability::VERIFY_HMAC,
310 "import-wrapped" => Capability::IMPORT_WRAPPED,
311 "create-otp-aead" => Capability::CREATE_OTP_AEAD,
312 "randomize-otp-aead" => Capability::RANDOMIZE_OTP_AEAD,
313 "rewrap-from-otp-aead-key" => Capability::REWRAP_FROM_OTP_AEAD_KEY,
314 "rewrap-to-otp-aead-key" => Capability::REWRAP_TO_OTP_AEAD_KEY,
315 "decrypt-otp" => Capability::DECRYPT_OTP,
316 "put-asymmetric-key" => Capability::PUT_ASYMMETRIC_KEY,
317 "put-authentication-key" => Capability::PUT_AUTHENTICATION_KEY,
318 "put-hmac-key" => Capability::PUT_HMAC_KEY,
319 "put-opaque" => Capability::PUT_OPAQUE,
320 "set-option" => Capability::PUT_OPTION,
321 "put-otp-aead-key" => Capability::PUT_OTP_AEAD_KEY,
322 "put-template" => Capability::PUT_TEMPLATE,
323 "put-wrap-key" => Capability::PUT_WRAP_KEY,
324 "reset-device" => Capability::RESET_DEVICE,
325 "sign-ssh-certificate" => Capability::SIGN_SSH_CERTIFICATE,
326 "unwrap-data" => Capability::UNWRAP_DATA,
327 "wrap-data" => Capability::WRAP_DATA,
328 "change-authentication-key" => Capability::CHANGE_AUTHENTICATION_KEY,
329 _ => return Err(()),
330 })
331 }
332}
333
334impl Serialize for Capability {
335 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
336 where
337 S: Serializer,
338 {
339 serializer.serialize_u64(self.bits())
340 }
341}
342
343impl<'de> Deserialize<'de> for Capability {
344 fn deserialize<D>(deserializer: D) -> Result<Capability, D::Error>
345 where
346 D: Deserializer<'de>,
347 {
348 struct CapabilityVisitor;
349
350 impl<'de> Visitor<'de> for CapabilityVisitor {
351 type Value = Capability;
352
353 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
354 formatter.write_str("8-bytes containing capability bitflags")
355 }
356
357 fn visit_u64<E>(self, value: u64) -> Result<Capability, E>
358 where
359 E: de::Error,
360 {
361 Capability::from_bits(value).ok_or_else(|| E::custom("invalid capability bitflags"))
362 }
363 }
364
365 deserializer.deserialize_u64(CapabilityVisitor)
366 }
367}