matc 0.1.3

Matter protocol library (controller side)
Documentation
use anyhow::Result;

use crate::{fabric, sigma};

use super::Device;

/// Test Certification Declaration (CMS SignedData) from the Matter SDK.
/// This is a minimal placeholder for development - real devices need a proper CD
/// issued by the CSA.
pub(crate) const TEST_CERTIFICATION_DECLARATION: &[u8] = &[
    0x30, 0x81, 0xE9, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02, 0xA0, 0x81,
    0xDB, 0x30, 0x81, 0xD8, 0x02, 0x01, 0x03, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x09, 0x60, 0x86, 0x48,
    0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, 0x45, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D,
    0x01, 0x07, 0x01, 0xA0, 0x38, 0x04, 0x36, 0x15, 0x24, 0x00, 0x01, 0x25, 0x01, 0xF1, 0xFF, 0x36,
    0x02, 0x05, 0x00, 0x80, 0x18, 0x25, 0x03, 0x34, 0x12, 0x2C, 0x04, 0x13, 0x5A, 0x49, 0x47, 0x32,
    0x30, 0x31, 0x34, 0x31, 0x5A, 0x42, 0x33, 0x33, 0x30, 0x30, 0x30, 0x31, 0x2D, 0x32, 0x34, 0x24,
    0x05, 0x00, 0x24, 0x06, 0x00, 0x25, 0x07, 0x94, 0x26, 0x24, 0x08, 0x00, 0x18, 0x31, 0x7D, 0x30,
    0x7B, 0x02, 0x01, 0x03, 0x80, 0x14, 0x62, 0xFA, 0x82, 0x33, 0x59, 0xAC, 0xFA, 0xA9, 0x96, 0x3E,
    0x1C, 0xFA, 0x14, 0x0A, 0xDD, 0xF5, 0x04, 0xF3, 0x71, 0x60, 0x30, 0x0B, 0x06, 0x09, 0x60, 0x86,
    0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D,
    0x04, 0x03, 0x02, 0x04, 0x47, 0x30, 0x45, 0x02, 0x20, 0x24, 0xE5, 0xD1, 0xF4, 0x7A, 0x7D, 0x7B,
    0x0D, 0x20, 0x6A, 0x26, 0xEF, 0x69, 0x9B, 0x7C, 0x97, 0x57, 0xB7, 0x2D, 0x46, 0x90, 0x89, 0xDE,
    0x31, 0x92, 0xE6, 0x78, 0xC7, 0x45, 0xE7, 0xF6, 0x0C, 0x02, 0x21, 0x00, 0xF8, 0xAA, 0x2F, 0xA7,
    0x11, 0xFC, 0xB7, 0x9B, 0x97, 0xE3, 0x97, 0xCE, 0xDA, 0x66, 0x7B, 0xAE, 0x46, 0x4E, 0x2B, 0xD3,
    0xFF, 0xDF, 0xC3, 0xCC, 0xED, 0x7A, 0xA8, 0xCA, 0x5F, 0x4C, 0x1A, 0x7C,
];

impl Device {
    pub(crate) fn load_dac_signing_key(&self) -> Result<ecdsa::SigningKey<p256::NistP256>> {
        let dac_key =
            crate::util::cryptoutil::read_private_key_from_pem(&self.config.dac_key_path)?;
        Ok(ecdsa::SigningKey::from(dac_key))
    }

    /// Search all commissioned fabrics for one whose destination ID matches the
    /// Sigma1 request.  Returns the index into `self.fabrics`.
    pub(crate) fn find_fabric_by_destination_id(
        &self,
        initiator_random: &[u8],
        received_destination_id: &[u8],
    ) -> Option<usize> {
        for (i, fi) in self.fabrics.iter().enumerate() {
            let ca_public_key = match fi.ca_public_key() {
                Ok(k) => k,
                Err(_) => continue,
            };
            let fabric_id = match fi.fabric_id() {
                Ok(id) => id,
                Err(_) => continue,
            };
            let ca_id = match fi.ca_id() {
                Ok(id) => id,
                Err(_) => continue,
            };
            let device_node_id = match fi.device_node_id() {
                Ok(id) => id,
                Err(_) => continue,
            };
            let mut fab = fabric::Fabric::new(fabric_id, ca_id, &ca_public_key);
            fab.ipk_epoch_key = fi.ipk.clone();
            if sigma::verify_destination_id(
                initiator_random,
                received_destination_id,
                &fab,
                &ca_public_key,
                device_node_id,
            )
            .is_ok()
            {
                return Some(i);
            }
        }
        None
    }
}