1use super::generated_ops::psa_key_attributes::key_type;
5use super::generated_ops::psa_key_attributes::{
6 key_type::DhFamily as DhFamilyProto, key_type::EccFamily as EccFamilyProto,
7 KeyAttributes as KeyAttributesProto, KeyPolicy as KeyPolicyProto, KeyType as KeyTypeProto,
8 UsageFlags as UsageFlagsProto,
9};
10use crate::operations::psa_algorithm::Algorithm;
12use crate::operations::psa_key_attributes::{
13 Attributes, DhFamily, EccFamily, Lifetime, Policy, Type, UsageFlags,
14};
15
16use crate::requests::{ResponseStatus, Result};
17use log::error;
18use std::convert::{TryFrom, TryInto};
19
20impl TryFrom<UsageFlagsProto> for UsageFlags {
22 type Error = ResponseStatus;
23
24 fn try_from(usage_flags_proto: UsageFlagsProto) -> Result<Self> {
25 let mut usage_flags = UsageFlags::default();
26 if usage_flags_proto.export {
27 let _ = usage_flags.set_export();
28 }
29 if usage_flags_proto.copy {
30 let _ = usage_flags.set_copy();
31 }
32 if usage_flags_proto.cache {
33 let _ = usage_flags.set_cache();
34 }
35 if usage_flags_proto.encrypt {
36 let _ = usage_flags.set_encrypt();
37 }
38 if usage_flags_proto.decrypt {
39 let _ = usage_flags.set_decrypt();
40 }
41 if usage_flags_proto.sign_message {
42 let _ = usage_flags.set_sign_message();
43 }
44 if usage_flags_proto.verify_message {
45 let _ = usage_flags.set_verify_message();
46 }
47 if usage_flags_proto.sign_hash {
48 let _ = usage_flags.set_sign_hash();
49 }
50 if usage_flags_proto.verify_hash {
51 let _ = usage_flags.set_verify_hash();
52 }
53 if usage_flags_proto.derive {
54 let _ = usage_flags.set_derive();
55 }
56 Ok(usage_flags)
57 }
58}
59
60impl TryFrom<UsageFlags> for UsageFlagsProto {
62 type Error = ResponseStatus;
63
64 fn try_from(usage_flags: UsageFlags) -> Result<Self> {
65 Ok(UsageFlagsProto {
66 export: usage_flags.export(),
67 copy: usage_flags.copy(),
68 cache: usage_flags.cache(),
69 encrypt: usage_flags.encrypt(),
70 decrypt: usage_flags.decrypt(),
71 sign_message: usage_flags.sign_message(),
72 verify_message: usage_flags.verify_message(),
73 sign_hash: usage_flags.sign_hash(),
74 verify_hash: usage_flags.verify_hash(),
75 derive: usage_flags.derive(),
76 })
77 }
78}
79
80impl TryFrom<KeyPolicyProto> for Policy {
82 type Error = ResponseStatus;
83
84 fn try_from(key_policy_proto: KeyPolicyProto) -> Result<Self> {
85 let permitted_algorithms: Algorithm = key_policy_proto
86 .key_algorithm
87 .ok_or_else(|| {
88 error!("The permitted_algorithms field of Policy message is not set (mandatory field).");
89 ResponseStatus::InvalidEncoding
90 })?
91 .try_into()?;
92 Ok(Policy {
93 usage_flags: key_policy_proto
94 .key_usage_flags
95 .ok_or_else(|| {
96 error!("The usage_flags field of Policy message is not set (mandatory field).");
97 ResponseStatus::InvalidEncoding
98 })?
99 .try_into()?,
100 permitted_algorithms,
101 })
102 }
103}
104
105impl TryFrom<Policy> for KeyPolicyProto {
107 type Error = ResponseStatus;
108
109 fn try_from(key_policy: Policy) -> Result<Self> {
110 Ok(KeyPolicyProto {
111 key_usage_flags: Some(key_policy.usage_flags.try_into()?),
112 key_algorithm: Some(key_policy.permitted_algorithms.try_into()?),
113 })
114 }
115}
116
117impl TryFrom<EccFamilyProto> for EccFamily {
119 type Error = ResponseStatus;
120
121 fn try_from(ecc_family_val: EccFamilyProto) -> Result<Self> {
122 match ecc_family_val {
123 EccFamilyProto::None => {
124 error!("The None value of EccFamily enumeration is not allowed (mandatory field).");
125 Err(ResponseStatus::InvalidEncoding)
126 }
127 EccFamilyProto::SecpK1 => Ok(EccFamily::SecpK1),
128 EccFamilyProto::SecpR1 => Ok(EccFamily::SecpR1),
129 #[allow(deprecated)]
130 EccFamilyProto::SecpR2 => Ok(EccFamily::SecpR2),
131 EccFamilyProto::SectK1 => Ok(EccFamily::SectK1),
132 EccFamilyProto::SectR1 => Ok(EccFamily::SectR1),
133 #[allow(deprecated)]
134 EccFamilyProto::SectR2 => Ok(EccFamily::SectR2),
135 EccFamilyProto::BrainpoolPR1 => Ok(EccFamily::BrainpoolPR1),
136 EccFamilyProto::Frp => Ok(EccFamily::Frp),
137 EccFamilyProto::Montgomery => Ok(EccFamily::Montgomery),
138 }
139 }
140}
141
142fn ecc_family_to_i32(ecc_family: EccFamily) -> i32 {
144 match ecc_family {
145 EccFamily::SecpK1 => EccFamilyProto::SecpK1.into(),
146 EccFamily::SecpR1 => EccFamilyProto::SecpR1.into(),
147 #[allow(deprecated)]
148 EccFamily::SecpR2 => EccFamilyProto::SecpR2.into(),
149 EccFamily::SectK1 => EccFamilyProto::SectK1.into(),
150 EccFamily::SectR1 => EccFamilyProto::SectR1.into(),
151 #[allow(deprecated)]
152 EccFamily::SectR2 => EccFamilyProto::SectR2.into(),
153 EccFamily::BrainpoolPR1 => EccFamilyProto::BrainpoolPR1.into(),
154 EccFamily::Frp => EccFamilyProto::Frp.into(),
155 EccFamily::Montgomery => EccFamilyProto::Montgomery.into(),
156 }
157}
158
159impl TryFrom<DhFamilyProto> for DhFamily {
161 type Error = ResponseStatus;
162
163 fn try_from(dh_family_val: DhFamilyProto) -> Result<Self> {
164 match dh_family_val {
165 DhFamilyProto::Rfc7919 => Ok(DhFamily::Rfc7919),
166 }
167 }
168}
169
170fn dh_family_to_i32(dh_family: DhFamily) -> i32 {
172 match dh_family {
173 DhFamily::Rfc7919 => DhFamilyProto::Rfc7919.into(),
174 }
175}
176
177impl TryFrom<KeyTypeProto> for Type {
178 type Error = ResponseStatus;
179
180 fn try_from(key_type_proto: KeyTypeProto) -> Result<Self> {
181 match key_type_proto.variant.ok_or_else(|| {
182 error!("variant field of Type message is empty.");
183 ResponseStatus::InvalidEncoding
184 })? {
185 key_type::Variant::RawData(_) => Ok(Type::RawData),
186 key_type::Variant::Hmac(_) => Ok(Type::Hmac),
187 key_type::Variant::Derive(_) => Ok(Type::Derive),
188 key_type::Variant::Aes(_) => Ok(Type::Aes),
189 key_type::Variant::Des(_) => Ok(Type::Des),
190 key_type::Variant::Camellia(_) => Ok(Type::Camellia),
191 key_type::Variant::Arc4(_) => Ok(Type::Arc4),
192 key_type::Variant::Chacha20(_) => Ok(Type::Chacha20),
193 key_type::Variant::RsaPublicKey(_) => Ok(Type::RsaPublicKey),
194 key_type::Variant::RsaKeyPair(_) => Ok(Type::RsaKeyPair),
195 key_type::Variant::EccKeyPair(ecc_key_pair) => Ok(Type::EccKeyPair {
196 curve_family: EccFamilyProto::try_from(ecc_key_pair.curve_family)?.try_into()?,
197 }),
198 key_type::Variant::EccPublicKey(ecc_public_key) => Ok(Type::EccPublicKey {
199 curve_family: EccFamilyProto::try_from(ecc_public_key.curve_family)?.try_into()?,
200 }),
201 key_type::Variant::DhKeyPair(dh_key_pair) => Ok(Type::DhKeyPair {
202 group_family: DhFamilyProto::try_from(dh_key_pair.group_family)?.try_into()?,
203 }),
204 key_type::Variant::DhPublicKey(dh_public_key) => Ok(Type::DhPublicKey {
205 group_family: DhFamilyProto::try_from(dh_public_key.group_family)?.try_into()?,
206 }),
207 }
208 }
209}
210
211impl TryFrom<Type> for KeyTypeProto {
212 type Error = ResponseStatus;
213
214 fn try_from(key_type: Type) -> Result<Self> {
215 match key_type {
216 Type::RawData => Ok(KeyTypeProto {
217 variant: Some(key_type::Variant::RawData(key_type::RawData {})),
218 }),
219 Type::Hmac => Ok(KeyTypeProto {
220 variant: Some(key_type::Variant::Hmac(key_type::Hmac {})),
221 }),
222 Type::Derive => Ok(KeyTypeProto {
223 variant: Some(key_type::Variant::Derive(key_type::Derive {})),
224 }),
225 Type::Aes => Ok(KeyTypeProto {
226 variant: Some(key_type::Variant::Aes(key_type::Aes {})),
227 }),
228 Type::Des => Ok(KeyTypeProto {
229 variant: Some(key_type::Variant::Des(key_type::Des {})),
230 }),
231 Type::Camellia => Ok(KeyTypeProto {
232 variant: Some(key_type::Variant::Camellia(key_type::Camellia {})),
233 }),
234 Type::Arc4 => Ok(KeyTypeProto {
235 variant: Some(key_type::Variant::Arc4(key_type::Arc4 {})),
236 }),
237 Type::Chacha20 => Ok(KeyTypeProto {
238 variant: Some(key_type::Variant::Chacha20(key_type::Chacha20 {})),
239 }),
240 Type::RsaPublicKey => Ok(KeyTypeProto {
241 variant: Some(key_type::Variant::RsaPublicKey(key_type::RsaPublicKey {})),
242 }),
243 Type::RsaKeyPair => Ok(KeyTypeProto {
244 variant: Some(key_type::Variant::RsaKeyPair(key_type::RsaKeyPair {})),
245 }),
246 Type::EccKeyPair { curve_family } => Ok(KeyTypeProto {
247 variant: Some(key_type::Variant::EccKeyPair(key_type::EccKeyPair {
248 curve_family: ecc_family_to_i32(curve_family),
249 })),
250 }),
251 Type::EccPublicKey { curve_family } => Ok(KeyTypeProto {
252 variant: Some(key_type::Variant::EccPublicKey(key_type::EccPublicKey {
253 curve_family: ecc_family_to_i32(curve_family),
254 })),
255 }),
256 Type::DhKeyPair { group_family } => Ok(KeyTypeProto {
257 variant: Some(key_type::Variant::DhKeyPair(key_type::DhKeyPair {
258 group_family: dh_family_to_i32(group_family),
259 })),
260 }),
261 Type::DhPublicKey { group_family } => Ok(KeyTypeProto {
262 variant: Some(key_type::Variant::DhPublicKey(key_type::DhPublicKey {
263 group_family: dh_family_to_i32(group_family),
264 })),
265 }),
266 }
267 }
268}
269
270impl TryFrom<KeyAttributesProto> for Attributes {
272 type Error = ResponseStatus;
273
274 fn try_from(key_attributes_proto: KeyAttributesProto) -> Result<Self> {
275 Ok(Attributes {
276 lifetime: Lifetime::Persistent,
277 key_type: key_attributes_proto
278 .key_type
279 .ok_or_else(|| {
280 error!(
281 "The key_type field of Attributes message is not set (mandatory field)."
282 );
283 ResponseStatus::InvalidEncoding
284 })?
285 .try_into()?,
286 bits: key_attributes_proto.key_bits.try_into().map_err(|e| {
287 error!("failed to convert key bits from proto. Error: {}", e);
288 ResponseStatus::InvalidEncoding
289 })?,
290 policy: key_attributes_proto
291 .key_policy
292 .ok_or_else(|| {
293 error!("The policy field of Attributes message is not set (mandatory field).");
294 ResponseStatus::InvalidEncoding
295 })?
296 .try_into()?,
297 })
298 }
299}
300
301impl TryFrom<Attributes> for KeyAttributesProto {
303 type Error = ResponseStatus;
304
305 fn try_from(key_attributes: Attributes) -> Result<Self> {
306 Ok(KeyAttributesProto {
307 key_type: Some(key_attributes.key_type.try_into()?),
308 key_bits: key_attributes.bits.try_into().map_err(|e| {
309 error!("failed to convert key bits to proto. Error: {}", e);
310 ResponseStatus::InvalidEncoding
311 })?,
312 key_policy: Some(key_attributes.policy.try_into()?),
313 })
314 }
315}
316
317#[cfg(test)]
318mod test {
319 #![allow(deprecated)]
320 use super::super::generated_ops::psa_algorithm::{self as algorithm_proto};
321 use super::super::generated_ops::psa_key_attributes::{
322 self as key_attributes_proto, KeyAttributes as KeyAttributesProto,
323 };
324 use crate::operations::psa_algorithm::{Algorithm, AsymmetricSignature, Hash};
325 use crate::operations::psa_key_attributes::{self, Attributes, Lifetime, Policy, UsageFlags};
326 use crate::requests::ResponseStatus;
327 use std::convert::{TryFrom, TryInto};
328
329 #[test]
330 fn key_attrs_to_proto() {
331 let mut usage_flags = UsageFlags::default();
332 let _ = usage_flags
333 .set_decrypt()
334 .set_export()
335 .set_copy()
336 .set_cache()
337 .set_encrypt()
338 .set_decrypt()
339 .set_sign_message()
340 .set_verify_message()
341 .set_sign_hash()
342 .set_verify_hash()
343 .set_derive();
344 let key_attrs = Attributes {
345 lifetime: Lifetime::Persistent,
346 key_type: psa_key_attributes::Type::RsaKeyPair,
347 bits: 1024,
348 policy: Policy {
349 usage_flags,
350 permitted_algorithms: Algorithm::AsymmetricSignature(
351 AsymmetricSignature::RsaPkcs1v15Sign {
352 hash_alg: Hash::Sha1.into(),
353 },
354 ),
355 },
356 };
357
358 let key_attrs_proto: KeyAttributesProto = key_attrs.try_into().unwrap();
359
360 let key_attrs_proto_expected = KeyAttributesProto {
361 key_type: Some(key_attributes_proto::KeyType {
362 variant: Some(key_attributes_proto::key_type::Variant::RsaKeyPair(key_attributes_proto::key_type::RsaKeyPair {})),
363 }),
364 key_bits: 1024,
365 key_policy: Some(key_attributes_proto::KeyPolicy {
366 key_usage_flags: Some(key_attributes_proto::UsageFlags {
367 export: true,
368 copy: true,
369 cache: true,
370 encrypt: true,
371 decrypt: true,
372 sign_message: true,
373 verify_message: true,
374 sign_hash: true,
375 verify_hash: true,
376 derive: true,
377 }),
378 key_algorithm: Some(algorithm_proto::Algorithm {
379 variant: Some(algorithm_proto::algorithm::Variant::AsymmetricSignature(algorithm_proto::algorithm::AsymmetricSignature {
380 variant: Some(algorithm_proto::algorithm::asymmetric_signature::Variant::RsaPkcs1v15Sign(algorithm_proto::algorithm::asymmetric_signature::RsaPkcs1v15Sign {
381 hash_alg: Some(algorithm_proto::algorithm::asymmetric_signature::SignHash {
382 variant: Some(algorithm_proto::algorithm::asymmetric_signature::sign_hash::Variant::Specific(
383 algorithm_proto::algorithm::Hash::Sha1.into(),
384 )),
385 }),
386 })),
387 }))
388 }),
389 }),
390 };
391
392 assert_eq!(key_attrs_proto, key_attrs_proto_expected);
393 }
394
395 #[test]
396 fn key_attrs_from_proto() {
397 let key_attrs_proto = KeyAttributesProto {
398 key_type: Some(key_attributes_proto::KeyType {
399 variant: Some(key_attributes_proto::key_type::Variant::RsaKeyPair(key_attributes_proto::key_type::RsaKeyPair {})),
400 }),
401 key_bits: 1024,
402 key_policy: Some(key_attributes_proto::KeyPolicy {
403 key_usage_flags: Some(key_attributes_proto::UsageFlags {
404 export: true,
405 copy: true,
406 cache: true,
407 encrypt: true,
408 decrypt: true,
409 sign_message: true,
410 verify_message: true,
411 sign_hash: true,
412 verify_hash: true,
413 derive: true,
414 }),
415 key_algorithm: Some(algorithm_proto::Algorithm {
416 variant: Some(algorithm_proto::algorithm::Variant::AsymmetricSignature(algorithm_proto::algorithm::AsymmetricSignature {
417 variant: Some(algorithm_proto::algorithm::asymmetric_signature::Variant::RsaPkcs1v15Sign(algorithm_proto::algorithm::asymmetric_signature::RsaPkcs1v15Sign {
418 hash_alg: Some(algorithm_proto::algorithm::asymmetric_signature::SignHash {
419 variant: Some(algorithm_proto::algorithm::asymmetric_signature::sign_hash::Variant::Specific(
420 algorithm_proto::algorithm::Hash::Sha1.into(),
421 )),
422 }),
423 })),
424 }))
425 }),
426 }),
427 };
428
429 let key_attrs: Attributes = key_attrs_proto.try_into().unwrap();
430
431 let mut usage_flags = UsageFlags::default();
432 let _ = usage_flags
433 .set_decrypt()
434 .set_export()
435 .set_copy()
436 .set_cache()
437 .set_encrypt()
438 .set_decrypt()
439 .set_sign_message()
440 .set_verify_message()
441 .set_sign_hash()
442 .set_verify_hash()
443 .set_derive();
444 let key_attrs_expected = Attributes {
445 lifetime: Lifetime::Persistent,
446 key_type: psa_key_attributes::Type::RsaKeyPair,
447 bits: 1024,
448 policy: Policy {
449 usage_flags,
450 permitted_algorithms: Algorithm::AsymmetricSignature(
451 AsymmetricSignature::RsaPkcs1v15Sign {
452 hash_alg: Hash::Sha1.into(),
453 },
454 ),
455 },
456 };
457
458 assert_eq!(key_attrs, key_attrs_expected);
459 }
460
461 #[test]
462 fn proto_key_type_variant_not_recognised() {
463 let key_attrs_proto = KeyAttributesProto {
464 key_type: Some(key_attributes_proto::KeyType { variant: None }),
465 key_bits: 1024,
466 key_policy: Some(key_attributes_proto::KeyPolicy {
467 key_usage_flags: Some(key_attributes_proto::UsageFlags {
468 export: true,
469 copy: true,
470 cache: true,
471 encrypt: true,
472 decrypt: true,
473 sign_message: true,
474 verify_message: true,
475 sign_hash: true,
476 verify_hash: true,
477 derive: true,
478 }),
479 key_algorithm: Some(algorithm_proto::Algorithm {
480 variant: Some(algorithm_proto::algorithm::Variant::None(
481 algorithm_proto::algorithm::None {},
482 )),
483 }),
484 }),
485 };
486
487 assert_eq!(
488 Attributes::try_from(key_attrs_proto).unwrap_err(),
489 ResponseStatus::InvalidEncoding
490 );
491 }
492
493 #[test]
494 fn proto_key_type_not_set() {
495 let key_attrs_proto = KeyAttributesProto {
496 key_type: None,
497 key_bits: 1024,
498 key_policy: Some(key_attributes_proto::KeyPolicy {
499 key_usage_flags: Some(key_attributes_proto::UsageFlags {
500 export: true,
501 copy: true,
502 cache: true,
503 encrypt: true,
504 decrypt: true,
505 sign_message: true,
506 verify_message: true,
507 sign_hash: true,
508 verify_hash: true,
509 derive: true,
510 }),
511 key_algorithm: Some(algorithm_proto::Algorithm {
512 variant: Some(algorithm_proto::algorithm::Variant::None(
513 algorithm_proto::algorithm::None {},
514 )),
515 }),
516 }),
517 };
518
519 assert_eq!(
520 Attributes::try_from(key_attrs_proto).unwrap_err(),
521 ResponseStatus::InvalidEncoding
522 );
523 }
524
525 #[test]
526 fn proto_usage_flags_not_set() {
527 let key_attrs_proto = KeyAttributesProto {
528 key_type: Some(key_attributes_proto::KeyType {
529 variant: Some(key_attributes_proto::key_type::Variant::RsaKeyPair(
530 key_attributes_proto::key_type::RsaKeyPair {},
531 )),
532 }),
533 key_bits: 1024,
534 key_policy: Some(key_attributes_proto::KeyPolicy {
535 key_usage_flags: None,
536 key_algorithm: Some(algorithm_proto::Algorithm {
537 variant: Some(algorithm_proto::algorithm::Variant::None(
538 algorithm_proto::algorithm::None {},
539 )),
540 }),
541 }),
542 };
543
544 assert_eq!(
545 Attributes::try_from(key_attrs_proto).unwrap_err(),
546 ResponseStatus::InvalidEncoding
547 );
548 }
549
550 #[test]
551 fn proto_key_alg_not_recognised() {
552 let key_attrs_proto = KeyAttributesProto {
553 key_type: Some(key_attributes_proto::KeyType {
554 variant: Some(key_attributes_proto::key_type::Variant::RsaKeyPair(
555 key_attributes_proto::key_type::RsaKeyPair {},
556 )),
557 }),
558 key_bits: 1024,
559 key_policy: Some(key_attributes_proto::KeyPolicy {
560 key_usage_flags: Some(key_attributes_proto::UsageFlags {
561 export: true,
562 copy: true,
563 cache: true,
564 encrypt: true,
565 decrypt: true,
566 sign_message: true,
567 verify_message: true,
568 sign_hash: true,
569 verify_hash: true,
570 derive: true,
571 }),
572 key_algorithm: Some(algorithm_proto::Algorithm { variant: None }),
573 }),
574 };
575
576 assert_eq!(
577 Attributes::try_from(key_attrs_proto).unwrap_err(),
578 ResponseStatus::InvalidEncoding
579 );
580 }
581
582 #[test]
583 fn proto_key_alg_not_recognised2() {
584 let key_attrs_proto = KeyAttributesProto {
585 key_type: Some(key_attributes_proto::KeyType {
586 variant: Some(key_attributes_proto::key_type::Variant::RsaKeyPair(
587 key_attributes_proto::key_type::RsaKeyPair {},
588 )),
589 }),
590 key_bits: 1024,
591 key_policy: Some(key_attributes_proto::KeyPolicy {
592 key_usage_flags: Some(key_attributes_proto::UsageFlags {
593 export: true,
594 copy: true,
595 cache: true,
596 encrypt: true,
597 decrypt: true,
598 sign_message: true,
599 verify_message: true,
600 sign_hash: true,
601 verify_hash: true,
602 derive: true,
603 }),
604 key_algorithm: Some(algorithm_proto::Algorithm {
605 variant: Some(algorithm_proto::algorithm::Variant::AsymmetricSignature(
606 algorithm_proto::algorithm::AsymmetricSignature { variant: None },
607 )),
608 }),
609 }),
610 };
611
612 assert_eq!(
613 Attributes::try_from(key_attrs_proto).unwrap_err(),
614 ResponseStatus::InvalidEncoding
615 );
616 }
617
618 #[test]
619 fn proto_key_alg_not_recognised3() {
620 let key_attrs_proto = KeyAttributesProto {
621 key_type: Some(key_attributes_proto::KeyType {
622 variant: Some(key_attributes_proto::key_type::Variant::RsaKeyPair(key_attributes_proto::key_type::RsaKeyPair {})),
623 }),
624 key_bits: 1024,
625 key_policy: Some(key_attributes_proto::KeyPolicy {
626 key_usage_flags: Some(key_attributes_proto::UsageFlags {
627 export: true,
628 copy: true,
629 cache: true,
630 encrypt: true,
631 decrypt: true,
632 sign_message: true,
633 verify_message: true,
634 sign_hash: true,
635 verify_hash: true,
636 derive: true,
637 }),
638 key_algorithm: Some(algorithm_proto::Algorithm {
639 variant: Some(algorithm_proto::algorithm::Variant::AsymmetricSignature(algorithm_proto::algorithm::AsymmetricSignature {
640 variant: Some(algorithm_proto::algorithm::asymmetric_signature::Variant::RsaPkcs1v15Sign(algorithm_proto::algorithm::asymmetric_signature::RsaPkcs1v15Sign {
641 hash_alg: Some(algorithm_proto::algorithm::asymmetric_signature::SignHash {
642 variant: Some(algorithm_proto::algorithm::asymmetric_signature::sign_hash::Variant::Specific(
643 78,
644 )),
645 }),
646 })),
647 }))
648 }),
649 }),
650 };
651
652 assert_eq!(
653 Attributes::try_from(key_attrs_proto).unwrap_err(),
654 ResponseStatus::InvalidEncoding
655 );
656 }
657}