1use crate::agent::CoseAgent;
3use crate::algs::HASH_ALGS;
4use crate::algs::{thumbprint, verify_chain, verify_thumbprint};
5use crate::common;
6use crate::errors::{CoseError, CoseField, CoseResult, CoseResultWithRet};
7use crate::keys;
8use cbor::{types::Type, Config, Decoder, Encoder};
9use std::io::Cursor;
10
11pub const SALT: i32 = -20;
13pub const ALG: i32 = 1;
14pub const CRIT: i32 = 2;
15pub const CONTENT_TYPE: i32 = 3;
16pub const KID: i32 = 4;
17pub const IV: i32 = 5;
18pub const PARTIAL_IV: i32 = 6;
19pub const COUNTER_SIG: i32 = 7;
20
21pub const PARTY_U_IDENTITY: i32 = -21;
23pub const PARTY_U_NONCE: i32 = -22;
24pub const PARTY_U_OTHER: i32 = -23;
25pub const PARTY_V_IDENTITY: i32 = -24;
26pub const PARTY_V_NONCE: i32 = -25;
27pub const PARTY_V_OTHER: i32 = -26;
28
29pub const EPHEMERAL_KEY: i32 = -1;
31pub const STATIC_KEY: i32 = -2;
32pub const STATIC_KEY_ID: i32 = -3;
33const UINT: [Type; 4] = [Type::UInt16, Type::UInt32, Type::UInt64, Type::UInt8];
34
35pub const X5BAG: i32 = 32;
37pub const X5CHAIN: i32 = 33;
38pub const X5T: i32 = 34;
39pub const X5U: i32 = 35;
40pub const X5T_SENDER: i32 = -27;
41pub const X5U_SENDER: i32 = -28;
42pub const X5CHAIN_SENDER: i32 = -29;
43
44#[derive(Clone, Debug)]
46pub enum ContentTypeTypes {
47 Uint(u32),
48 Tstr(String),
49}
50
51#[derive(Clone)]
53pub struct CoseHeader {
54 pub protected: Vec<i32>,
56 pub unprotected: Vec<i32>,
58 pub alg: Option<i32>,
60 pub crit: Vec<i32>,
62 pub content_type: Option<ContentTypeTypes>,
64 pub kid: Option<Vec<u8>>,
66 pub iv: Option<Vec<u8>>,
68 pub partial_iv: Option<Vec<u8>>,
70 pub salt: Option<Vec<u8>>,
72 pub counters: Vec<CoseAgent>,
74 pub party_u_identity: Option<Vec<u8>>,
76 pub party_u_nonce: Option<Vec<u8>>,
78 pub party_u_other: Option<Vec<u8>>,
80 pub party_v_identity: Option<Vec<u8>>,
82 pub party_v_nonce: Option<Vec<u8>>,
84 pub party_v_other: Option<Vec<u8>>,
86 pub pub_other: Option<Vec<u8>>,
88 pub priv_info: Option<Vec<u8>>,
90 pub ecdh_key: keys::CoseKey,
92 pub static_kid: Option<Vec<u8>>,
94 pub x5bag: Option<Vec<Vec<u8>>>,
96 pub x5chain: Option<Vec<Vec<u8>>>,
98 pub x5t: Option<Vec<u8>>,
100 pub x5t_alg: Option<i32>,
102 pub x5u: Option<String>,
104 pub x5t_sender: Option<Vec<u8>>,
106 pub x5t_sender_alg: Option<i32>,
108 pub x5u_sender: Option<String>,
110 pub x5chain_sender: Option<Vec<Vec<u8>>>,
112 pub x5_private: Vec<u8>,
114 pub(crate) labels_found: Vec<i32>,
115}
116
117impl CoseHeader {
118 pub fn new() -> CoseHeader {
120 CoseHeader {
121 labels_found: Vec::new(),
122 unprotected: Vec::new(),
123 protected: Vec::new(),
124 counters: Vec::new(),
125 crit: Vec::new(),
126 content_type: None,
127 partial_iv: None,
128 salt: None,
129 alg: None,
130 kid: None,
131 iv: None,
132 party_u_identity: None,
133 party_v_identity: None,
134 party_u_nonce: None,
135 party_v_nonce: None,
136 party_u_other: None,
137 party_v_other: None,
138 pub_other: None,
139 priv_info: None,
140 static_kid: None,
141 x5bag: None,
142 x5chain: None,
143 x5t: None,
144 x5_private: Vec::new(),
145 x5t_alg: None,
146 x5u: None,
147 x5t_sender: None,
148 x5t_sender_alg: None,
149 x5chain_sender: None,
150 x5u_sender: None,
151 ecdh_key: keys::CoseKey::new(),
152 }
153 }
154
155 pub(crate) fn remove_label(&mut self, label: i32) {
156 self.unprotected.retain(|&x| x != label);
157 self.protected.retain(|&x| x != label);
158 self.crit.retain(|&x| x != label);
159 }
160
161 fn reg_label(&mut self, label: i32, prot: bool, crit: bool) {
162 self.remove_label(label);
163 if prot {
164 self.protected.push(label);
165 } else {
166 self.unprotected.push(label);
167 }
168 if crit && !self.crit.contains(&label) {
169 self.crit.push(label);
170 }
171 }
172
173 pub fn alg(&mut self, alg: i32, prot: bool, crit: bool) {
178 self.reg_label(ALG, prot, crit);
179 self.alg = Some(alg);
180 }
181
182 pub fn kid(&mut self, kid: Vec<u8>, prot: bool, crit: bool) {
187 self.reg_label(KID, prot, crit);
188 self.kid = Some(kid);
189 }
190
191 pub fn iv(&mut self, iv: Vec<u8>, prot: bool, crit: bool) {
196 self.remove_label(PARTIAL_IV);
197 self.partial_iv = None;
198 self.reg_label(IV, prot, crit);
199 self.iv = Some(iv);
200 }
201
202 pub fn partial_iv(&mut self, partial_iv: Vec<u8>, prot: bool, crit: bool) {
207 self.remove_label(IV);
208 self.iv = None;
209 self.reg_label(PARTIAL_IV, prot, crit);
210 self.partial_iv = Some(partial_iv);
211 }
212
213 pub fn salt(&mut self, salt: Vec<u8>, prot: bool, crit: bool) {
218 self.reg_label(SALT, prot, crit);
219 self.salt = Some(salt);
220 }
221
222 pub fn content_type(&mut self, content_type: ContentTypeTypes, prot: bool, crit: bool) {
227 self.reg_label(CONTENT_TYPE, prot, crit);
228 self.content_type = Some(content_type);
229 }
230
231 pub fn party_identity(
237 &mut self,
238 identity: Vec<u8>,
239 prot: bool,
240 crit: bool,
241 u: bool,
242 include: bool,
243 ) {
244 if u {
245 if include {
246 self.reg_label(PARTY_U_IDENTITY, prot, crit);
247 }
248 self.party_u_identity = Some(identity);
249 } else {
250 if include {
251 self.reg_label(PARTY_V_IDENTITY, prot, crit);
252 }
253 self.party_v_identity = Some(identity);
254 }
255 }
256
257 pub fn party_nonce(&mut self, nonce: Vec<u8>, prot: bool, crit: bool, u: bool) {
263 if u {
264 self.reg_label(PARTY_U_NONCE, prot, crit);
265 self.party_u_nonce = Some(nonce);
266 } else {
267 self.reg_label(PARTY_V_NONCE, prot, crit);
268 self.party_v_nonce = Some(nonce);
269 }
270 }
271
272 pub fn party_other(&mut self, other: Vec<u8>, prot: bool, crit: bool, u: bool) {
278 if u {
279 self.reg_label(PARTY_U_OTHER, prot, crit);
280 self.party_u_other = Some(other);
281 } else {
282 self.reg_label(PARTY_V_OTHER, prot, crit);
283 self.party_v_other = Some(other);
284 }
285 }
286
287 pub fn pub_other(&mut self, other: Vec<u8>) {
289 self.pub_other = Some(other);
290 }
291
292 pub fn priv_info(&mut self, info: Vec<u8>) {
294 self.priv_info = Some(info);
295 }
296
297 pub fn x5bag(&mut self, x5bag: Vec<Vec<u8>>, prot: bool, crit: bool) {
303 self.reg_label(X5BAG, prot, crit);
304 self.x5bag = Some(x5bag);
305 }
306
307 pub fn x5chain(&mut self, x5chain: Vec<Vec<u8>>, prot: bool, crit: bool) {
313 self.reg_label(X5CHAIN, prot, crit);
314 self.x5chain = Some(x5chain);
315 }
316
317 pub fn x5u(&mut self, x5u: String, prot: bool, crit: bool) {
323 self.reg_label(X5U, prot, crit);
324 self.x5u = Some(x5u);
325 }
326
327 pub fn x5chain_sender(&mut self, x5chain: Vec<Vec<u8>>, prot: bool, crit: bool) {
333 self.remove_label(EPHEMERAL_KEY);
334 self.remove_label(STATIC_KEY_ID);
335 self.remove_label(STATIC_KEY);
336 self.reg_label(X5CHAIN_SENDER, prot, crit);
337 self.x5chain_sender = Some(x5chain);
338 }
339
340 pub fn x5t(&mut self, x5: Vec<u8>, alg: i32, prot: bool, crit: bool) -> CoseResult {
347 if !HASH_ALGS.contains(&alg) {
348 return Err(CoseError::Invalid(CoseField::Alg));
349 }
350 self.reg_label(X5T, prot, crit);
351 self.x5t = Some(x5);
352 self.x5t_alg = Some(alg);
353 Ok(())
354 }
355
356 pub fn x5_private(&mut self, x5: Vec<u8>) {
362 self.x5_private = x5;
363 }
364
365 pub fn x5t_sender(&mut self, x5: Vec<u8>, alg: i32, prot: bool, crit: bool) -> CoseResult {
372 if !HASH_ALGS.contains(&alg) {
373 return Err(CoseError::Invalid(CoseField::Alg));
374 }
375 self.reg_label(X5T_SENDER, prot, crit);
376 self.x5t_sender = Some(thumbprint(&x5, &alg)?);
377 self.x5t_sender_alg = Some(alg);
378 Ok(())
379 }
380
381 pub fn x5u_sender(&mut self, x5u: String, prot: bool, crit: bool) {
387 self.reg_label(X5U_SENDER, prot, crit);
388 self.x5u_sender = Some(x5u);
389 }
390
391 pub fn ephemeral_key(&mut self, key: keys::CoseKey, prot: bool, crit: bool) {
396 self.remove_label(X5T_SENDER);
397 self.remove_label(STATIC_KEY_ID);
398 self.remove_label(STATIC_KEY);
399 self.static_kid = None;
400 self.reg_label(EPHEMERAL_KEY, prot, crit);
401 self.ecdh_key = key;
402 }
403
404 pub fn static_key(&mut self, key: keys::CoseKey, prot: bool, crit: bool) {
409 self.remove_label(X5T_SENDER);
410 self.remove_label(STATIC_KEY_ID);
411 self.remove_label(EPHEMERAL_KEY);
412 self.static_kid = None;
413 self.reg_label(STATIC_KEY, prot, crit);
414 self.ecdh_key = key;
415 }
416
417 pub fn static_key_id(&mut self, kid: Vec<u8>, key: keys::CoseKey, prot: bool, crit: bool) {
422 self.remove_label(X5T_SENDER);
423 self.remove_label(STATIC_KEY);
424 self.remove_label(EPHEMERAL_KEY);
425 self.reg_label(STATIC_KEY_ID, prot, crit);
426 self.ecdh_key = key;
427 self.static_kid = Some(kid);
428 }
429
430 pub fn ecdh_key(&mut self, key: keys::CoseKey) {
434 self.ecdh_key = key;
435 }
436
437 pub(crate) fn encode_unprotected(&mut self, encoder: &mut Encoder<Vec<u8>>) -> CoseResult {
438 encoder.object(self.unprotected.len())?;
439 for i in 0..self.unprotected.len() {
440 if !self.labels_found.contains(&self.unprotected[i]) {
441 self.labels_found.push(self.unprotected[i]);
442 } else {
443 return Err(CoseError::DuplicateLabel(self.unprotected[i]));
444 };
445 encoder.i32(self.unprotected[i])?;
446 self.encode_label(self.unprotected[i], encoder, false)?;
447 }
448 Ok(())
449 }
450
451 pub(crate) fn get_protected_bstr(&mut self, verify_label: bool) -> CoseResultWithRet<Vec<u8>> {
452 let mut ph_bstr = Vec::new();
453 let mut encoder = Encoder::new(Vec::new());
454 let prot_len = self.protected.len();
455 let crit_len = self.crit.len();
456 if crit_len > 0 || prot_len > 0 {
457 if crit_len > 0 {
458 encoder.object(prot_len + 1)?;
459 encoder.i32(CRIT)?;
460 encoder.array(crit_len)?;
461 for i in &self.crit {
462 encoder.i32(*i)?;
463 }
464 } else {
465 encoder.object(prot_len)?;
466 }
467 for i in 0..self.protected.len() {
468 if verify_label {
469 if !self.labels_found.contains(&self.protected[i]) {
470 self.labels_found.push(self.protected[i]);
471 } else {
472 return Err(CoseError::DuplicateLabel(self.protected[i]));
473 };
474 }
475 encoder.i32(self.protected[i])?;
476 self.encode_label(self.protected[i], &mut encoder, true)?;
477 }
478 ph_bstr = encoder.into_writer().to_vec();
479 }
480 Ok(ph_bstr)
481 }
482
483 pub(crate) fn decode_unprotected(
484 &mut self,
485 decoder: &mut Decoder<Cursor<Vec<u8>>>,
486 is_counter_sig: bool,
487 ) -> CoseResult {
488 let unprot_len = decoder.object()?;
489 self.unprotected = Vec::new();
490 for _ in 0..unprot_len {
491 let label = decoder.i32()?;
492 if !self.labels_found.contains(&label) {
493 self.labels_found.push(label);
494 } else {
495 return Err(CoseError::DuplicateLabel(label));
496 }
497 self.decode_label(label, decoder, false, is_counter_sig)?;
498 }
499 Ok(())
500 }
501
502 pub(crate) fn decode_protected_bstr(&mut self, ph_bstr: &Vec<u8>) -> CoseResult {
503 let mut decoder = Decoder::new(Config::default(), Cursor::new(ph_bstr.clone()));
504 let prot_len = decoder.object()?;
505 self.protected = Vec::new();
506 for _ in 0..prot_len {
507 let label = decoder.i32()?;
508 if !self.labels_found.contains(&label) {
509 self.labels_found.push(label);
510 } else {
511 return Err(CoseError::DuplicateLabel(label));
512 };
513 self.decode_label(label, &mut decoder, true, false)?;
514 }
515 Ok(())
516 }
517
518 fn encode_label(
519 &mut self,
520 label: i32,
521 encoder: &mut Encoder<Vec<u8>>,
522 protected: bool,
523 ) -> CoseResult {
524 match label {
525 ALG => {
526 encoder.i32(self.alg.ok_or(CoseError::Missing(CoseField::Alg))?)?;
527 }
528 KID => {
529 encoder.bytes(
530 &self
531 .kid
532 .as_ref()
533 .ok_or(CoseError::Missing(CoseField::Kid))?,
534 )?;
535 }
536 IV => {
537 encoder.bytes(&self.iv.as_ref().ok_or(CoseError::Missing(CoseField::Iv))?)?;
538 }
539 PARTIAL_IV => {
540 encoder.bytes(
541 &self
542 .partial_iv
543 .as_ref()
544 .ok_or(CoseError::Missing(CoseField::PartialIv))?,
545 )?;
546 }
547 SALT => {
548 encoder.bytes(
549 &self
550 .salt
551 .as_ref()
552 .ok_or(CoseError::Missing(CoseField::Salt))?,
553 )?;
554 }
555 CONTENT_TYPE => {
556 match &self
557 .content_type
558 .as_ref()
559 .ok_or(CoseError::Missing(CoseField::ContentType))?
560 {
561 ContentTypeTypes::Uint(v) => encoder.u32(*v)?,
562 ContentTypeTypes::Tstr(v) => encoder.text(v)?,
563 }
564 }
565 PARTY_U_IDENTITY => {
566 encoder.bytes(
567 &self
568 .party_u_identity
569 .as_ref()
570 .ok_or(CoseError::Missing(CoseField::PartyUIdentity))?,
571 )?;
572 }
573 PARTY_U_NONCE => {
574 encoder.bytes(
575 &self
576 .party_u_nonce
577 .as_ref()
578 .ok_or(CoseError::Missing(CoseField::PartyUNonce))?,
579 )?;
580 }
581 PARTY_U_OTHER => {
582 encoder.bytes(
583 &self
584 .party_u_other
585 .as_ref()
586 .ok_or(CoseError::Missing(CoseField::PartyUOther))?,
587 )?;
588 }
589 PARTY_V_IDENTITY => {
590 encoder.bytes(
591 &self
592 .party_v_identity
593 .as_ref()
594 .ok_or(CoseError::Missing(CoseField::PartyVIdentity))?,
595 )?;
596 }
597 PARTY_V_NONCE => {
598 encoder.bytes(
599 &self
600 .party_v_nonce
601 .as_ref()
602 .ok_or(CoseError::Missing(CoseField::PartyVNonce))?,
603 )?;
604 }
605 PARTY_V_OTHER => {
606 encoder.bytes(
607 &self
608 .party_v_other
609 .as_ref()
610 .ok_or(CoseError::Missing(CoseField::PartyVOther))?,
611 )?;
612 }
613 X5BAG | X5CHAIN | X5CHAIN_SENDER => {
614 let x5;
615 if label == X5BAG {
616 x5 = self
617 .x5bag
618 .as_ref()
619 .ok_or(CoseError::Missing(CoseField::X5Bag))?;
620 } else if label == X5CHAIN {
621 x5 = self
622 .x5chain
623 .as_ref()
624 .ok_or(CoseError::Missing(CoseField::X5Chain))?;
625 } else {
626 x5 = self
627 .x5chain_sender
628 .as_ref()
629 .ok_or(CoseError::Missing(CoseField::X5ChainSender))?;
630 }
631 let x5_len = x5.len();
632 if x5_len > 0 {
633 if x5_len == 1 {
634 encoder.bytes(&x5[0])?;
635 } else {
636 if label != X5BAG {
637 verify_chain(&x5)?;
638 }
639 encoder.array(x5_len)?;
640 for x in x5 {
641 encoder.bytes(x)?;
642 }
643 }
644 }
645 }
646 X5T => {
647 let x5t = self
648 .x5t
649 .as_ref()
650 .ok_or(CoseError::Missing(CoseField::X5T))?;
651 let x5t_alg = self.x5t_alg.ok_or(CoseError::Missing(CoseField::X5TAlg))?;
652 if self.x5chain != None {
653 verify_thumbprint(&self.x5chain.as_ref().unwrap()[0].clone(), &x5t, &x5t_alg)?;
654 }
655 encoder.array(2)?;
656 encoder.i32(x5t_alg)?;
657 encoder.bytes(x5t)?;
658 }
659 X5T_SENDER => {
660 let x5t_sender = self
661 .x5t_sender
662 .as_ref()
663 .ok_or(CoseError::Missing(CoseField::X5TSender))?;
664 let x5t_sender_alg = self
665 .x5t_sender_alg
666 .ok_or(CoseError::Missing(CoseField::X5TSenderAlg))?;
667 if self.x5chain_sender != None {
668 verify_thumbprint(
669 &self.x5chain_sender.as_ref().unwrap()[0].clone(),
670 &x5t_sender,
671 &x5t_sender_alg,
672 )?;
673 }
674 encoder.array(2)?;
675 encoder.i32(x5t_sender_alg)?;
676 encoder.bytes(x5t_sender)?;
677 }
678 X5U => {
679 encoder.text(
680 self.x5u
681 .as_ref()
682 .ok_or(CoseError::Missing(CoseField::X5U))?,
683 )?;
684 }
685 X5U_SENDER => {
686 encoder.text(
687 self.x5u_sender
688 .as_ref()
689 .ok_or(CoseError::Missing(CoseField::X5USender))?,
690 )?;
691 }
692 EPHEMERAL_KEY | STATIC_KEY => {
693 let mut encode_ecdh = self.ecdh_key.clone();
694 encode_ecdh.remove_label(keys::D);
695 encode_ecdh.d = None;
696 if label == EPHEMERAL_KEY {
697 encode_ecdh.remove_label(keys::KID);
698 encode_ecdh.kid = None;
699 }
700 encode_ecdh.encode_key(encoder)?;
701 }
702 STATIC_KEY_ID => {
703 encoder.bytes(
704 &self
705 .static_kid
706 .as_ref()
707 .ok_or(CoseError::Missing(CoseField::StaticKid))?,
708 )?;
709 }
710 COUNTER_SIG if !protected => {
711 if self.counters.len() > 1 {
712 encoder.array(self.counters.len())?;
713 }
714 for counter in &mut self.counters {
715 counter.encode(encoder)?;
716 }
717 }
718 _ => {
719 return Err(CoseError::InvalidLabel(label));
720 }
721 }
722 Ok(())
723 }
724
725 fn decode_label(
726 &mut self,
727 label: i32,
728 decoder: &mut Decoder<Cursor<Vec<u8>>>,
729 protected: bool,
730 is_counter_sig: bool,
731 ) -> CoseResult {
732 if protected {
733 self.protected.push(label);
734 } else {
735 self.unprotected.push(label);
736 }
737 match label {
738 ALG => {
739 let type_info = decoder.kernel().typeinfo()?;
740 if type_info.0 == Type::Text {
741 self.alg = Some(common::get_alg_id(
742 std::str::from_utf8(
743 &decoder.kernel().raw_data(type_info.1, common::MAX_BYTES)?,
744 )
745 .unwrap()
746 .to_string(),
747 )?);
748 } else if common::CBOR_NUMBER_TYPES.contains(&type_info.0) {
749 self.alg = Some(decoder.kernel().i32(&type_info)?);
750 } else {
751 return Err(CoseError::InvalidCoseStructure());
752 }
753 }
754 CRIT if protected => {
755 self.crit = Vec::new();
756 for _ in 0..decoder.array()? {
757 self.crit.push(decoder.i32()?);
758 }
759 }
760 CONTENT_TYPE => {
761 let type_info = decoder.kernel().typeinfo()?;
762 if type_info.0 == Type::Text {
763 self.content_type = Some(ContentTypeTypes::Tstr(
764 std::str::from_utf8(
765 &decoder.kernel().raw_data(type_info.1, common::MAX_BYTES)?,
766 )
767 .unwrap()
768 .to_string(),
769 ));
770 } else if UINT.contains(&type_info.0) {
771 self.content_type =
772 Some(ContentTypeTypes::Uint(decoder.kernel().u32(&type_info)?));
773 } else {
774 return Err(CoseError::InvalidCoseStructure());
775 }
776 }
777 KID => {
778 let type_info = decoder.kernel().typeinfo()?;
779 if type_info.0 == Type::Bytes {
780 self.kid = Some(decoder.kernel().raw_data(type_info.1, common::MAX_BYTES)?);
781 } else if type_info.0 == Type::Text {
782 self.kid = Some(decoder.kernel().raw_data(type_info.1, common::MAX_BYTES)?);
783 } else {
784 return Err(CoseError::InvalidCoseStructure());
785 }
786 }
787 IV => {
788 self.iv = Some(decoder.bytes()?.to_vec());
789 }
790 SALT => {
791 self.salt = Some(decoder.bytes()?.to_vec());
792 }
793 PARTY_U_IDENTITY => {
794 self.party_u_identity = Some(decoder.bytes()?.to_vec());
795 }
796 PARTY_U_NONCE => {
797 self.party_u_nonce = match decoder.bytes() {
798 Ok(value) => Some(value),
799 Err(ref err) => match err {
800 cbor::decoder::DecodeError::UnexpectedType { datatype, info: _ } => {
801 if *datatype == Type::Bool {
802 None
803 } else {
804 return Err(CoseError::InvalidCoseStructure());
805 }
806 }
807 _ => {
808 return Err(CoseError::InvalidCoseStructure());
809 }
810 },
811 };
812 }
813 PARTY_U_OTHER => {
814 self.party_u_other = Some(decoder.bytes()?.to_vec());
815 }
816 PARTY_V_IDENTITY => {
817 self.party_v_identity = Some(decoder.bytes()?.to_vec());
818 }
819 PARTY_V_NONCE => {
820 self.party_v_nonce = match decoder.bytes() {
821 Ok(value) => Some(value),
822 Err(ref err) => match err {
823 cbor::decoder::DecodeError::UnexpectedType { datatype, info: _ } => {
824 if *datatype == Type::Bool {
825 None
826 } else {
827 return Err(CoseError::InvalidCoseStructure());
828 }
829 }
830 _ => {
831 return Err(CoseError::InvalidCoseStructure());
832 }
833 },
834 };
835 }
836 PARTY_V_OTHER => {
837 self.party_v_other = Some(decoder.bytes()?.to_vec());
838 }
839 PARTIAL_IV => {
840 self.partial_iv = Some(decoder.bytes()?.to_vec());
841 }
842 X5BAG | X5CHAIN | X5CHAIN_SENDER => {
843 let type_info = decoder.kernel().typeinfo()?;
844 if type_info.0 == Type::Array {
845 let x5_len = type_info.1;
846 let mut x5 = Vec::new();
847 for _ in 0..x5_len {
848 x5.push(decoder.bytes()?.to_vec());
849 }
850 if label == X5BAG {
851 self.x5bag = Some(x5);
852 } else if label == X5CHAIN {
853 verify_chain(&x5)?;
854 self.x5chain = Some(x5);
855 } else {
856 verify_chain(&x5)?;
857 self.x5chain_sender = Some(x5);
858 }
859 } else if type_info.0 == Type::Bytes {
860 let x5 = Some(vec![decoder
861 .kernel()
862 .raw_data(type_info.1, common::MAX_BYTES)?]);
863 if label == X5BAG {
864 self.x5bag = x5;
865 } else if label == X5CHAIN {
866 self.x5chain = x5;
867 } else {
868 self.x5chain_sender = x5;
869 }
870 } else {
871 return Err(CoseError::InvalidCoseStructure());
872 }
873 }
874 X5T | X5T_SENDER => {
875 if decoder.array()? != 2 {
876 return Err(CoseError::InvalidCoseStructure());
877 }
878 let type_info = decoder.kernel().typeinfo()?;
879 let x5t_alg;
880 if type_info.0 == Type::Text {
881 x5t_alg = Some(common::get_alg_id(
882 std::str::from_utf8(
883 &decoder.kernel().raw_data(type_info.1, common::MAX_BYTES)?,
884 )
885 .unwrap()
886 .to_string(),
887 )?);
888 } else if common::CBOR_NUMBER_TYPES.contains(&type_info.0) {
889 x5t_alg = Some(decoder.kernel().i32(&type_info)?);
890 } else {
891 return Err(CoseError::InvalidCoseStructure());
892 }
893 let x5t = Some(decoder.bytes()?);
894 if label == X5T {
895 if self.x5chain != None {
896 verify_thumbprint(
897 &self.x5chain.as_ref().unwrap()[0].clone(),
898 &x5t.as_ref().unwrap(),
899 &x5t_alg.as_ref().unwrap(),
900 )?;
901 }
902 self.x5t = x5t;
903 self.x5t_alg = x5t_alg;
904 } else {
905 if self.x5chain_sender != None {
906 verify_thumbprint(
907 &self.x5chain_sender.as_ref().unwrap()[0].clone(),
908 &x5t.as_ref().unwrap(),
909 &x5t_alg.as_ref().unwrap(),
910 )?;
911 }
912 self.x5t_sender = x5t;
913 self.x5t_sender_alg = x5t_alg;
914 }
915 }
916 X5U => {
917 self.x5u = Some(decoder.text()?);
918 }
919 X5U_SENDER => {
920 self.x5u_sender = Some(decoder.text()?);
921 }
922 EPHEMERAL_KEY => {
923 if [X5CHAIN_SENDER, STATIC_KEY, STATIC_KEY_ID]
924 .iter()
925 .any(|i| self.labels_found.contains(i))
926 {
927 return Err(CoseError::InvalidCoseStructure());
928 }
929 self.ecdh_key.decode_key(decoder)?;
930 }
931 STATIC_KEY => {
932 if [X5CHAIN_SENDER, EPHEMERAL_KEY, STATIC_KEY_ID]
933 .iter()
934 .any(|i| self.labels_found.contains(i))
935 {
936 return Err(CoseError::InvalidCoseStructure());
937 }
938 self.ecdh_key.decode_key(decoder)?;
939 }
940 STATIC_KEY_ID => {
941 if [X5CHAIN_SENDER, EPHEMERAL_KEY, STATIC_KEY]
942 .iter()
943 .any(|i| self.labels_found.contains(i))
944 {
945 return Err(CoseError::InvalidCoseStructure());
946 }
947 self.static_kid = Some(decoder.bytes()?.to_vec());
948 }
949 COUNTER_SIG if !is_counter_sig => {
950 let mut counter = CoseAgent::new_counter_sig();
951 let n = decoder.array()?;
952 let mut n1 = 0;
953 match decoder.bytes() {
954 Ok(value) => {
955 counter.ph_bstr = value;
956 }
957 Err(ref err) => match err {
958 cbor::decoder::DecodeError::UnexpectedType { datatype, info } => {
959 if *datatype == Type::Array {
960 n1 = *info;
961 }
962 }
963 _ => {
964 return Err(CoseError::InvalidCoseStructure());
965 }
966 },
967 };
968 if n1 == 0 && n == 3 {
969 counter.decode(decoder)?;
970 self.counters.push(counter);
971 } else {
972 counter.ph_bstr = decoder.bytes()?;
973 counter.decode(decoder)?;
974 self.counters.push(counter);
975 for _ in 1..n {
976 counter = CoseAgent::new_counter_sig();
977 decoder.array()?;
978 counter.ph_bstr = decoder.bytes()?;
979 counter.decode(decoder)?;
980 self.counters.push(counter);
981 }
982 }
983 }
984 _ => {
985 return Err(CoseError::InvalidLabel(label));
986 }
987 }
988 Ok(())
989 }
990
991 pub fn get_counter(&self, kid: &Vec<u8>) -> CoseResultWithRet<Vec<usize>> {
993 let mut counters: Vec<usize> = Vec::new();
994 for i in 0..self.counters.len() {
995 if self.counters[i]
996 .header
997 .kid
998 .as_ref()
999 .ok_or(CoseError::Missing(CoseField::Kid))?
1000 == kid
1001 {
1002 counters.push(i);
1003 }
1004 }
1005 Ok(counters)
1006 }
1007}