Skip to content

Commit 50f18db

Browse files
authored
Merge pull request #82 from ivmarkov/main
Do not hold on to RefCell borrows across await points
2 parents ede024c + f53f3b7 commit 50f18db

File tree

6 files changed

+217
-234
lines changed

6 files changed

+217
-234
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ on:
1010
workflow_dispatch:
1111

1212
env:
13-
RUST_TOOLCHAIN: nightly-2023-07-01
13+
RUST_TOOLCHAIN: nightly
1414
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
1515
CARGO_TERM_COLOR: always
1616

rs-matter/src/mdns/builtin.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,6 @@ impl<'a> MdnsService<'a> {
208208
select(&mut broadcast, &mut respond).await.unwrap()
209209
}
210210

211-
#[allow(clippy::await_holding_refcell_ref)]
212211
async fn broadcast(&self, tx_pipe: &Pipe<'_>) -> Result<(), Error> {
213212
loop {
214213
select(
@@ -258,7 +257,6 @@ impl<'a> MdnsService<'a> {
258257
}
259258
}
260259

261-
#[allow(clippy::await_holding_refcell_ref)]
262260
async fn respond(&self, rx_pipe: &Pipe<'_>, tx_pipe: &Pipe<'_>) -> Result<(), Error> {
263261
loop {
264262
{

rs-matter/src/secure_channel/case.rs

Lines changed: 132 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ impl<'a> Case<'a> {
8787
self.handle_casesigma3(exchange, rx, tx, &mut session).await
8888
}
8989

90-
#[allow(clippy::await_holding_refcell_ref)]
9190
async fn handle_casesigma3(
9291
&mut self,
9392
exchange: &mut Exchange<'_>,
@@ -97,100 +96,81 @@ impl<'a> Case<'a> {
9796
) -> Result<(), Error> {
9897
rx.check_proto_opcode(OpCode::CASESigma3 as _)?;
9998

100-
let fabric_mgr = self.fabric_mgr.borrow();
101-
102-
let fabric = fabric_mgr.get_fabric(case_session.local_fabric_idx)?;
103-
if fabric.is_none() {
104-
drop(fabric_mgr);
105-
complete_with_status(
106-
exchange,
107-
tx,
108-
common::SCStatusCodes::NoSharedTrustRoots,
109-
None,
110-
)
111-
.await?;
112-
return Ok(());
113-
}
114-
// Safe to unwrap here
115-
let fabric = fabric.unwrap();
116-
117-
let root = get_root_node_struct(rx.as_slice())?;
118-
let encrypted = root.find_tag(1)?.slice()?;
119-
120-
let mut decrypted = alloc!([0; 800]);
121-
if encrypted.len() > decrypted.len() {
122-
error!("Data too large");
123-
Err(ErrorCode::NoSpace)?;
124-
}
125-
let decrypted = &mut decrypted[..encrypted.len()];
126-
decrypted.copy_from_slice(encrypted);
127-
128-
let len = Case::get_sigma3_decryption(fabric.ipk.op_key(), case_session, decrypted)?;
129-
let decrypted = &decrypted[..len];
130-
131-
let root = get_root_node_struct(decrypted)?;
132-
let d = Sigma3Decrypt::from_tlv(&root)?;
133-
134-
let initiator_noc = alloc!(Cert::new(d.initiator_noc.0)?);
135-
let mut initiator_icac = None;
136-
if let Some(icac) = d.initiator_icac {
137-
initiator_icac = Some(alloc!(Cert::new(icac.0)?));
138-
}
139-
140-
#[cfg(feature = "alloc")]
141-
let initiator_icac_mut = initiator_icac.as_deref();
99+
let status = {
100+
let fabric_mgr = self.fabric_mgr.borrow();
142101

143-
#[cfg(not(feature = "alloc"))]
144-
let initiator_icac_mut = initiator_icac.as_ref();
102+
let fabric = fabric_mgr.get_fabric(case_session.local_fabric_idx)?;
103+
if let Some(fabric) = fabric {
104+
let root = get_root_node_struct(rx.as_slice())?;
105+
let encrypted = root.find_tag(1)?.slice()?;
106+
107+
let mut decrypted = alloc!([0; 800]);
108+
if encrypted.len() > decrypted.len() {
109+
error!("Data too large");
110+
Err(ErrorCode::NoSpace)?;
111+
}
112+
let decrypted = &mut decrypted[..encrypted.len()];
113+
decrypted.copy_from_slice(encrypted);
145114

146-
if let Err(e) = Case::validate_certs(fabric, &initiator_noc, initiator_icac_mut) {
147-
error!("Certificate Chain doesn't match: {}", e);
148-
complete_with_status(exchange, tx, common::SCStatusCodes::InvalidParameter, None)
149-
.await?;
150-
return Ok(());
151-
}
115+
let len =
116+
Case::get_sigma3_decryption(fabric.ipk.op_key(), case_session, decrypted)?;
117+
let decrypted = &decrypted[..len];
152118

153-
if Case::validate_sigma3_sign(
154-
d.initiator_noc.0,
155-
d.initiator_icac.map(|a| a.0),
156-
&initiator_noc,
157-
d.signature.0,
158-
case_session,
159-
)
160-
.is_err()
161-
{
162-
error!("Sigma3 Signature doesn't match");
163-
complete_with_status(exchange, tx, common::SCStatusCodes::InvalidParameter, None)
164-
.await?;
165-
return Ok(());
166-
}
119+
let root = get_root_node_struct(decrypted)?;
120+
let d = Sigma3Decrypt::from_tlv(&root)?;
167121

168-
// Only now do we add this message to the TT Hash
169-
let mut peer_catids: NocCatIds = Default::default();
170-
initiator_noc.get_cat_ids(&mut peer_catids);
171-
case_session.tt_hash.update(rx.as_slice())?;
172-
let clone_data = Case::get_session_clone_data(
173-
fabric.ipk.op_key(),
174-
fabric.get_node_id(),
175-
initiator_noc.get_node_id()?,
176-
exchange.with_session(|sess| Ok(sess.get_peer_addr()))?,
177-
case_session,
178-
&peer_catids,
179-
)?;
122+
let initiator_noc = alloc!(Cert::new(d.initiator_noc.0)?);
123+
let mut initiator_icac = None;
124+
if let Some(icac) = d.initiator_icac {
125+
initiator_icac = Some(alloc!(Cert::new(icac.0)?));
126+
}
180127

181-
// TODO: Handle NoSpace
182-
exchange.with_session_mgr_mut(|sess_mgr| sess_mgr.clone_session(&clone_data))?;
128+
#[cfg(feature = "alloc")]
129+
let initiator_icac_mut = initiator_icac.as_deref();
130+
131+
#[cfg(not(feature = "alloc"))]
132+
let initiator_icac_mut = initiator_icac.as_ref();
133+
134+
if let Err(e) = Case::validate_certs(fabric, &initiator_noc, initiator_icac_mut) {
135+
error!("Certificate Chain doesn't match: {}", e);
136+
SCStatusCodes::InvalidParameter
137+
} else if let Err(e) = Case::validate_sigma3_sign(
138+
d.initiator_noc.0,
139+
d.initiator_icac.map(|a| a.0),
140+
&initiator_noc,
141+
d.signature.0,
142+
case_session,
143+
) {
144+
error!("Sigma3 Signature doesn't match: {}", e);
145+
SCStatusCodes::InvalidParameter
146+
} else {
147+
// Only now do we add this message to the TT Hash
148+
let mut peer_catids: NocCatIds = Default::default();
149+
initiator_noc.get_cat_ids(&mut peer_catids);
150+
case_session.tt_hash.update(rx.as_slice())?;
151+
let clone_data = Case::get_session_clone_data(
152+
fabric.ipk.op_key(),
153+
fabric.get_node_id(),
154+
initiator_noc.get_node_id()?,
155+
exchange.with_session(|sess| Ok(sess.get_peer_addr()))?,
156+
case_session,
157+
&peer_catids,
158+
)?;
159+
160+
// TODO: Handle NoSpace
161+
exchange
162+
.with_session_mgr_mut(|sess_mgr| sess_mgr.clone_session(&clone_data))?;
163+
164+
SCStatusCodes::SessionEstablishmentSuccess
165+
}
166+
} else {
167+
SCStatusCodes::NoSharedTrustRoots
168+
}
169+
};
183170

184-
complete_with_status(
185-
exchange,
186-
tx,
187-
SCStatusCodes::SessionEstablishmentSuccess,
188-
None,
189-
)
190-
.await
171+
complete_with_status(exchange, tx, status, None).await
191172
}
192173

193-
#[allow(clippy::await_holding_refcell_ref)]
194174
async fn handle_casesigma1(
195175
&mut self,
196176
exchange: &mut Exchange<'_>,
@@ -255,70 +235,76 @@ impl<'a> Case<'a> {
255235
const MAX_ENCRYPTED_SIZE: usize = 800;
256236

257237
let mut encrypted = alloc!([0; MAX_ENCRYPTED_SIZE]);
258-
let encrypted_len = {
259-
let mut signature = alloc!([0u8; crypto::EC_SIGNATURE_LEN_BYTES]);
238+
let mut signature = alloc!([0u8; crypto::EC_SIGNATURE_LEN_BYTES]);
239+
240+
let fabric_found = {
260241
let fabric_mgr = self.fabric_mgr.borrow();
261242

262243
let fabric = fabric_mgr.get_fabric(case_session.local_fabric_idx)?;
263-
if fabric.is_none() {
264-
drop(fabric_mgr);
265-
complete_with_status(
266-
exchange,
267-
tx,
268-
common::SCStatusCodes::NoSharedTrustRoots,
269-
None,
270-
)
271-
.await?;
272-
return Ok(());
244+
if let Some(fabric) = fabric {
245+
#[cfg(feature = "alloc")]
246+
let signature_mut = &mut *signature;
247+
248+
#[cfg(not(feature = "alloc"))]
249+
let signature_mut = &mut signature;
250+
251+
let sign_len = Case::get_sigma2_sign(
252+
fabric,
253+
&case_session.our_pub_key,
254+
&case_session.peer_pub_key,
255+
signature_mut,
256+
)?;
257+
let signature = &signature[..sign_len];
258+
259+
#[cfg(feature = "alloc")]
260+
let encrypted_mut = &mut *encrypted;
261+
262+
#[cfg(not(feature = "alloc"))]
263+
let encrypted_mut = &mut encrypted;
264+
265+
let encrypted_len = Case::get_sigma2_encryption(
266+
fabric,
267+
self.rand,
268+
&our_random,
269+
case_session,
270+
signature,
271+
encrypted_mut,
272+
)?;
273+
274+
let encrypted = &encrypted[0..encrypted_len];
275+
276+
// Generate our Response Body
277+
tx.reset();
278+
tx.set_proto_id(PROTO_ID_SECURE_CHANNEL);
279+
tx.set_proto_opcode(OpCode::CASESigma2 as u8);
280+
281+
let mut tw = TLVWriter::new(tx.get_writebuf()?);
282+
tw.start_struct(TagType::Anonymous)?;
283+
tw.str8(TagType::Context(1), &our_random)?;
284+
tw.u16(TagType::Context(2), local_sessid)?;
285+
tw.str8(TagType::Context(3), &case_session.our_pub_key)?;
286+
tw.str16(TagType::Context(4), encrypted)?;
287+
tw.end_container()?;
288+
289+
case_session.tt_hash.update(tx.as_mut_slice())?;
290+
291+
true
292+
} else {
293+
false
273294
}
274-
275-
#[cfg(feature = "alloc")]
276-
let signature_mut = &mut *signature;
277-
278-
#[cfg(not(feature = "alloc"))]
279-
let signature_mut = &mut signature;
280-
281-
let sign_len = Case::get_sigma2_sign(
282-
fabric.unwrap(),
283-
&case_session.our_pub_key,
284-
&case_session.peer_pub_key,
285-
signature_mut,
286-
)?;
287-
let signature = &signature[..sign_len];
288-
289-
#[cfg(feature = "alloc")]
290-
let encrypted_mut = &mut *encrypted;
291-
292-
#[cfg(not(feature = "alloc"))]
293-
let encrypted_mut = &mut encrypted;
294-
295-
Case::get_sigma2_encryption(
296-
fabric.unwrap(),
297-
self.rand,
298-
&our_random,
299-
case_session,
300-
signature,
301-
encrypted_mut,
302-
)?
303295
};
304-
let encrypted = &encrypted[0..encrypted_len];
305-
306-
// Generate our Response Body
307-
tx.reset();
308-
tx.set_proto_id(PROTO_ID_SECURE_CHANNEL);
309-
tx.set_proto_opcode(OpCode::CASESigma2 as u8);
310296

311-
let mut tw = TLVWriter::new(tx.get_writebuf()?);
312-
tw.start_struct(TagType::Anonymous)?;
313-
tw.str8(TagType::Context(1), &our_random)?;
314-
tw.u16(TagType::Context(2), local_sessid)?;
315-
tw.str8(TagType::Context(3), &case_session.our_pub_key)?;
316-
tw.str16(TagType::Context(4), encrypted)?;
317-
tw.end_container()?;
318-
319-
case_session.tt_hash.update(tx.as_mut_slice())?;
320-
321-
exchange.exchange(tx, rx).await
297+
if fabric_found {
298+
exchange.exchange(tx, rx).await
299+
} else {
300+
complete_with_status(
301+
exchange,
302+
tx,
303+
common::SCStatusCodes::NoSharedTrustRoots,
304+
None,
305+
)
306+
.await
307+
}
322308
}
323309

324310
fn get_session_clone_data(
@@ -515,7 +501,7 @@ impl<'a> Case<'a> {
515501
fabric: &Fabric,
516502
rand: Rand,
517503
our_random: &[u8],
518-
case_session: &mut CaseSession,
504+
case_session: &CaseSession,
519505
signature: &[u8],
520506
out: &mut [u8],
521507
) -> Result<usize, Error> {

rs-matter/src/secure_channel/crypto_mbedtls.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ impl CryptoSpake2 {
186186
let (Z, V) = Self::get_ZV_as_verifier(
187187
&self.w0,
188188
&self.L,
189-
&mut self.M,
189+
&self.M,
190190
&X,
191191
&self.xy,
192192
&self.order,
@@ -228,7 +228,7 @@ impl CryptoSpake2 {
228228
fn get_ZV_as_prover(
229229
w0: &Mpi,
230230
w1: &Mpi,
231-
N: &mut EcPoint,
231+
N: &EcPoint,
232232
Y: &EcPoint,
233233
x: &Mpi,
234234
order: &Mpi,
@@ -264,7 +264,7 @@ impl CryptoSpake2 {
264264
fn get_ZV_as_verifier(
265265
w0: &Mpi,
266266
L: &EcPoint,
267-
M: &mut EcPoint,
267+
M: &EcPoint,
268268
X: &EcPoint,
269269
y: &Mpi,
270270
order: &Mpi,
@@ -292,7 +292,7 @@ impl CryptoSpake2 {
292292
Ok((Z, V))
293293
}
294294

295-
fn invert(group: &mut EcGroup, num: &EcPoint) -> Result<EcPoint, mbedtls::Error> {
295+
fn invert(group: &EcGroup, num: &EcPoint) -> Result<EcPoint, mbedtls::Error> {
296296
let p = group.p()?;
297297
let num_y = num.y()?;
298298
let inverted_num_y = p.sub(&num_y)?;

0 commit comments

Comments
 (0)