diff --git a/rs-matter/src/cert/builder.rs b/rs-matter/src/cert/builder.rs index a8093963..c7c63e88 100644 --- a/rs-matter/src/cert/builder.rs +++ b/rs-matter/src/cert/builder.rs @@ -43,13 +43,6 @@ enum CertType { Noc, } -/// Internal shared certificate builder implementation. -/// -/// Contains all the common logic for building Noc, Icac, and Rcac certificates. -struct CertBuilderCore<'a> { - buf: &'a mut [u8], -} - pub struct IssuerDN { pub(crate) ca_id: Option, pub(crate) fabric_id: Option, @@ -64,10 +57,40 @@ pub struct SubjectDN<'a> { pub(crate) ca_id: Option, } +/// Validity period for certificates, represented as seconds since the Matter epoch (2000-01-01T00:00:00Z). #[derive(Clone, Copy)] pub struct Validity { - pub(crate) not_before: u32, - pub(crate) not_after: u32, + /// NotBefore time (seconds since Matter epoch) + /// + /// This must not be 0 (the Matter epoch start) to avoid collision with CHIP's epoch=0 sentinel in ASN.1 time encoding. + pub not_before: u32, + /// NotAfter time (seconds since Matter epoch, 0 = no expiry) + pub not_after: u32, +} + +// NotBefore MUST NOT be 0 (Matter epoch start, 2000-01-01). +// CHIP's ChipEpochToASN1Time treats epoch=0 as the "no +// well-defined expiration date" sentinel and re-emits it as +// GeneralizedTime "99991231235959Z" regardless of which field +// it appears in (see CHIPCert.cpp:1076-1106 and the +// explanatory comment about CHIP epoch 0 NotBefore producing +// an invalid TBS signature on round-trip). +// +// We sign over UTCTime "000101000000Z" (Matter epoch); CHIP +// would reconstruct GeneralizedTime "99991231235959Z" and the +// hash would mismatch. Using 1 second past the Matter epoch +// avoids the sentinel collision while keeping the cert +// effectively unbounded on the lower end. +pub const VALID_FOREVER: Validity = Validity { + not_before: 1, // 2000-01-01 00:00:01 — past CHIP's epoch=0 sentinel + not_after: 0, // no expiry (NotAfter sentinel is legitimate) +}; + +/// Internal shared certificate builder implementation. +/// +/// Contains all the common logic for building Noc, Icac, and Rcac certificates. +struct CertBuilderCore<'a> { + buf: &'a mut [u8], } impl<'a> CertBuilderCore<'a> { @@ -263,20 +286,21 @@ impl<'a> CertBuilderCore<'a> { subject_key_id: &KeyId, authority_key_id: &KeyId, ) -> Result<(), Error> { - // 1. Basic Constraints + // 1. Basic Constraints — per Matter Spec: + // RCAC: cA = TRUE, pathLenConstraint shall NOT be present + // ICAC: cA = TRUE, pathLenConstraint = 0 + // NOC: cA = FALSE, pathLenConstraint shall NOT be present tw.start_struct(&TLVTag::Context(1))?; match cert_type { CertType::Rcac => { - tw.bool(&TLVTag::Context(1), true)?; // is_ca = true - tw.u8(&TLVTag::Context(2), 1)?; // path_len = 1 + tw.bool(&TLVTag::Context(1), true)?; } CertType::Icac => { - tw.bool(&TLVTag::Context(1), true)?; // is_ca = true + tw.bool(&TLVTag::Context(1), true)?; tw.u8(&TLVTag::Context(2), 0)?; // path_len = 0 } CertType::Noc => { - tw.bool(&TLVTag::Context(1), false)?; // is_ca = false - // No path_len for end entity + tw.bool(&TLVTag::Context(1), false)?; } } tw.end_container()?; @@ -581,12 +605,13 @@ impl<'a> RcacBuilder<'a> { #[cfg(test)] mod tests { - use super::*; use crate::{ cert::{MAX_CERT_TLV_AND_ASN1_LEN, MAX_CERT_TLV_LEN}, crypto::{test_only_crypto, CanonPkcPublicKey, PublicKey, SigningSecretKey}, }; + use super::*; + #[test] fn test_validate_cat_id_valid() { // Version = 1, identifier = 0x1234 @@ -659,6 +684,41 @@ mod tests { assert!(len < MAX_CERT_TLV_LEN); } + #[test] + fn test_rcac_self_verify() { + let crypto = test_only_crypto(); + let rcac_secret_key = unwrap!(crypto.generate_secret_key()); + let rcac_pubkey = rcac_secret_key.pub_key().unwrap(); + + let subject = SubjectDN { + node_id: None, + fabric_id: Some(0x0000_0000_0000_0001), + cat_ids: &[], + ca_id: Some(0x1122_3344_5566_7788), + }; + let mut cert_buf = [0u8; MAX_CERT_TLV_AND_ASN1_LEN]; + let mut builder = RcacBuilder::new(&mut cert_buf); + let len = unwrap!(builder.build( + &crypto, + subject, + VALID_FOREVER, + &rcac_pubkey, + &rcac_secret_key, + &[0x01], + )); + + // Re-parse the just-built RCAC and self-verify. + let cert = CertRef::new(crate::tlv::TLVElement::new(&cert_buf[..len])); + let mut scratch = [0u8; MAX_CERT_TLV_AND_ASN1_LEN]; + let res = cert + .verify_chain_start(&crypto, VALID_FOREVER.not_before as _) + .finalise(&mut scratch); + assert!( + res.is_ok(), + "RCAC built by RcacBuilder failed self-verification: {res:?}" + ); + } + /// Test building an ICAC signed by RCAC #[test] fn test_build_icac() { @@ -676,8 +736,6 @@ mod tests { let icac_id = 0x1234u64; let rcac_id = 0x5678u64; let fabric_id = 0x0000000000000001u64; - let not_before = 0u32; - let not_after = 0u32; let subject = SubjectDN { node_id: None, @@ -686,11 +744,6 @@ mod tests { ca_id: Some(icac_id), }; - let validity = Validity { - not_before, - not_after, - }; - let issuer = IssuerDN { ca_id: Some(rcac_id), fabric_id: Some(fabric_id), @@ -703,7 +756,7 @@ mod tests { let len = unwrap!(builder.build( &crypto, subject, - validity, + VALID_FOREVER, &icac_pubkey, &rcac_pubkey, &rcac_secret_key, diff --git a/rs-matter/src/commissioner/fabric_credentials.rs b/rs-matter/src/commissioner/fabric_credentials.rs index 75249fe0..78cb6a55 100644 --- a/rs-matter/src/commissioner/fabric_credentials.rs +++ b/rs-matter/src/commissioner/fabric_credentials.rs @@ -21,6 +21,7 @@ //! during commissioning. It combines NOC generation with IPK management //! and node ID assignment. +use crate::cert::builder::Validity; use crate::cert::MAX_CERT_TLV_LEN; use crate::crypto::{CanonAeadKey, CanonAeadKeyRef, Crypto, RngCore, AEAD_CANON_KEY_LEN}; use crate::error::Error; @@ -90,8 +91,9 @@ impl FabricCredentials { /// # Arguments /// * `crypto` - Cryptographic backend /// * `fabric_id` - The fabric identifier - pub fn new(crypto: &C, fabric_id: u64) -> Result { - let noc_generator = NocGenerator::new(crypto, fabric_id)?; + /// * `validity` - Validity period for generated certificates + pub fn new(crypto: &C, fabric_id: u64, validity: Validity) -> Result { + let noc_generator = NocGenerator::new(crypto, fabric_id, validity)?; let mut ipk = CanonAeadKey::new(); let mut ipk_bytes = [0u8; AEAD_CANON_KEY_LEN]; crypto.rand()?.fill_bytes(&mut ipk_bytes); @@ -110,15 +112,17 @@ impl FabricCredentials { /// * `crypto` - Cryptographic backend /// * `fabric_id` - The fabric identifier /// * `starting_node_id` - The first node ID to assign + /// * `validity` - Validity period for generated certificates pub fn with_starting_node_id( crypto: &C, fabric_id: u64, starting_node_id: u64, + validity: Validity, ) -> Result { if starting_node_id < 1 { return Err(crate::error::ErrorCode::InvalidData.into()); } - let mut creds = Self::new(crypto, fabric_id)?; + let mut creds = Self::new(crypto, fabric_id, validity)?; creds.next_node_id = starting_node_id; Ok(creds) } @@ -265,11 +269,13 @@ impl FabricCredentials { #[cfg(test)] mod tests { - use super::*; + use crate::cert::builder::VALID_FOREVER; use crate::cert::CertRef; use crate::crypto::{test_only_crypto, AEAD_KEY_ZEROED}; use crate::tlv::TLVElement; + use super::*; + /// Valid CSR from C++ test (TestChipCryptoPAL.cpp) /// This CSR has a valid signature and can be verified. const GOOD_CSR: &[u8] = &[ @@ -318,7 +324,7 @@ mod tests { let crypto = test_only_crypto(); let fabric_id = 0x1234567890ABCDEFu64; - let creds = unwrap!(FabricCredentials::new(&crypto, fabric_id)); + let creds = unwrap!(FabricCredentials::new(&crypto, fabric_id, VALID_FOREVER)); // Should have root cert assert!(!creds.root_cert().is_empty()); @@ -339,7 +345,8 @@ mod tests { let creds = unwrap!(FabricCredentials::with_starting_node_id( &crypto, fabric_id, - starting_node_id + starting_node_id, + VALID_FOREVER, )); assert_eq!(creds.peek_next_node_id(), starting_node_id); @@ -349,7 +356,7 @@ mod tests { fn test_node_id_auto_increment() { let crypto = test_only_crypto(); let fabric_id = 0x1u64; - let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id)); + let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id, VALID_FOREVER)); let csr = generate_test_csr(); @@ -370,7 +377,7 @@ mod tests { fn test_peek_next_node_id_doesnt_increment() { let crypto = test_only_crypto(); let fabric_id = 0x1u64; - let creds = unwrap!(FabricCredentials::new(&crypto, fabric_id)); + let creds = unwrap!(FabricCredentials::new(&crypto, fabric_id, VALID_FOREVER)); let id1 = creds.peek_next_node_id(); let id2 = creds.peek_next_node_id(); @@ -385,7 +392,7 @@ mod tests { fn test_custom_node_id_doesnt_affect_counter() { let crypto = test_only_crypto(); let fabric_id = 0x1u64; - let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id)); + let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id, VALID_FOREVER)); let csr = generate_test_csr(); @@ -406,7 +413,7 @@ mod tests { fn test_generate_device_credentials_basic() { let crypto = test_only_crypto(); let fabric_id = 0x1u64; - let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id)); + let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id, VALID_FOREVER)); let csr = generate_test_csr(); @@ -428,7 +435,7 @@ mod tests { fn test_device_credentials_with_cat_ids() { let crypto = test_only_crypto(); let fabric_id = 0x1u64; - let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id)); + let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id, VALID_FOREVER)); let csr = generate_test_csr(); let cat_ids = &[0x00011111u32, 0x00022222u32]; @@ -443,7 +450,7 @@ mod tests { fn test_enable_icac() { let crypto = test_only_crypto(); let fabric_id = 0x1u64; - let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id)); + let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id, VALID_FOREVER)); // Initially no ICAC assert!(creds.icac_cert().is_none()); @@ -459,7 +466,7 @@ mod tests { fn test_device_credentials_includes_icac_when_enabled() { let crypto = test_only_crypto(); let fabric_id = 0x1u64; - let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id)); + let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id, VALID_FOREVER)); let csr = generate_test_csr(); @@ -477,7 +484,7 @@ mod tests { fn test_icac_cert_available_after_enable() { let crypto = test_only_crypto(); let fabric_id = 0x1u64; - let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id)); + let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id, VALID_FOREVER)); assert!(creds.icac_cert().is_none()); @@ -491,7 +498,7 @@ mod tests { fn test_noc_signed_by_icac_when_enabled() { let crypto = test_only_crypto(); let fabric_id = 0x1u64; - let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id)); + let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id, VALID_FOREVER)); let csr = generate_test_csr(); @@ -511,7 +518,7 @@ mod tests { fn test_ipk_is_generated() { let crypto = test_only_crypto(); let fabric_id = 0x1u64; - let creds = unwrap!(FabricCredentials::new(&crypto, fabric_id)); + let creds = unwrap!(FabricCredentials::new(&crypto, fabric_id, VALID_FOREVER)); let ipk = creds.ipk(); @@ -524,7 +531,7 @@ mod tests { fn test_set_custom_ipk() { let crypto = test_only_crypto(); let fabric_id = 0x1u64; - let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id)); + let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id, VALID_FOREVER)); let custom_ipk = [0x42u8; AEAD_CANON_KEY_LEN]; creds.set_ipk(CanonAeadKeyRef::new(&custom_ipk)); @@ -536,7 +543,7 @@ mod tests { fn test_root_cert_available() { let crypto = test_only_crypto(); let fabric_id = 0x1u64; - let creds = unwrap!(FabricCredentials::new(&crypto, fabric_id)); + let creds = unwrap!(FabricCredentials::new(&crypto, fabric_id, VALID_FOREVER)); let root_cert = creds.root_cert(); assert!(!root_cert.is_empty()); @@ -547,7 +554,7 @@ mod tests { fn test_root_cert_consistent() { let crypto = test_only_crypto(); let fabric_id = 0x1u64; - let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id)); + let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id, VALID_FOREVER)); let csr = generate_test_csr(); @@ -568,7 +575,7 @@ mod tests { fn test_verify_noc_and_rcac_parse() { let crypto = test_only_crypto(); let fabric_id = 0x1u64; - let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id)); + let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id, VALID_FOREVER)); let csr = generate_test_csr(); @@ -587,7 +594,7 @@ mod tests { fn test_generated_noc_contains_correct_node_id() { let crypto = test_only_crypto(); let fabric_id = 0x1u64; - let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id)); + let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id, VALID_FOREVER)); let csr = generate_test_csr(); @@ -605,7 +612,7 @@ mod tests { fn test_generated_noc_contains_correct_fabric_id() { let crypto = test_only_crypto(); let fabric_id = 0xABCDEF123456u64; - let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id)); + let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id, VALID_FOREVER)); let csr = generate_test_csr(); @@ -622,7 +629,7 @@ mod tests { fn test_cat_ids_present_in_noc_when_specified() { let crypto = test_only_crypto(); let fabric_id = 0x1u64; - let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id)); + let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id, VALID_FOREVER)); let csr = generate_test_csr(); let cat_ids = &[0x00011111u32, 0x00022222u32, 0x00033333u32]; @@ -642,7 +649,7 @@ mod tests { fn test_invalid_csr_fails() { let crypto = test_only_crypto(); let fabric_id = 0x1u64; - let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id)); + let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id, VALID_FOREVER)); let invalid_csr = &[0x01, 0x02, 0x03, 0x04]; @@ -655,7 +662,7 @@ mod tests { fn test_four_cat_ids_fails() { let crypto = test_only_crypto(); let fabric_id = 0x1u64; - let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id)); + let mut creds = unwrap!(FabricCredentials::new(&crypto, fabric_id, VALID_FOREVER)); let csr = generate_test_csr(); let too_many_cat_ids = &[0x00011111u32, 0x00022222u32, 0x00033333u32, 0x00044444u32]; diff --git a/rs-matter/src/commissioner/noc_generator.rs b/rs-matter/src/commissioner/noc_generator.rs index 2563a860..b0c80abc 100644 --- a/rs-matter/src/commissioner/noc_generator.rs +++ b/rs-matter/src/commissioner/noc_generator.rs @@ -23,7 +23,7 @@ //! - Optional Intermediate CA Certificate (ICAC) //! - Node Operational Certificate (NOC) -use crate::cert::builder::{IcacBuilder, IssuerDN, NocBuilder, RcacBuilder}; +use crate::cert::builder::{IcacBuilder, IssuerDN, NocBuilder, RcacBuilder, Validity}; use crate::cert::x509::csr::CsrRef; use crate::cert::{MAX_CERT_TLV_AND_ASN1_LEN, MAX_CERT_TLV_LEN}; use crate::crypto::{ @@ -77,6 +77,8 @@ pub struct NocGenerator { icac_id: Option, /// Next serial number for certificates next_serial: u64, + /// Validity period for certificates + validity: Validity, } impl NocGenerator { @@ -88,10 +90,11 @@ impl NocGenerator { /// # Arguments /// * `crypto` - Cryptographic backend /// * `fabric_id` - The fabric identifier for this CA + /// * `validity` - Validity period for generated certificates /// /// # Returns /// A new `NocGenerator` ready to issue NOCs. - pub fn new(crypto: &C, fabric_id: u64) -> Result { + pub fn new(crypto: &C, fabric_id: u64, validity: Validity) -> Result { // Generate a random RCAC ID let mut rcac_id_bytes = [0u8; 8]; crypto.rand()?.fill_bytes(&mut rcac_id_bytes); @@ -123,11 +126,6 @@ impl NocGenerator { ca_id: Some(rcac_id), }; - let validity = crate::cert::builder::Validity { - not_before: 0, // epoch start - not_after: 0, // no expiry - }; - let cert_len = RcacBuilder::new(&mut cert_buf).build( crypto, subject, @@ -153,6 +151,7 @@ impl NocGenerator { rcac_id, icac_id: None, next_serial: 1, + validity, }) } @@ -164,12 +163,14 @@ impl NocGenerator { /// * `root_cert` - The Root CA certificate (TLV encoded) /// * `fabric_id` - The fabric identifier /// * `rcac_id` - The RCAC identifier + /// * `validity` - Validity period for generated certificates pub fn from_root_ca( crypto: &C, root_privkey: CanonPkcSecretKey, root_cert: &[u8], fabric_id: u64, rcac_id: u64, + validity: Validity, ) -> Result { // Derive public key from private key let root_key = crypto.secret_key(root_privkey.reference())?; @@ -192,6 +193,7 @@ impl NocGenerator { rcac_id, icac_id: None, next_serial: 1, + validity, }) } @@ -234,11 +236,6 @@ impl NocGenerator { ca_id: Some(icac_id), }; - let validity = crate::cert::builder::Validity { - not_before: 0, // epoch start - not_after: 0, // no expiry - }; - let issuer = crate::cert::builder::IssuerDN { ca_id: Some(self.rcac_id), fabric_id: Some(self.fabric_id), @@ -248,7 +245,7 @@ impl NocGenerator { let cert_len = IcacBuilder::new(&mut cert_buf).build( crypto, subject, - validity, + self.validity, &icac_key.pub_key()?, &root_signing_key.pub_key()?, &root_signing_key, @@ -330,15 +327,10 @@ impl NocGenerator { ca_id: None, }; - let validity = crate::cert::builder::Validity { - not_before: 0, // epoch start - not_after: 0, // no expiry - }; - let cert_len = NocBuilder::new(&mut cert_buf).build( crypto, subject, - validity, + self.validity, &crypto.pub_key(CanonPkcPublicKeyRef::try_new(&device_pubkey)?)?, &crypto.pub_key(issuer_pubkey.reference())?, &signing_key, @@ -418,11 +410,13 @@ impl NocGenerator { #[cfg(test)] mod tests { - use super::*; + use crate::cert::builder::VALID_FOREVER; use crate::cert::CertRef; use crate::crypto::test_only_crypto; use crate::tlv::TLVElement; + use super::*; + /// Known valid CSR from C++ test vectors (TestChipCryptoPAL.cpp) /// This CSR has a valid signature and can be verified. const GOOD_CSR: &[u8] = &[ @@ -466,7 +460,7 @@ mod tests { let crypto = test_only_crypto(); let fabric_id = 0x1234_5678_9ABC_DEF0; - let generator = unwrap!(NocGenerator::new(&crypto, fabric_id)); + let generator = unwrap!(NocGenerator::new(&crypto, fabric_id, VALID_FOREVER)); // Verify fabric_id is stored assert_eq!(generator.fabric_id(), fabric_id); @@ -490,7 +484,7 @@ mod tests { let crypto = test_only_crypto(); let fabric_id = 0xABCD; - let gen1 = unwrap!(NocGenerator::new(&crypto, fabric_id)); + let gen1 = unwrap!(NocGenerator::new(&crypto, fabric_id, VALID_FOREVER)); let root_cert = gen1.root_cert(); let rcac_id = gen1.rcac_id(); @@ -504,7 +498,8 @@ mod tests { root_privkey, &root_cert_copy, fabric_id, - rcac_id + rcac_id, + VALID_FOREVER, )); // Verify credentials match @@ -517,7 +512,7 @@ mod tests { fn test_generate_icac_creates_certificate() { let crypto = test_only_crypto(); let fabric_id = 0x1; - let mut generator = unwrap!(NocGenerator::new(&crypto, fabric_id)); + let mut generator = unwrap!(NocGenerator::new(&crypto, fabric_id, VALID_FOREVER)); let icac = unwrap!(generator.generate_icac(&crypto)); @@ -532,7 +527,7 @@ mod tests { fn test_icac_cert_available_after_generation() { let crypto = test_only_crypto(); let fabric_id = 0x1; - let mut generator = unwrap!(NocGenerator::new(&crypto, fabric_id)); + let mut generator = unwrap!(NocGenerator::new(&crypto, fabric_id, VALID_FOREVER)); // Before generation, icac_cert() should return None assert!(generator.icac_cert().is_none()); @@ -555,7 +550,7 @@ mod tests { fn test_multiple_icac_calls_replace_previous() { let crypto = test_only_crypto(); let fabric_id = 0x1; - let mut generator = unwrap!(NocGenerator::new(&crypto, fabric_id)); + let mut generator = unwrap!(NocGenerator::new(&crypto, fabric_id, VALID_FOREVER)); // Generate first ICAC unwrap!(generator.generate_icac(&crypto)); @@ -581,7 +576,7 @@ mod tests { fn test_generate_noc_basic() { let crypto = test_only_crypto(); let fabric_id = 0x1; - let mut generator = unwrap!(NocGenerator::new(&crypto, fabric_id)); + let mut generator = unwrap!(NocGenerator::new(&crypto, fabric_id, VALID_FOREVER)); let node_id = 0x1234; let creds = unwrap!(generator.generate_noc(&crypto, GOOD_CSR, node_id, &[])); @@ -600,7 +595,7 @@ mod tests { fn test_generate_noc_with_icac() { let crypto = test_only_crypto(); let fabric_id = 0x1; - let mut generator = unwrap!(NocGenerator::new(&crypto, fabric_id)); + let mut generator = unwrap!(NocGenerator::new(&crypto, fabric_id, VALID_FOREVER)); // Generate ICAC first unwrap!(generator.generate_icac(&crypto)); @@ -620,7 +615,7 @@ mod tests { fn test_generate_noc_with_cat_ids() { let crypto = test_only_crypto(); let fabric_id = 0x1; - let mut generator = unwrap!(NocGenerator::new(&crypto, fabric_id)); + let mut generator = unwrap!(NocGenerator::new(&crypto, fabric_id, VALID_FOREVER)); let node_id = 0xABCD; let cat_ids = [0x0001_0001, 0x0001_0002, 0x0001_0003]; @@ -642,7 +637,7 @@ mod tests { fn test_generate_noc_increments_serial() { let crypto = test_only_crypto(); let fabric_id = 0x1; - let mut generator = unwrap!(NocGenerator::new(&crypto, fabric_id)); + let mut generator = unwrap!(NocGenerator::new(&crypto, fabric_id, VALID_FOREVER)); // Initial serial should be 1 assert_eq!(generator.next_serial, 1); @@ -664,7 +659,7 @@ mod tests { fn test_noc_contains_correct_node_id() { let crypto = test_only_crypto(); let fabric_id = 0x9999; - let mut generator = unwrap!(NocGenerator::new(&crypto, fabric_id)); + let mut generator = unwrap!(NocGenerator::new(&crypto, fabric_id, VALID_FOREVER)); let node_id = 0xDEAD_BEEF_CAFE_BABE; let creds = unwrap!(generator.generate_noc(&crypto, GOOD_CSR, node_id, &[])); @@ -680,7 +675,7 @@ mod tests { fn test_noc_contains_device_pubkey_from_csr() { let crypto = test_only_crypto(); let fabric_id = 0x1; - let mut generator = unwrap!(NocGenerator::new(&crypto, fabric_id)); + let mut generator = unwrap!(NocGenerator::new(&crypto, fabric_id, VALID_FOREVER)); let creds = unwrap!(generator.generate_noc(&crypto, GOOD_CSR, 1, &[])); @@ -742,7 +737,7 @@ mod tests { fn test_generate_noc_bad_signature_fails() { let crypto = test_only_crypto(); let fabric_id = 0x1; - let mut generator = unwrap!(NocGenerator::new(&crypto, fabric_id)); + let mut generator = unwrap!(NocGenerator::new(&crypto, fabric_id, VALID_FOREVER)); // CSR with bad signature should fail verification let result = generator.generate_noc(&crypto, BAD_SIGNATURE_CSR, 1, &[]); @@ -753,7 +748,7 @@ mod tests { fn test_generate_noc_too_many_cat_ids_fails() { let crypto = test_only_crypto(); let fabric_id = 0x1; - let mut generator = unwrap!(NocGenerator::new(&crypto, fabric_id)); + let mut generator = unwrap!(NocGenerator::new(&crypto, fabric_id, VALID_FOREVER)); // More than 3 CAT IDs should fail let too_many_cat_ids = [0x0001_0001, 0x0001_0002, 0x0001_0003, 0x0001_0004]; @@ -766,7 +761,7 @@ mod tests { fn test_generated_rcac_can_be_parsed() { let crypto = test_only_crypto(); let fabric_id = 0x1234; - let generator = unwrap!(NocGenerator::new(&crypto, fabric_id)); + let generator = unwrap!(NocGenerator::new(&crypto, fabric_id, VALID_FOREVER)); let rcac = generator.root_cert(); @@ -782,7 +777,7 @@ mod tests { fn test_generated_icac_can_be_parsed() { let crypto = test_only_crypto(); let fabric_id = 0x5678; - let mut generator = unwrap!(NocGenerator::new(&crypto, fabric_id)); + let mut generator = unwrap!(NocGenerator::new(&crypto, fabric_id, VALID_FOREVER)); let icac = unwrap!(generator.generate_icac(&crypto)); @@ -798,7 +793,7 @@ mod tests { fn test_generated_noc_can_be_parsed() { let crypto = test_only_crypto(); let fabric_id = 0xABCD; - let mut generator = unwrap!(NocGenerator::new(&crypto, fabric_id)); + let mut generator = unwrap!(NocGenerator::new(&crypto, fabric_id, VALID_FOREVER)); let node_id = 0x9999; let creds = unwrap!(generator.generate_noc(&crypto, GOOD_CSR, node_id, &[])); diff --git a/rs-matter/tests/case.rs b/rs-matter/tests/case.rs index fa8cb5e6..e48d7f02 100644 --- a/rs-matter/tests/case.rs +++ b/rs-matter/tests/case.rs @@ -17,15 +17,14 @@ #![cfg(all(feature = "std", feature = "async-io"))] -#[allow(dead_code)] -mod common; - use core::pin::pin; use embassy_futures::select::{select, Either}; use embassy_time::{Duration, Timer}; + use log::info; +use rs_matter::cert::builder::VALID_FOREVER; use rs_matter::commissioner::fabric_credentials::FabricCredentials; use rs_matter::crypto::{test_only_crypto, CanonPkcSecretKey, Crypto, SecretKey, SigningSecretKey}; use rs_matter::dm::devices::test::{TEST_DEV_ATT, TEST_DEV_COMM, TEST_DEV_DET}; @@ -41,6 +40,9 @@ use rs_matter::Matter; use crate::common::{create_localhost_socket_pair, init_env_logger, run_device_controller}; +#[allow(dead_code)] +mod common; + const TEST_FABRIC_ID: u64 = 1; const CONTROLLER_NODE_ID: u64 = 100; const DEVICE_NODE_ID: u64 = 200; @@ -62,7 +64,8 @@ fn test_case_handshake() { // ---- 1. Generate credentials using FabricCredentials ---- - let mut fabric_creds = FabricCredentials::new(&crypto, TEST_FABRIC_ID).unwrap(); + let mut fabric_creds = + FabricCredentials::new(&crypto, TEST_FABRIC_ID, VALID_FOREVER).unwrap(); // Generate controller credentials (keypair + CSR + NOC) let controller_secret_key = crypto.generate_secret_key().unwrap();