1 //! Parsing and encoding DICE chain from and to CBOR.
2 
3 use anyhow::Result;
4 use ciborium::value::Value;
5 use coset::iana::{self, EnumI64};
6 use coset::{AsCborValue, CoseKey, Label};
7 
8 mod chain;
9 mod entry;
10 mod profile;
11 
12 /// Type allowed for the COSE_Key object key_ops field in the DICE chain.
13 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
14 pub(super) enum KeyOpsType {
15     /// The key_ops field must be an array as specified in the RFC 9052.
16     #[default]
17     Array,
18     /// The key_ops field can be either a single int or an array.
19     IntOrArray,
20 }
21 
22 /// Convert a `Value` into a `CoseKey`, respecting the `Session` options that might alter the
23 /// validation rules for `CoseKey`s in the DICE chain.
cose_key_from_cbor_value(mut value: Value, key_ops_type: KeyOpsType) -> Result<CoseKey>24 fn cose_key_from_cbor_value(mut value: Value, key_ops_type: KeyOpsType) -> Result<CoseKey> {
25     if key_ops_type == KeyOpsType::IntOrArray {
26         // Convert any integer key_ops into an array of the same integer so that the coset library
27         // can handle it.
28         if let Value::Map(ref mut entries) = value {
29             for (label, value) in entries.iter_mut() {
30                 let label = Label::from_cbor_value(label.clone())?;
31                 if label == Label::Int(iana::KeyParameter::KeyOps.to_i64()) && value.is_integer() {
32                     *value = Value::Array(vec![value.clone()]);
33                 }
34             }
35         }
36     }
37     Ok(CoseKey::from_cbor_value(value)?)
38 }
39