1use crate::agent::CoseAgent;
3use crate::algs::HASH_ALGS;
4use crate::algs::{thumbprint, verify_chain, verify_thumbprint};
5use crate::common;
6use crate::errors::{CoseError, 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 }
159
160 fn reg_label(&mut self, label: i32, prot: bool, crit: bool) {
161 self.remove_label(label);
162 if prot {
163 self.protected.push(label);
164 } else {
165 self.unprotected.push(label);
166 }
167 if crit && !self.crit.contains(&label) {
168 self.crit.push(ALG);
169 }
170 }
171
172 pub fn alg(&mut self, alg: i32, prot: bool, crit: bool) {
177 self.reg_label(ALG, prot, crit);
178 self.alg = Some(alg);
179 }
180
181 pub fn kid(&mut self, kid: Vec<u8>, prot: bool, crit: bool) {
186 self.reg_label(KID, prot, crit);
187 self.kid = Some(kid);
188 }
189
190 pub fn iv(&mut self, iv: Vec<u8>, prot: bool, crit: bool) {
195 self.remove_label(PARTIAL_IV);
196 self.partial_iv = None;
197 self.reg_label(IV, prot, crit);
198 self.iv = Some(iv);
199 }
200
201 pub fn partial_iv(&mut self, partial_iv: Vec<u8>, prot: bool, crit: bool) {
206 self.remove_label(IV);
207 self.iv = None;
208 self.reg_label(PARTIAL_IV, prot, crit);
209 self.partial_iv = Some(partial_iv);
210 }
211
212 pub fn salt(&mut self, salt: Vec<u8>, prot: bool, crit: bool) {
217 self.reg_label(SALT, prot, crit);
218 self.salt = Some(salt);
219 }
220
221 pub fn content_type(&mut self, content_type: ContentTypeTypes, prot: bool, crit: bool) {
226 self.reg_label(CONTENT_TYPE, prot, crit);
227 self.content_type = Some(content_type);
228 }
229
230 pub fn party_identity(&mut self, identity: Vec<u8>, prot: bool, crit: bool, u: bool) {
236 if u {
237 self.reg_label(PARTY_U_IDENTITY, prot, crit);
238 self.party_u_identity = Some(identity);
239 } else {
240 self.reg_label(PARTY_V_IDENTITY, prot, crit);
241 self.party_v_identity = Some(identity);
242 }
243 }
244
245 pub fn party_nonce(&mut self, nonce: Vec<u8>, prot: bool, crit: bool, u: bool) {
251 if u {
252 self.reg_label(PARTY_U_NONCE, prot, crit);
253 self.party_u_nonce = Some(nonce);
254 } else {
255 self.reg_label(PARTY_V_NONCE, prot, crit);
256 self.party_v_nonce = Some(nonce);
257 }
258 }
259
260 pub fn party_other(&mut self, other: Vec<u8>, prot: bool, crit: bool, u: bool) {
266 if u {
267 self.reg_label(PARTY_U_OTHER, prot, crit);
268 self.party_u_other = Some(other);
269 } else {
270 self.reg_label(PARTY_V_OTHER, prot, crit);
271 self.party_v_other = Some(other);
272 }
273 }
274
275 pub fn pub_other(&mut self, other: Vec<u8>) {
277 self.pub_other = Some(other);
278 }
279
280 pub fn priv_info(&mut self, info: Vec<u8>) {
282 self.priv_info = Some(info);
283 }
284
285 pub fn x5bag(&mut self, x5bag: Vec<Vec<u8>>, prot: bool, crit: bool) {
291 self.reg_label(X5BAG, prot, crit);
292 self.x5bag = Some(x5bag);
293 }
294
295 pub fn x5chain(&mut self, x5chain: Vec<Vec<u8>>, prot: bool, crit: bool) {
301 self.reg_label(X5CHAIN, prot, crit);
302 self.x5chain = Some(x5chain);
303 }
304
305 pub fn x5u(&mut self, x5u: String, prot: bool, crit: bool) {
311 self.reg_label(X5U, prot, crit);
312 self.x5u = Some(x5u);
313 }
314
315 pub fn x5chain_sender(&mut self, x5chain: Vec<Vec<u8>>, prot: bool, crit: bool) {
321 self.remove_label(EPHEMERAL_KEY);
322 self.remove_label(STATIC_KEY_ID);
323 self.remove_label(STATIC_KEY);
324 self.reg_label(X5CHAIN_SENDER, prot, crit);
325 self.x5chain_sender = Some(x5chain);
326 }
327
328 pub fn x5t(&mut self, x5: Vec<u8>, alg: i32, prot: bool, crit: bool) -> CoseResult {
335 if !HASH_ALGS.contains(&alg) {
336 return Err(CoseError::InvalidAlg());
337 }
338 self.reg_label(X5T, prot, crit);
339 self.x5t = Some(thumbprint(&x5, &alg)?);
340 self.x5t_alg = Some(alg);
341 Ok(())
342 }
343
344 pub fn x5_private(&mut self, x5: Vec<u8>) {
350 self.x5_private = x5;
351 }
352
353 pub fn x5t_sender(&mut self, x5: Vec<u8>, alg: i32, prot: bool, crit: bool) -> CoseResult {
360 if !HASH_ALGS.contains(&alg) {
361 return Err(CoseError::InvalidAlg());
362 }
363 self.reg_label(X5T_SENDER, prot, crit);
364 self.x5t_sender = Some(thumbprint(&x5, &alg)?);
365 self.x5t_sender_alg = Some(alg);
366 Ok(())
367 }
368
369 pub fn x5u_sender(&mut self, x5u: String, prot: bool, crit: bool) {
375 self.reg_label(X5U_SENDER, prot, crit);
376 self.x5u_sender = Some(x5u);
377 }
378
379 pub fn ephemeral_key(&mut self, key: keys::CoseKey, prot: bool, crit: bool) {
384 self.remove_label(X5T_SENDER);
385 self.remove_label(STATIC_KEY_ID);
386 self.remove_label(STATIC_KEY);
387 self.static_kid = None;
388 self.reg_label(EPHEMERAL_KEY, prot, crit);
389 self.ecdh_key = key;
390 }
391
392 pub fn static_key(&mut self, key: keys::CoseKey, prot: bool, crit: bool) {
397 self.remove_label(X5T_SENDER);
398 self.remove_label(STATIC_KEY_ID);
399 self.remove_label(EPHEMERAL_KEY);
400 self.static_kid = None;
401 self.reg_label(STATIC_KEY, prot, crit);
402 self.ecdh_key = key;
403 }
404
405 pub fn static_key_id(&mut self, kid: Vec<u8>, key: keys::CoseKey, prot: bool, crit: bool) {
410 self.remove_label(X5T_SENDER);
411 self.remove_label(STATIC_KEY);
412 self.remove_label(EPHEMERAL_KEY);
413 self.reg_label(STATIC_KEY_ID, prot, crit);
414 self.ecdh_key = key;
415 self.static_kid = Some(kid);
416 }
417
418 pub fn ecdh_key(&mut self, key: keys::CoseKey) {
422 self.ecdh_key = key;
423 }
424
425 pub(crate) fn encode_unprotected(&mut self, encoder: &mut Encoder<Vec<u8>>) -> CoseResult {
426 encoder.object(self.unprotected.len())?;
427 for i in 0..self.unprotected.len() {
428 if !self.labels_found.contains(&self.unprotected[i]) {
429 self.labels_found.push(self.unprotected[i]);
430 } else {
431 return Err(CoseError::DuplicateLabel(self.unprotected[i]));
432 };
433 encoder.i32(self.unprotected[i])?;
434 self.encode_label(self.unprotected[i], encoder, false)?;
435 }
436 Ok(())
437 }
438
439 pub(crate) fn get_protected_bstr(&mut self, verify_label: bool) -> CoseResultWithRet<Vec<u8>> {
440 let mut ph_bstr = Vec::new();
441 let mut encoder = Encoder::new(Vec::new());
442 let prot_len = self.protected.len();
443 let crit_len = self.crit.len();
444 if crit_len > 0 || prot_len > 0 {
445 if crit_len > 0 {
446 encoder.object(prot_len + 1)?;
447 encoder.i32(CRIT)?;
448 encoder.array(crit_len)?;
449 for i in &self.crit {
450 encoder.i32(*i)?;
451 }
452 } else {
453 encoder.object(prot_len)?;
454 }
455 for i in 0..self.protected.len() {
456 if verify_label {
457 if !self.labels_found.contains(&self.protected[i]) {
458 self.labels_found.push(self.protected[i]);
459 } else {
460 return Err(CoseError::DuplicateLabel(self.protected[i]));
461 };
462 }
463 encoder.i32(self.protected[i])?;
464 self.encode_label(self.protected[i], &mut encoder, true)?;
465 }
466 ph_bstr = encoder.into_writer().to_vec();
467 }
468 Ok(ph_bstr)
469 }
470
471 pub(crate) fn decode_unprotected(
472 &mut self,
473 decoder: &mut Decoder<Cursor<Vec<u8>>>,
474 is_counter_sig: bool,
475 ) -> CoseResult {
476 let unprot_len = decoder.object()?;
477 self.unprotected = Vec::new();
478 for _ in 0..unprot_len {
479 let label = decoder.i32()?;
480 if !self.labels_found.contains(&label) {
481 self.labels_found.push(label);
482 } else {
483 return Err(CoseError::DuplicateLabel(label));
484 }
485 self.decode_label(label, decoder, false, is_counter_sig)?;
486 }
487 Ok(())
488 }
489
490 pub(crate) fn decode_protected_bstr(&mut self, ph_bstr: &Vec<u8>) -> CoseResult {
491 let mut decoder = Decoder::new(Config::default(), Cursor::new(ph_bstr.clone()));
492 let prot_len = decoder.object()?;
493 self.protected = Vec::new();
494 for _ in 0..prot_len {
495 let label = decoder.i32()?;
496 if !self.labels_found.contains(&label) {
497 self.labels_found.push(label);
498 } else {
499 return Err(CoseError::DuplicateLabel(label));
500 };
501 self.decode_label(label, &mut decoder, true, false)?;
502 }
503 Ok(())
504 }
505
506 fn encode_label(
507 &mut self,
508 label: i32,
509 encoder: &mut Encoder<Vec<u8>>,
510 protected: bool,
511 ) -> CoseResult {
512 if label == ALG {
513 encoder.i32(self.alg.ok_or(CoseError::MissingAlg())?)?;
514 } else if label == KID {
515 encoder.bytes(&self.kid.as_ref().ok_or(CoseError::MissingKID())?)?;
516 } else if label == IV {
517 encoder.bytes(&self.iv.as_ref().ok_or(CoseError::MissingIV())?)?;
518 } else if label == PARTIAL_IV {
519 encoder.bytes(
520 &self
521 .partial_iv
522 .as_ref()
523 .ok_or(CoseError::MissingPartialIV())?,
524 )?;
525 } else if label == SALT {
526 encoder.bytes(&self.salt.as_ref().ok_or(CoseError::MissingSalt())?)?;
527 } else if label == CONTENT_TYPE {
528 match &self
529 .content_type
530 .as_ref()
531 .ok_or(CoseError::MissingContentType())?
532 {
533 ContentTypeTypes::Uint(v) => encoder.u32(*v)?,
534 ContentTypeTypes::Tstr(v) => encoder.text(v)?,
535 }
536 } else if label == PARTY_U_IDENTITY {
537 encoder.bytes(
538 &self
539 .party_u_identity
540 .as_ref()
541 .ok_or(CoseError::MissingPartyUID())?,
542 )?;
543 } else if label == PARTY_U_NONCE {
544 encoder.bytes(
545 &self
546 .party_u_nonce
547 .as_ref()
548 .ok_or(CoseError::MissingPartyUNonce())?,
549 )?;
550 } else if label == PARTY_U_OTHER {
551 encoder.bytes(
552 &self
553 .party_u_other
554 .as_ref()
555 .ok_or(CoseError::MissingPartyUOther())?,
556 )?;
557 } else if label == PARTY_V_IDENTITY {
558 encoder.bytes(
559 &self
560 .party_v_identity
561 .as_ref()
562 .ok_or(CoseError::MissingPartyVID())?,
563 )?;
564 } else if label == PARTY_V_NONCE {
565 encoder.bytes(
566 &self
567 .party_v_nonce
568 .as_ref()
569 .ok_or(CoseError::MissingPartyVNonce())?,
570 )?;
571 } else if label == PARTY_V_OTHER {
572 encoder.bytes(
573 &self
574 .party_v_other
575 .as_ref()
576 .ok_or(CoseError::MissingPartyVOther())?,
577 )?;
578 } else if [X5BAG, X5CHAIN, X5CHAIN_SENDER].contains(&label) {
579 let x5;
580 if label == X5BAG {
581 x5 = self.x5bag.as_ref().ok_or(CoseError::MissingX5Bag())?;
582 } else if label == X5CHAIN {
583 x5 = self.x5chain.as_ref().ok_or(CoseError::MissingX5Chain())?;
584 } else {
585 x5 = self
586 .x5chain_sender
587 .as_ref()
588 .ok_or(CoseError::MissingX5Chain())?;
589 }
590 let x5_len = x5.len();
591 if x5_len > 0 {
592 if x5_len == 1 {
593 encoder.bytes(&x5[0])?;
594 } else {
595 if label != X5BAG {
596 verify_chain(&x5)?;
597 }
598 encoder.array(x5_len)?;
599 for x in x5 {
600 encoder.bytes(x)?;
601 }
602 }
603 }
604 } else if label == X5T {
605 let x5t = self.x5t.as_ref().ok_or(CoseError::MissingX5T())?;
606 let x5t_alg = self.x5t_alg.ok_or(CoseError::MissingX5T())?;
607 if self.x5chain != None {
608 verify_thumbprint(&self.x5chain.as_ref().unwrap()[0].clone(), &x5t, &x5t_alg)?;
609 }
610 encoder.array(2)?;
611 encoder.i32(x5t_alg)?;
612 encoder.bytes(x5t)?;
613 } else if label == X5T_SENDER {
614 let x5t_sender = self
615 .x5t_sender
616 .as_ref()
617 .ok_or(CoseError::MissingX5TSender())?;
618 let x5t_sender_alg = self.x5t_sender_alg.ok_or(CoseError::MissingX5TSender())?;
619 if self.x5chain_sender != None {
620 verify_thumbprint(
621 &self.x5chain_sender.as_ref().unwrap()[0].clone(),
622 &x5t_sender,
623 &x5t_sender_alg,
624 )?;
625 }
626 encoder.array(2)?;
627 encoder.i32(x5t_sender_alg)?;
628 encoder.bytes(x5t_sender)?;
629 } else if label == X5U {
630 encoder.text(self.x5u.as_ref().ok_or(CoseError::MissingX5U())?)?;
631 } else if label == X5U_SENDER {
632 encoder.text(
633 self.x5u_sender
634 .as_ref()
635 .ok_or(CoseError::MissingX5USender())?,
636 )?;
637 } else if label == EPHEMERAL_KEY || label == STATIC_KEY {
638 let mut encode_ecdh = self.ecdh_key.clone();
639 encode_ecdh.remove_label(keys::D);
640 encode_ecdh.d = None;
641 encode_ecdh.encode_key(encoder)?;
642 } else if label == STATIC_KEY_ID {
643 encoder.bytes(
644 &self
645 .static_kid
646 .as_ref()
647 .ok_or(CoseError::MissingStaticKID())?,
648 )?;
649 } else if label == COUNTER_SIG && !protected {
650 if self.counters.len() > 1 {
651 encoder.array(self.counters.len())?;
652 }
653 for counter in &mut self.counters {
654 counter.encode(encoder)?;
655 }
656 } else {
657 return Err(CoseError::InvalidLabel(label));
658 }
659 Ok(())
660 }
661
662 fn decode_label(
663 &mut self,
664 label: i32,
665 decoder: &mut Decoder<Cursor<Vec<u8>>>,
666 protected: bool,
667 is_counter_sig: bool,
668 ) -> CoseResult {
669 if protected {
670 self.protected.push(label);
671 } else {
672 self.unprotected.push(label);
673 }
674 if label == ALG {
675 let type_info = decoder.kernel().typeinfo()?;
676 if type_info.0 == Type::Text {
677 self.alg = Some(common::get_alg_id(
678 std::str::from_utf8(
679 &decoder.kernel().raw_data(type_info.1, common::MAX_BYTES)?,
680 )
681 .unwrap()
682 .to_string(),
683 )?);
684 } else if common::CBOR_NUMBER_TYPES.contains(&type_info.0) {
685 self.alg = Some(decoder.kernel().i32(&type_info)?);
686 } else {
687 return Err(CoseError::InvalidCoseStructure());
688 }
689 } else if label == CRIT && protected {
690 self.crit = Vec::new();
691 for _ in 0..decoder.array()? {
692 self.crit.push(decoder.i32()?);
693 }
694 } else if label == CONTENT_TYPE {
695 let type_info = decoder.kernel().typeinfo()?;
696 if type_info.0 == Type::Text {
697 self.content_type = Some(ContentTypeTypes::Tstr(
698 std::str::from_utf8(
699 &decoder.kernel().raw_data(type_info.1, common::MAX_BYTES)?,
700 )
701 .unwrap()
702 .to_string(),
703 ));
704 } else if UINT.contains(&type_info.0) {
705 self.content_type = Some(ContentTypeTypes::Uint(decoder.kernel().u32(&type_info)?));
706 } else {
707 return Err(CoseError::InvalidCoseStructure());
708 }
709 } else if label == KID {
710 let type_info = decoder.kernel().typeinfo()?;
711 if type_info.0 == Type::Bytes {
712 self.kid = Some(decoder.kernel().raw_data(type_info.1, common::MAX_BYTES)?);
713 } else if type_info.0 == Type::Text {
714 self.kid = Some(decoder.kernel().raw_data(type_info.1, common::MAX_BYTES)?);
715 } else {
716 return Err(CoseError::InvalidCoseStructure());
717 }
718 } else if label == IV {
719 self.iv = Some(decoder.bytes()?.to_vec());
720 } else if label == SALT {
721 self.salt = Some(decoder.bytes()?.to_vec());
722 } else if label == PARTY_U_IDENTITY {
723 self.party_u_identity = Some(decoder.bytes()?.to_vec());
724 } else if label == PARTY_U_NONCE {
725 self.party_u_nonce = match decoder.bytes() {
726 Ok(value) => Some(value),
727 Err(ref err) => match err {
728 cbor::decoder::DecodeError::UnexpectedType { datatype, info: _ } => {
729 if *datatype == Type::Bool {
730 None
731 } else {
732 return Err(CoseError::InvalidCoseStructure());
733 }
734 }
735 _ => {
736 return Err(CoseError::InvalidCoseStructure());
737 }
738 },
739 };
740 } else if label == PARTY_U_OTHER {
741 self.party_u_other = Some(decoder.bytes()?.to_vec());
742 } else if label == PARTY_V_IDENTITY {
743 self.party_v_identity = Some(decoder.bytes()?.to_vec());
744 } else if label == PARTY_V_NONCE {
745 self.party_v_nonce = match decoder.bytes() {
746 Ok(value) => Some(value),
747 Err(ref err) => match err {
748 cbor::decoder::DecodeError::UnexpectedType { datatype, info: _ } => {
749 if *datatype == Type::Bool {
750 None
751 } else {
752 return Err(CoseError::InvalidCoseStructure());
753 }
754 }
755 _ => {
756 return Err(CoseError::InvalidCoseStructure());
757 }
758 },
759 };
760 } else if label == PARTY_V_OTHER {
761 self.party_v_other = Some(decoder.bytes()?.to_vec());
762 } else if label == PARTIAL_IV {
763 self.partial_iv = Some(decoder.bytes()?.to_vec());
764 } else if [X5BAG, X5CHAIN, X5CHAIN_SENDER].contains(&label) {
765 let type_info = decoder.kernel().typeinfo()?;
766 if type_info.0 == Type::Array {
767 let x5_len = type_info.1;
768 let mut x5 = Vec::new();
769 for _ in 0..x5_len {
770 x5.push(decoder.bytes()?.to_vec());
771 }
772 if label == X5BAG {
773 self.x5bag = Some(x5);
774 } else if label == X5CHAIN {
775 verify_chain(&x5)?;
776 self.x5chain = Some(x5);
777 } else {
778 verify_chain(&x5)?;
779 self.x5chain_sender = Some(x5);
780 }
781 } else if type_info.0 == Type::Bytes {
782 let x5 = Some(vec![decoder
783 .kernel()
784 .raw_data(type_info.1, common::MAX_BYTES)?]);
785 if label == X5BAG {
786 self.x5bag = x5;
787 } else if label == X5CHAIN {
788 self.x5chain = x5;
789 } else {
790 self.x5chain_sender = x5;
791 }
792 } else {
793 return Err(CoseError::InvalidCoseStructure());
794 }
795 } else if [X5T, X5T_SENDER].contains(&label) {
796 if decoder.array()? != 2 {
797 return Err(CoseError::InvalidCoseStructure());
798 }
799 let type_info = decoder.kernel().typeinfo()?;
800 let x5t_alg;
801 if type_info.0 == Type::Text {
802 x5t_alg = Some(common::get_alg_id(
803 std::str::from_utf8(
804 &decoder.kernel().raw_data(type_info.1, common::MAX_BYTES)?,
805 )
806 .unwrap()
807 .to_string(),
808 )?);
809 } else if common::CBOR_NUMBER_TYPES.contains(&type_info.0) {
810 x5t_alg = Some(decoder.kernel().i32(&type_info)?);
811 } else {
812 return Err(CoseError::InvalidCoseStructure());
813 }
814 let x5t = Some(decoder.bytes()?);
815 if label == X5T {
816 if self.x5chain != None {
817 verify_thumbprint(
818 &self.x5chain.as_ref().unwrap()[0].clone(),
819 &x5t.as_ref().unwrap(),
820 &x5t_alg.as_ref().unwrap(),
821 )?;
822 }
823 self.x5t = x5t;
824 self.x5t_alg = x5t_alg;
825 } else {
826 if self.x5chain_sender != None {
827 verify_thumbprint(
828 &self.x5chain_sender.as_ref().unwrap()[0].clone(),
829 &x5t.as_ref().unwrap(),
830 &x5t_alg.as_ref().unwrap(),
831 )?;
832 }
833 self.x5t_sender = x5t;
834 self.x5t_sender_alg = x5t_alg;
835 }
836 } else if label == X5U {
837 self.x5u = Some(decoder.text()?);
838 } else if label == X5U_SENDER {
839 self.x5u_sender = Some(decoder.text()?);
840 } else if label == EPHEMERAL_KEY {
841 if [X5CHAIN_SENDER, STATIC_KEY, STATIC_KEY_ID]
842 .iter()
843 .any(|i| self.labels_found.contains(i))
844 {
845 return Err(CoseError::InvalidCoseStructure());
846 }
847 self.ecdh_key.decode_key(decoder)?;
848 } else if label == STATIC_KEY {
849 if [X5CHAIN_SENDER, EPHEMERAL_KEY, STATIC_KEY_ID]
850 .iter()
851 .any(|i| self.labels_found.contains(i))
852 {
853 return Err(CoseError::InvalidCoseStructure());
854 }
855 self.ecdh_key.decode_key(decoder)?;
856 } else if label == STATIC_KEY_ID {
857 if [X5CHAIN_SENDER, EPHEMERAL_KEY, STATIC_KEY]
858 .iter()
859 .any(|i| self.labels_found.contains(i))
860 {
861 return Err(CoseError::InvalidCoseStructure());
862 }
863 self.static_kid = Some(decoder.bytes()?.to_vec());
864 } else if label == COUNTER_SIG && !is_counter_sig {
865 let mut counter = CoseAgent::new_counter_sig();
866 let n = decoder.array()?;
867 let mut n1 = 0;
868 match decoder.bytes() {
869 Ok(value) => {
870 counter.ph_bstr = value;
871 }
872 Err(ref err) => match err {
873 cbor::decoder::DecodeError::UnexpectedType { datatype, info } => {
874 if *datatype == Type::Array {
875 n1 = *info;
876 }
877 }
878 _ => {
879 return Err(CoseError::InvalidCoseStructure());
880 }
881 },
882 };
883 if n1 == 0 && n == 3 {
884 counter.decode(decoder)?;
885 self.counters.push(counter);
886 } else {
887 counter.ph_bstr = decoder.bytes()?;
888 counter.decode(decoder)?;
889 self.counters.push(counter);
890 for _ in 1..n {
891 counter = CoseAgent::new_counter_sig();
892 decoder.array()?;
893 counter.ph_bstr = decoder.bytes()?;
894 counter.decode(decoder)?;
895 self.counters.push(counter);
896 }
897 }
898 } else {
899 return Err(CoseError::InvalidLabel(label));
900 }
901 Ok(())
902 }
903
904 pub fn get_counter(&self, kid: &Vec<u8>) -> CoseResultWithRet<Vec<usize>> {
906 let mut counters: Vec<usize> = Vec::new();
907 for i in 0..self.counters.len() {
908 if self.counters[i]
909 .header
910 .kid
911 .as_ref()
912 .ok_or(CoseError::MissingKID())?
913 == kid
914 {
915 counters.push(i);
916 }
917 }
918 Ok(counters)
919 }
920}