Session: Include NoC CAT fields, and populate them from the CASE exchange

This commit is contained in:
Kedar Sovani 2023-02-09 15:45:25 +05:30
parent 315b7edbc8
commit 725d19187e
7 changed files with 68 additions and 15 deletions

View file

@ -318,6 +318,18 @@ impl DistNames {
}
})
}
fn u64_arr(&self, match_id: DnTags, output: &mut [u64]) {
let mut out_index = 0;
for (_, val) in self.dn.iter().filter(|(id, _)| *id == match_id as u8) {
if let DistNameValue::Uint(a) = val {
if out_index < output.len() {
output[out_index] = *a;
out_index += 1;
}
}
}
}
}
const PRINTABLE_STR_THRESHOLD: u8 = 0x80;
@ -543,6 +555,10 @@ impl Cert {
self.subject.u64(DnTags::NodeId).ok_or(Error::NoNodeId)
}
pub fn get_cat_ids(&self, output: &mut [u64]) {
self.subject.u64_arr(DnTags::NocCat, output)
}
pub fn get_fabric_id(&self) -> Result<u64, Error> {
self.subject.u64(DnTags::FabricId).ok_or(Error::NoFabricId)
}

View file

@ -221,7 +221,7 @@ impl DataModel {
match sess.get_session_mode() {
SessionMode::Case(c) => {
let subject = AccessorSubjects::new(sess.get_peer_node_id().unwrap_or_default());
Accessor::new(c, subject, AuthMode::Case, self.acl_mgr.clone())
Accessor::new(c.fab_idx, subject, AuthMode::Case, self.acl_mgr.clone())
}
SessionMode::Pase => Accessor::new(
0,

View file

@ -89,12 +89,17 @@ impl FailSafe {
match c.noc_state {
NocState::NocNotRecvd => return Err(Error::Invalid),
NocState::AddNocRecvd(idx) | NocState::UpdateNocRecvd(idx) => {
if SessionMode::Case(idx) != session_mode {
if let SessionMode::Case(c) = session_mode {
if c.fab_idx != idx {
error!(
"Received disarm in separate session from previous Add/Update NOC"
);
return Err(Error::Invalid);
}
} else {
error!("Received disarm in a non-CASE session");
return Err(Error::Invalid);
}
}
}
inner.state = State::Idle;

View file

@ -248,11 +248,11 @@ impl NocCluster {
.map_err(|_| IMStatusCode::InvalidDataType)?;
let (result, fab_idx) =
if let SessionMode::Case(fab_idx) = cmd_req.trans.session.get_session_mode() {
if self.fabric_mgr.set_label(fab_idx, label).is_err() {
(NocStatus::LabelConflict, fab_idx)
if let SessionMode::Case(c) = cmd_req.trans.session.get_session_mode() {
if self.fabric_mgr.set_label(c.fab_idx, label).is_err() {
(NocStatus::LabelConflict, c.fab_idx)
} else {
(NocStatus::Ok, fab_idx)
(NocStatus::Ok, c.fab_idx)
}
} else {
// Update Fabric Label not allowed

View file

@ -33,7 +33,7 @@ use crate::{
network::Address,
proto_demux::{ProtoCtx, ResponseRequired},
queue::{Msg, WorkQ},
session::{CloneData, SessionMode},
session::{CaseDetails, CloneData, NocCatIds, SessionMode},
},
utils::writebuf::WriteBuf,
};
@ -155,6 +155,8 @@ impl Case {
}
// Only now do we add this message to the TT Hash
let mut peer_catids: NocCatIds = Default::default();
initiator_noc.get_cat_ids(&mut peer_catids);
case_session.tt_hash.update(ctx.rx.as_borrow_slice())?;
let clone_data = Case::get_session_clone_data(
fabric.ipk.op_key(),
@ -162,6 +164,7 @@ impl Case {
initiator_noc.get_node_id()?,
ctx.exch_ctx.sess.get_peer_addr(),
&case_session,
&peer_catids,
)?;
// Queue a transport mgr request to add a new session
WorkQ::get()?.sync_send(Msg::NewSession(clone_data))?;
@ -281,6 +284,7 @@ impl Case {
peer_nodeid: u64,
peer_addr: Address,
case_session: &CaseSession,
peer_catids: &NocCatIds,
) -> Result<CloneData, Error> {
let mut session_keys = [0_u8; 3 * crypto::SYMM_KEY_LEN_BYTES];
Case::get_session_keys(
@ -296,7 +300,10 @@ impl Case {
case_session.peer_sessid,
case_session.local_sessid,
peer_addr,
SessionMode::Case(case_session.local_fabric_idx as u8),
SessionMode::Case(CaseDetails::new(
case_session.local_fabric_idx as u8,
peer_catids,
)),
);
clone_data.dec_key.copy_from_slice(&session_keys[0..16]);

View file

@ -37,12 +37,28 @@ use super::{
packet::{Packet, PacketPool},
};
pub const MAX_CAT_IDS_PER_NOC: usize = 3;
const MATTER_AES128_KEY_SIZE: usize = 16;
#[derive(Debug, Default, Copy, Clone, PartialEq)]
pub struct CaseDetails {
pub fab_idx: u8,
pub cat_ids: [u64; MAX_CAT_IDS_PER_NOC],
}
impl CaseDetails {
pub fn new(fab_idx: u8, cat_ids: &[u64; MAX_CAT_IDS_PER_NOC]) -> Self {
Self {
fab_idx,
cat_ids: *cat_ids,
}
}
}
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum SessionMode {
// The Case session will capture the local fabric index
Case(u8),
Case(CaseDetails),
Pase,
PlainText,
}
@ -53,6 +69,8 @@ impl Default for SessionMode {
}
}
pub type NocCatIds = [u64; MAX_CAT_IDS_PER_NOC];
#[derive(Debug)]
pub struct Session {
peer_addr: Address,
@ -188,9 +206,16 @@ impl Session {
self.peer_nodeid
}
pub fn get_peer_cat_ids(&self) -> Option<&NocCatIds> {
match &self.mode {
SessionMode::Case(a) => Some(&a.cat_ids),
_ => None,
}
}
pub fn get_local_fabric_idx(&self) -> Option<u8> {
match self.mode {
SessionMode::Case(a) => Some(a),
SessionMode::Case(a) => Some(a.fab_idx),
_ => None,
}
}

View file

@ -32,7 +32,6 @@ use matter::{
secure_channel::pake::PaseMgr,
tlv::{TLVWriter, TagType, ToTLV},
transport::packet::Packet,
transport::proto_demux::HandleProto,
transport::{
exchange::{self, Exchange, ExchangeCtx},
network::Address,
@ -40,6 +39,7 @@ use matter::{
proto_demux::ProtoCtx,
session::{CloneData, SessionMgr, SessionMode},
},
transport::{proto_demux::HandleProto, session::CaseDetails},
utils::writebuf::WriteBuf,
};
use std::{
@ -146,7 +146,7 @@ impl ImEngine {
std::net::IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
5542,
)),
SessionMode::Case(1),
SessionMode::Case(CaseDetails::new(1, &Default::default())),
);
let sess_idx = sess_mgr.clone_session(&clone_data).unwrap();
let sess = sess_mgr.get_session_handle(sess_idx);