diff --git a/matter/src/cert/mod.rs b/matter/src/cert/mod.rs index cc6bd31..360ce31 100644 --- a/matter/src/cert/mod.rs +++ b/matter/src/cert/mod.rs @@ -26,7 +26,8 @@ use crate::{ use log::error; use num_derive::FromPrimitive; -use self::{asn1_writer::ASN1Writer, printer::CertPrinter}; +pub use self::asn1_writer::ASN1Writer; +use self::printer::CertPrinter; // As per https://datatracker.ietf.org/doc/html/rfc5280 diff --git a/matter/src/crypto/crypto_mbedtls.rs b/matter/src/crypto/crypto_mbedtls.rs index bf9cb88..e818583 100644 --- a/matter/src/crypto/crypto_mbedtls.rs +++ b/matter/src/crypto/crypto_mbedtls.rs @@ -29,7 +29,12 @@ use mbedtls::{ }; use super::CryptoKeyPair; -use crate::error::Error; +use crate::{ + // TODO: We should move ASN1Writer out of Cert, + // so Crypto doesn't have to depend on Cert + cert::{ASN1Writer, CertConsumer}, + error::Error, +}; pub struct HmacSha256 { inner: Hmac, @@ -183,7 +188,7 @@ impl CryptoKeyPair for KeyPair { // current rust-mbedTLS APIs the signature to be in DER format let mut mbedtls_sign = [0u8; super::EC_SIGNATURE_LEN_BYTES * 3]; - let len = convert_r_s_to_asn1_sign(signature, &mut mbedtls_sign); + let len = convert_r_s_to_asn1_sign(signature, &mut mbedtls_sign)?; let mbedtls_sign = &mbedtls_sign[..len]; if let Err(e) = tmp_key.verify(hash::Type::Sha256, &msg_hash, mbedtls_sign) { @@ -195,51 +200,16 @@ impl CryptoKeyPair for KeyPair { } } -fn convert_r_s_to_asn1_sign(signature: &[u8], mbedtls_sign: &mut [u8]) -> usize { - let mut offset = 0; - mbedtls_sign[offset] = 0x30; - offset += 1; - let mut len = 68; - if (signature[0] & 0x80) == 0x80 { - len += 1; - } - if (signature[32] & 0x80) == 0x80 { - len += 1; - } - mbedtls_sign[offset] = len; - offset += 1; - mbedtls_sign[offset] = 0x02; - offset += 1; - if (signature[0] & 0x80) == 0x80 { - // It seems if topmost bit is 1, there is an extra 0 - mbedtls_sign[offset] = 33; - offset += 1; - mbedtls_sign[offset] = 0; - offset += 1; - } else { - mbedtls_sign[offset] = 32; - offset += 1; - } - mbedtls_sign[offset..(offset + 32)].copy_from_slice(&signature[..32]); - offset += 32; +fn convert_r_s_to_asn1_sign(signature: &[u8], mbedtls_sign: &mut [u8]) -> Result { + let r = &signature[0..32]; + let s = &signature[32..64]; - mbedtls_sign[offset] = 0x02; - offset += 1; - if (signature[32] & 0x80) == 0x80 { - // It seems if topmost bit is 1, there is an extra 0 - mbedtls_sign[offset] = 33; - offset += 1; - mbedtls_sign[offset] = 0; - offset += 1; - } else { - mbedtls_sign[offset] = 32; - offset += 1; - } - - mbedtls_sign[offset..(offset + 32)].copy_from_slice(&signature[32..64]); - offset += 32; - - offset + let mut wr = ASN1Writer::new(mbedtls_sign); + wr.start_seq("")?; + wr.integer("r", r)?; + wr.integer("s", s)?; + wr.end_seq()?; + Ok(wr.as_slice().len()) } // mbedTLS sign() function directly encodes the signature in ASN1. The lower level function diff --git a/matter/src/data_model/sdm/general_commissioning.rs b/matter/src/data_model/sdm/general_commissioning.rs index 220217b..d652bc2 100644 --- a/matter/src/data_model/sdm/general_commissioning.rs +++ b/matter/src/data_model/sdm/general_commissioning.rs @@ -33,6 +33,7 @@ enum CommissioningError { ErrValueOutsideRange = 1, ErrInvalidAuth = 2, ErrNotCommissioning = 3, + ErrBusyWithOtherAdmin = 4, } pub const ID: u32 = 0x0030; @@ -180,17 +181,18 @@ impl GenCommCluster { cmd_enter!("ARM Fail Safe"); let p = FailSafeParams::from_tlv(&cmd_req.data)?; + let mut status = CommissioningError::Ok as u8; if self .failsafe .arm(p.expiry_len, cmd_req.trans.session.get_session_mode()) .is_err() { - return Err(IMStatusCode::Busy); + status = CommissioningError::ErrBusyWithOtherAdmin as u8; } let cmd_data = CommonResponse { - error_code: CommissioningError::Ok as u8, + error_code: status, debug_txt: "".to_owned(), }; let resp = ib::InvResp::cmd_new( diff --git a/matter/src/data_model/system_model/descriptor.rs b/matter/src/data_model/system_model/descriptor.rs index 377b950..ac778bb 100644 --- a/matter/src/data_model/system_model/descriptor.rs +++ b/matter/src/data_model/system_model/descriptor.rs @@ -67,6 +67,12 @@ impl DescriptorCluster { Access::RV, Quality::NONE, )?, + Attribute::new( + Attributes::ClientList as u16, + AttrValue::Custom, + Access::RV, + Quality::NONE, + )?, ]; c.base.add_attributes(&attrs[..])?; Ok(c) @@ -124,6 +130,12 @@ impl DescriptorCluster { } let _ = tw.end_container(); } + + fn encode_client_list(&self, tag: TagType, tw: &mut TLVWriter) { + // No Clients supported + let _ = tw.start_array(tag); + let _ = tw.end_container(); + } } impl ClusterType for DescriptorCluster { @@ -145,6 +157,9 @@ impl ClusterType for DescriptorCluster { Some(Attributes::PartsList) => encoder.encode(EncodeValue::Closure(&|tag, tw| { self.encode_parts_list(tag, tw) })), + Some(Attributes::ClientList) => encoder.encode(EncodeValue::Closure(&|tag, tw| { + self.encode_client_list(tag, tw) + })), _ => { error!("Attribute not supported: this shouldn't happen"); }