[refactoring] Group all the CBOR util functions in cbor_util

This cl only moves all the CBOR utility functions in one place.
Some return error types are adjusted to adapt the change. There
should be no behavior change.

Bug: 310931749
Test: atest rialto_test
Change-Id: Ie3db9c93b1355d25d7d796818e19e554560e1f23
diff --git a/libs/cborutil/src/lib.rs b/libs/cborutil/src/lib.rs
index 2ec5af4..6e834f1 100644
--- a/libs/cborutil/src/lib.rs
+++ b/libs/cborutil/src/lib.rs
@@ -18,8 +18,11 @@
 
 extern crate alloc;
 
+use alloc::string::String;
 use alloc::vec::Vec;
-use coset::{CoseError, Result};
+use ciborium::value::{Integer, Value};
+use coset::{CoseError, CoseKey, Label, Result};
+use log::error;
 use serde::{de::DeserializeOwned, Serialize};
 
 /// Serializes the given data to a CBOR-encoded byte vector.
@@ -39,3 +42,88 @@
         Err(CoseError::ExtraneousData)
     }
 }
+
+/// Converts the provided value `v` to a value array.
+pub fn value_to_array(v: Value, context: &'static str) -> Result<Vec<Value>> {
+    v.into_array().map_err(|e| to_unexpected_item_error(&e, "array", context))
+}
+
+/// Converts the provided value `v` to a text string.
+pub fn value_to_text(v: Value, context: &'static str) -> Result<String> {
+    v.into_text().map_err(|e| to_unexpected_item_error(&e, "tstr", context))
+}
+
+/// Converts the provided value `v` to a map.
+pub fn value_to_map(v: Value, context: &'static str) -> Result<Vec<(Value, Value)>> {
+    v.into_map().map_err(|e| to_unexpected_item_error(&e, "map", context))
+}
+
+/// Converts the provided value `v` to a number.
+pub fn value_to_num<T: TryFrom<Integer>>(v: Value, context: &'static str) -> Result<T> {
+    let num = v.into_integer().map_err(|e| to_unexpected_item_error(&e, "int", context))?;
+    num.try_into().map_err(|_| {
+        error!("The provided value '{num:?}' is not a valid number: {context}");
+        CoseError::OutOfRangeIntegerValue
+    })
+}
+
+/// Converts the provided value `v` to a byte array of length `N`.
+pub fn value_to_byte_array<const N: usize>(v: Value, context: &'static str) -> Result<[u8; N]> {
+    let arr = value_to_bytes(v, context)?;
+    arr.try_into().map_err(|e| {
+        error!("The provided value '{context}' is not an array of length {N}: {e:?}");
+        CoseError::UnexpectedItem("bstr", "array of length {N}")
+    })
+}
+
+/// Converts the provided value `v` to bytes array.
+pub fn value_to_bytes(v: Value, context: &'static str) -> Result<Vec<u8>> {
+    v.into_bytes().map_err(|e| to_unexpected_item_error(&e, "bstr", context))
+}
+
+/// Builds a `CoseError::UnexpectedItem` error when the provided value `v` is not of the expected
+/// type `expected_type` and logs the error message with the provided `context`.
+pub fn to_unexpected_item_error(
+    v: &Value,
+    expected_type: &'static str,
+    context: &'static str,
+) -> CoseError {
+    let v_type = cbor_value_type(v);
+    assert!(v_type != expected_type);
+    error!("The provided value type '{v_type}' is not of type '{expected_type}': {context}");
+    CoseError::UnexpectedItem(v_type, expected_type)
+}
+
+/// Reads the type of the provided value `v`.
+pub fn cbor_value_type(v: &Value) -> &'static str {
+    match v {
+        Value::Integer(_) => "int",
+        Value::Bytes(_) => "bstr",
+        Value::Float(_) => "float",
+        Value::Text(_) => "tstr",
+        Value::Bool(_) => "bool",
+        Value::Null => "nul",
+        Value::Tag(_, _) => "tag",
+        Value::Array(_) => "array",
+        Value::Map(_) => "map",
+        _ => "other",
+    }
+}
+
+/// Returns the value of the given label in the given COSE key as bytes.
+pub fn get_label_value_as_bytes(key: &CoseKey, label: Label) -> Result<&[u8]> {
+    let v = get_label_value(key, label)?;
+    Ok(v.as_bytes().ok_or_else(|| {
+        to_unexpected_item_error(v, "bstr", "Get label value in CoseKey as bytes")
+    })?)
+}
+
+/// Returns the value of the given label in the given COSE key.
+pub fn get_label_value(key: &CoseKey, label: Label) -> Result<&Value> {
+    Ok(&key
+        .params
+        .iter()
+        .find(|(k, _)| k == &label)
+        .ok_or(CoseError::UnexpectedItem("", "Label not found in CoseKey"))?
+        .1)
+}