Do not hold on to RefCell borrows across await points
This commit is contained in:
		
							parent
							
								
									ede024cf71
								
							
						
					
					
						commit
						f53f3b789d
					
				
					 6 changed files with 210 additions and 227 deletions
				
			
		
							
								
								
									
										2
									
								
								.github/workflows/ci.yml
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/ci.yml
									
										
									
									
										vendored
									
									
								
							|  | @ -10,7 +10,7 @@ on: | ||||||
|   workflow_dispatch: |   workflow_dispatch: | ||||||
| 
 | 
 | ||||||
| env: | env: | ||||||
|   RUST_TOOLCHAIN: nightly-2023-07-01 |   RUST_TOOLCHAIN: nightly | ||||||
|   GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |   GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||||||
|   CARGO_TERM_COLOR: always |   CARGO_TERM_COLOR: always | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -208,7 +208,6 @@ impl<'a> MdnsService<'a> { | ||||||
|         select(&mut broadcast, &mut respond).await.unwrap() |         select(&mut broadcast, &mut respond).await.unwrap() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     #[allow(clippy::await_holding_refcell_ref)] |  | ||||||
|     async fn broadcast(&self, tx_pipe: &Pipe<'_>) -> Result<(), Error> { |     async fn broadcast(&self, tx_pipe: &Pipe<'_>) -> Result<(), Error> { | ||||||
|         loop { |         loop { | ||||||
|             select( |             select( | ||||||
|  | @ -258,7 +257,6 @@ impl<'a> MdnsService<'a> { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     #[allow(clippy::await_holding_refcell_ref)] |  | ||||||
|     async fn respond(&self, rx_pipe: &Pipe<'_>, tx_pipe: &Pipe<'_>) -> Result<(), Error> { |     async fn respond(&self, rx_pipe: &Pipe<'_>, tx_pipe: &Pipe<'_>) -> Result<(), Error> { | ||||||
|         loop { |         loop { | ||||||
|             { |             { | ||||||
|  |  | ||||||
|  | @ -87,7 +87,6 @@ impl<'a> Case<'a> { | ||||||
|         self.handle_casesigma3(exchange, rx, tx, &mut session).await |         self.handle_casesigma3(exchange, rx, tx, &mut session).await | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     #[allow(clippy::await_holding_refcell_ref)] |  | ||||||
|     async fn handle_casesigma3( |     async fn handle_casesigma3( | ||||||
|         &mut self, |         &mut self, | ||||||
|         exchange: &mut Exchange<'_>, |         exchange: &mut Exchange<'_>, | ||||||
|  | @ -97,100 +96,81 @@ impl<'a> Case<'a> { | ||||||
|     ) -> Result<(), Error> { |     ) -> Result<(), Error> { | ||||||
|         rx.check_proto_opcode(OpCode::CASESigma3 as _)?; |         rx.check_proto_opcode(OpCode::CASESigma3 as _)?; | ||||||
| 
 | 
 | ||||||
|         let fabric_mgr = self.fabric_mgr.borrow(); |         let status = { | ||||||
|  |             let fabric_mgr = self.fabric_mgr.borrow(); | ||||||
| 
 | 
 | ||||||
|         let fabric = fabric_mgr.get_fabric(case_session.local_fabric_idx)?; |             let fabric = fabric_mgr.get_fabric(case_session.local_fabric_idx)?; | ||||||
|         if fabric.is_none() { |             if let Some(fabric) = fabric { | ||||||
|             drop(fabric_mgr); |                 let root = get_root_node_struct(rx.as_slice())?; | ||||||
|             complete_with_status( |                 let encrypted = root.find_tag(1)?.slice()?; | ||||||
|                 exchange, |  | ||||||
|                 tx, |  | ||||||
|                 common::SCStatusCodes::NoSharedTrustRoots, |  | ||||||
|                 None, |  | ||||||
|             ) |  | ||||||
|             .await?; |  | ||||||
|             return Ok(()); |  | ||||||
|         } |  | ||||||
|         // Safe to unwrap here
 |  | ||||||
|         let fabric = fabric.unwrap(); |  | ||||||
| 
 | 
 | ||||||
|         let root = get_root_node_struct(rx.as_slice())?; |                 let mut decrypted = alloc!([0; 800]); | ||||||
|         let encrypted = root.find_tag(1)?.slice()?; |                 if encrypted.len() > decrypted.len() { | ||||||
|  |                     error!("Data too large"); | ||||||
|  |                     Err(ErrorCode::NoSpace)?; | ||||||
|  |                 } | ||||||
|  |                 let decrypted = &mut decrypted[..encrypted.len()]; | ||||||
|  |                 decrypted.copy_from_slice(encrypted); | ||||||
| 
 | 
 | ||||||
|         let mut decrypted = alloc!([0; 800]); |                 let len = | ||||||
|         if encrypted.len() > decrypted.len() { |                     Case::get_sigma3_decryption(fabric.ipk.op_key(), case_session, decrypted)?; | ||||||
|             error!("Data too large"); |                 let decrypted = &decrypted[..len]; | ||||||
|             Err(ErrorCode::NoSpace)?; |  | ||||||
|         } |  | ||||||
|         let decrypted = &mut decrypted[..encrypted.len()]; |  | ||||||
|         decrypted.copy_from_slice(encrypted); |  | ||||||
| 
 | 
 | ||||||
|         let len = Case::get_sigma3_decryption(fabric.ipk.op_key(), case_session, decrypted)?; |                 let root = get_root_node_struct(decrypted)?; | ||||||
|         let decrypted = &decrypted[..len]; |                 let d = Sigma3Decrypt::from_tlv(&root)?; | ||||||
| 
 | 
 | ||||||
|         let root = get_root_node_struct(decrypted)?; |                 let initiator_noc = alloc!(Cert::new(d.initiator_noc.0)?); | ||||||
|         let d = Sigma3Decrypt::from_tlv(&root)?; |                 let mut initiator_icac = None; | ||||||
|  |                 if let Some(icac) = d.initiator_icac { | ||||||
|  |                     initiator_icac = Some(alloc!(Cert::new(icac.0)?)); | ||||||
|  |                 } | ||||||
| 
 | 
 | ||||||
|         let initiator_noc = alloc!(Cert::new(d.initiator_noc.0)?); |                 #[cfg(feature = "alloc")] | ||||||
|         let mut initiator_icac = None; |                 let initiator_icac_mut = initiator_icac.as_deref(); | ||||||
|         if let Some(icac) = d.initiator_icac { |  | ||||||
|             initiator_icac = Some(alloc!(Cert::new(icac.0)?)); |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         #[cfg(feature = "alloc")] |                 #[cfg(not(feature = "alloc"))] | ||||||
|         let initiator_icac_mut = initiator_icac.as_deref(); |                 let initiator_icac_mut = initiator_icac.as_ref(); | ||||||
| 
 | 
 | ||||||
|         #[cfg(not(feature = "alloc"))] |                 if let Err(e) = Case::validate_certs(fabric, &initiator_noc, initiator_icac_mut) { | ||||||
|         let initiator_icac_mut = initiator_icac.as_ref(); |                     error!("Certificate Chain doesn't match: {}", e); | ||||||
|  |                     SCStatusCodes::InvalidParameter | ||||||
|  |                 } else if let Err(e) = Case::validate_sigma3_sign( | ||||||
|  |                     d.initiator_noc.0, | ||||||
|  |                     d.initiator_icac.map(|a| a.0), | ||||||
|  |                     &initiator_noc, | ||||||
|  |                     d.signature.0, | ||||||
|  |                     case_session, | ||||||
|  |                 ) { | ||||||
|  |                     error!("Sigma3 Signature doesn't match: {}", e); | ||||||
|  |                     SCStatusCodes::InvalidParameter | ||||||
|  |                 } else { | ||||||
|  |                     // 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(rx.as_slice())?; | ||||||
|  |                     let clone_data = Case::get_session_clone_data( | ||||||
|  |                         fabric.ipk.op_key(), | ||||||
|  |                         fabric.get_node_id(), | ||||||
|  |                         initiator_noc.get_node_id()?, | ||||||
|  |                         exchange.with_session(|sess| Ok(sess.get_peer_addr()))?, | ||||||
|  |                         case_session, | ||||||
|  |                         &peer_catids, | ||||||
|  |                     )?; | ||||||
| 
 | 
 | ||||||
|         if let Err(e) = Case::validate_certs(fabric, &initiator_noc, initiator_icac_mut) { |                     // TODO: Handle NoSpace
 | ||||||
|             error!("Certificate Chain doesn't match: {}", e); |                     exchange | ||||||
|             complete_with_status(exchange, tx, common::SCStatusCodes::InvalidParameter, None) |                         .with_session_mgr_mut(|sess_mgr| sess_mgr.clone_session(&clone_data))?; | ||||||
|                 .await?; |  | ||||||
|             return Ok(()); |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         if Case::validate_sigma3_sign( |                     SCStatusCodes::SessionEstablishmentSuccess | ||||||
|             d.initiator_noc.0, |                 } | ||||||
|             d.initiator_icac.map(|a| a.0), |             } else { | ||||||
|             &initiator_noc, |                 SCStatusCodes::NoSharedTrustRoots | ||||||
|             d.signature.0, |             } | ||||||
|             case_session, |         }; | ||||||
|         ) |  | ||||||
|         .is_err() |  | ||||||
|         { |  | ||||||
|             error!("Sigma3 Signature doesn't match"); |  | ||||||
|             complete_with_status(exchange, tx, common::SCStatusCodes::InvalidParameter, None) |  | ||||||
|                 .await?; |  | ||||||
|             return Ok(()); |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         // Only now do we add this message to the TT Hash
 |         complete_with_status(exchange, tx, status, None).await | ||||||
|         let mut peer_catids: NocCatIds = Default::default(); |  | ||||||
|         initiator_noc.get_cat_ids(&mut peer_catids); |  | ||||||
|         case_session.tt_hash.update(rx.as_slice())?; |  | ||||||
|         let clone_data = Case::get_session_clone_data( |  | ||||||
|             fabric.ipk.op_key(), |  | ||||||
|             fabric.get_node_id(), |  | ||||||
|             initiator_noc.get_node_id()?, |  | ||||||
|             exchange.with_session(|sess| Ok(sess.get_peer_addr()))?, |  | ||||||
|             case_session, |  | ||||||
|             &peer_catids, |  | ||||||
|         )?; |  | ||||||
| 
 |  | ||||||
|         // TODO: Handle NoSpace
 |  | ||||||
|         exchange.with_session_mgr_mut(|sess_mgr| sess_mgr.clone_session(&clone_data))?; |  | ||||||
| 
 |  | ||||||
|         complete_with_status( |  | ||||||
|             exchange, |  | ||||||
|             tx, |  | ||||||
|             SCStatusCodes::SessionEstablishmentSuccess, |  | ||||||
|             None, |  | ||||||
|         ) |  | ||||||
|         .await |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     #[allow(clippy::await_holding_refcell_ref)] |  | ||||||
|     async fn handle_casesigma1( |     async fn handle_casesigma1( | ||||||
|         &mut self, |         &mut self, | ||||||
|         exchange: &mut Exchange<'_>, |         exchange: &mut Exchange<'_>, | ||||||
|  | @ -255,70 +235,76 @@ impl<'a> Case<'a> { | ||||||
|         const MAX_ENCRYPTED_SIZE: usize = 800; |         const MAX_ENCRYPTED_SIZE: usize = 800; | ||||||
| 
 | 
 | ||||||
|         let mut encrypted = alloc!([0; MAX_ENCRYPTED_SIZE]); |         let mut encrypted = alloc!([0; MAX_ENCRYPTED_SIZE]); | ||||||
|         let encrypted_len = { |         let mut signature = alloc!([0u8; crypto::EC_SIGNATURE_LEN_BYTES]); | ||||||
|             let mut signature = alloc!([0u8; crypto::EC_SIGNATURE_LEN_BYTES]); | 
 | ||||||
|  |         let fabric_found = { | ||||||
|             let fabric_mgr = self.fabric_mgr.borrow(); |             let fabric_mgr = self.fabric_mgr.borrow(); | ||||||
| 
 | 
 | ||||||
|             let fabric = fabric_mgr.get_fabric(case_session.local_fabric_idx)?; |             let fabric = fabric_mgr.get_fabric(case_session.local_fabric_idx)?; | ||||||
|             if fabric.is_none() { |             if let Some(fabric) = fabric { | ||||||
|                 drop(fabric_mgr); |                 #[cfg(feature = "alloc")] | ||||||
|                 complete_with_status( |                 let signature_mut = &mut *signature; | ||||||
|                     exchange, | 
 | ||||||
|                     tx, |                 #[cfg(not(feature = "alloc"))] | ||||||
|                     common::SCStatusCodes::NoSharedTrustRoots, |                 let signature_mut = &mut signature; | ||||||
|                     None, | 
 | ||||||
|                 ) |                 let sign_len = Case::get_sigma2_sign( | ||||||
|                 .await?; |                     fabric, | ||||||
|                 return Ok(()); |                     &case_session.our_pub_key, | ||||||
|  |                     &case_session.peer_pub_key, | ||||||
|  |                     signature_mut, | ||||||
|  |                 )?; | ||||||
|  |                 let signature = &signature[..sign_len]; | ||||||
|  | 
 | ||||||
|  |                 #[cfg(feature = "alloc")] | ||||||
|  |                 let encrypted_mut = &mut *encrypted; | ||||||
|  | 
 | ||||||
|  |                 #[cfg(not(feature = "alloc"))] | ||||||
|  |                 let encrypted_mut = &mut encrypted; | ||||||
|  | 
 | ||||||
|  |                 let encrypted_len = Case::get_sigma2_encryption( | ||||||
|  |                     fabric, | ||||||
|  |                     self.rand, | ||||||
|  |                     &our_random, | ||||||
|  |                     case_session, | ||||||
|  |                     signature, | ||||||
|  |                     encrypted_mut, | ||||||
|  |                 )?; | ||||||
|  | 
 | ||||||
|  |                 let encrypted = &encrypted[0..encrypted_len]; | ||||||
|  | 
 | ||||||
|  |                 // Generate our Response Body
 | ||||||
|  |                 tx.reset(); | ||||||
|  |                 tx.set_proto_id(PROTO_ID_SECURE_CHANNEL); | ||||||
|  |                 tx.set_proto_opcode(OpCode::CASESigma2 as u8); | ||||||
|  | 
 | ||||||
|  |                 let mut tw = TLVWriter::new(tx.get_writebuf()?); | ||||||
|  |                 tw.start_struct(TagType::Anonymous)?; | ||||||
|  |                 tw.str8(TagType::Context(1), &our_random)?; | ||||||
|  |                 tw.u16(TagType::Context(2), local_sessid)?; | ||||||
|  |                 tw.str8(TagType::Context(3), &case_session.our_pub_key)?; | ||||||
|  |                 tw.str16(TagType::Context(4), encrypted)?; | ||||||
|  |                 tw.end_container()?; | ||||||
|  | 
 | ||||||
|  |                 case_session.tt_hash.update(tx.as_mut_slice())?; | ||||||
|  | 
 | ||||||
|  |                 true | ||||||
|  |             } else { | ||||||
|  |                 false | ||||||
|             } |             } | ||||||
| 
 |  | ||||||
|             #[cfg(feature = "alloc")] |  | ||||||
|             let signature_mut = &mut *signature; |  | ||||||
| 
 |  | ||||||
|             #[cfg(not(feature = "alloc"))] |  | ||||||
|             let signature_mut = &mut signature; |  | ||||||
| 
 |  | ||||||
|             let sign_len = Case::get_sigma2_sign( |  | ||||||
|                 fabric.unwrap(), |  | ||||||
|                 &case_session.our_pub_key, |  | ||||||
|                 &case_session.peer_pub_key, |  | ||||||
|                 signature_mut, |  | ||||||
|             )?; |  | ||||||
|             let signature = &signature[..sign_len]; |  | ||||||
| 
 |  | ||||||
|             #[cfg(feature = "alloc")] |  | ||||||
|             let encrypted_mut = &mut *encrypted; |  | ||||||
| 
 |  | ||||||
|             #[cfg(not(feature = "alloc"))] |  | ||||||
|             let encrypted_mut = &mut encrypted; |  | ||||||
| 
 |  | ||||||
|             Case::get_sigma2_encryption( |  | ||||||
|                 fabric.unwrap(), |  | ||||||
|                 self.rand, |  | ||||||
|                 &our_random, |  | ||||||
|                 case_session, |  | ||||||
|                 signature, |  | ||||||
|                 encrypted_mut, |  | ||||||
|             )? |  | ||||||
|         }; |         }; | ||||||
|         let encrypted = &encrypted[0..encrypted_len]; |  | ||||||
| 
 | 
 | ||||||
|         // Generate our Response Body
 |         if fabric_found { | ||||||
|         tx.reset(); |             exchange.exchange(tx, rx).await | ||||||
|         tx.set_proto_id(PROTO_ID_SECURE_CHANNEL); |         } else { | ||||||
|         tx.set_proto_opcode(OpCode::CASESigma2 as u8); |             complete_with_status( | ||||||
| 
 |                 exchange, | ||||||
|         let mut tw = TLVWriter::new(tx.get_writebuf()?); |                 tx, | ||||||
|         tw.start_struct(TagType::Anonymous)?; |                 common::SCStatusCodes::NoSharedTrustRoots, | ||||||
|         tw.str8(TagType::Context(1), &our_random)?; |                 None, | ||||||
|         tw.u16(TagType::Context(2), local_sessid)?; |             ) | ||||||
|         tw.str8(TagType::Context(3), &case_session.our_pub_key)?; |             .await | ||||||
|         tw.str16(TagType::Context(4), encrypted)?; |         } | ||||||
|         tw.end_container()?; |  | ||||||
| 
 |  | ||||||
|         case_session.tt_hash.update(tx.as_mut_slice())?; |  | ||||||
| 
 |  | ||||||
|         exchange.exchange(tx, rx).await |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn get_session_clone_data( |     fn get_session_clone_data( | ||||||
|  | @ -515,7 +501,7 @@ impl<'a> Case<'a> { | ||||||
|         fabric: &Fabric, |         fabric: &Fabric, | ||||||
|         rand: Rand, |         rand: Rand, | ||||||
|         our_random: &[u8], |         our_random: &[u8], | ||||||
|         case_session: &mut CaseSession, |         case_session: &CaseSession, | ||||||
|         signature: &[u8], |         signature: &[u8], | ||||||
|         out: &mut [u8], |         out: &mut [u8], | ||||||
|     ) -> Result<usize, Error> { |     ) -> Result<usize, Error> { | ||||||
|  |  | ||||||
|  | @ -186,7 +186,7 @@ impl CryptoSpake2 { | ||||||
|         let (Z, V) = Self::get_ZV_as_verifier( |         let (Z, V) = Self::get_ZV_as_verifier( | ||||||
|             &self.w0, |             &self.w0, | ||||||
|             &self.L, |             &self.L, | ||||||
|             &mut self.M, |             &self.M, | ||||||
|             &X, |             &X, | ||||||
|             &self.xy, |             &self.xy, | ||||||
|             &self.order, |             &self.order, | ||||||
|  | @ -228,7 +228,7 @@ impl CryptoSpake2 { | ||||||
|     fn get_ZV_as_prover( |     fn get_ZV_as_prover( | ||||||
|         w0: &Mpi, |         w0: &Mpi, | ||||||
|         w1: &Mpi, |         w1: &Mpi, | ||||||
|         N: &mut EcPoint, |         N: &EcPoint, | ||||||
|         Y: &EcPoint, |         Y: &EcPoint, | ||||||
|         x: &Mpi, |         x: &Mpi, | ||||||
|         order: &Mpi, |         order: &Mpi, | ||||||
|  | @ -264,7 +264,7 @@ impl CryptoSpake2 { | ||||||
|     fn get_ZV_as_verifier( |     fn get_ZV_as_verifier( | ||||||
|         w0: &Mpi, |         w0: &Mpi, | ||||||
|         L: &EcPoint, |         L: &EcPoint, | ||||||
|         M: &mut EcPoint, |         M: &EcPoint, | ||||||
|         X: &EcPoint, |         X: &EcPoint, | ||||||
|         y: &Mpi, |         y: &Mpi, | ||||||
|         order: &Mpi, |         order: &Mpi, | ||||||
|  | @ -292,7 +292,7 @@ impl CryptoSpake2 { | ||||||
|         Ok((Z, V)) |         Ok((Z, V)) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn invert(group: &mut EcGroup, num: &EcPoint) -> Result<EcPoint, mbedtls::Error> { |     fn invert(group: &EcGroup, num: &EcPoint) -> Result<EcPoint, mbedtls::Error> { | ||||||
|         let p = group.p()?; |         let p = group.p()?; | ||||||
|         let num_y = num.y()?; |         let num_y = num.y()?; | ||||||
|         let inverted_num_y = p.sub(&num_y)?; |         let inverted_num_y = p.sub(&num_y)?; | ||||||
|  |  | ||||||
|  | @ -213,7 +213,6 @@ impl<'a> Pake<'a> { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     #[allow(non_snake_case)] |     #[allow(non_snake_case)] | ||||||
|     #[allow(clippy::await_holding_refcell_ref)] |  | ||||||
|     async fn handle_pasepake1( |     async fn handle_pasepake1( | ||||||
|         &mut self, |         &mut self, | ||||||
|         exchange: &mut Exchange<'_>, |         exchange: &mut Exchange<'_>, | ||||||
|  | @ -224,32 +223,32 @@ impl<'a> Pake<'a> { | ||||||
|         rx.check_proto_opcode(OpCode::PASEPake1 as _)?; |         rx.check_proto_opcode(OpCode::PASEPake1 as _)?; | ||||||
|         self.update_timeout(exchange, tx, false).await?; |         self.update_timeout(exchange, tx, false).await?; | ||||||
| 
 | 
 | ||||||
|         let pase = self.pase.borrow(); |         { | ||||||
|         let session = pase.session.as_ref().ok_or(ErrorCode::NoSession)?; |             let pase = self.pase.borrow(); | ||||||
|  |             let session = pase.session.as_ref().ok_or(ErrorCode::NoSession)?; | ||||||
| 
 | 
 | ||||||
|         let pA = extract_pasepake_1_or_3_params(rx.as_slice())?; |             let pA = extract_pasepake_1_or_3_params(rx.as_slice())?; | ||||||
|         let mut pB: [u8; 65] = [0; 65]; |             let mut pB: [u8; 65] = [0; 65]; | ||||||
|         let mut cB: [u8; 32] = [0; 32]; |             let mut cB: [u8; 32] = [0; 32]; | ||||||
|         spake2p.start_verifier(&session.verifier)?; |             spake2p.start_verifier(&session.verifier)?; | ||||||
|         spake2p.handle_pA(pA, &mut pB, &mut cB, pase.rand)?; |             spake2p.handle_pA(pA, &mut pB, &mut cB, pase.rand)?; | ||||||
| 
 | 
 | ||||||
|         // Generate response
 |             // Generate response
 | ||||||
|         tx.reset(); |             tx.reset(); | ||||||
|         tx.set_proto_id(PROTO_ID_SECURE_CHANNEL); |             tx.set_proto_id(PROTO_ID_SECURE_CHANNEL); | ||||||
|         tx.set_proto_opcode(OpCode::PASEPake2 as u8); |             tx.set_proto_opcode(OpCode::PASEPake2 as u8); | ||||||
| 
 | 
 | ||||||
|         let mut tw = TLVWriter::new(tx.get_writebuf()?); |             let mut tw = TLVWriter::new(tx.get_writebuf()?); | ||||||
|         let resp = Pake1Resp { |             let resp = Pake1Resp { | ||||||
|             pb: OctetStr(&pB), |                 pb: OctetStr(&pB), | ||||||
|             cb: OctetStr(&cB), |                 cb: OctetStr(&cB), | ||||||
|         }; |             }; | ||||||
|         resp.to_tlv(&mut tw, TagType::Anonymous)?; |             resp.to_tlv(&mut tw, TagType::Anonymous)?; | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         drop(pase); |  | ||||||
|         exchange.exchange(tx, rx).await |         exchange.exchange(tx, rx).await | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     #[allow(clippy::await_holding_refcell_ref)] |  | ||||||
|     async fn handle_pbkdfparamrequest( |     async fn handle_pbkdfparamrequest( | ||||||
|         &mut self, |         &mut self, | ||||||
|         exchange: &mut Exchange<'_>, |         exchange: &mut Exchange<'_>, | ||||||
|  | @ -260,52 +259,51 @@ impl<'a> Pake<'a> { | ||||||
|         rx.check_proto_opcode(OpCode::PBKDFParamRequest as _)?; |         rx.check_proto_opcode(OpCode::PBKDFParamRequest as _)?; | ||||||
|         self.update_timeout(exchange, tx, true).await?; |         self.update_timeout(exchange, tx, true).await?; | ||||||
| 
 | 
 | ||||||
|         let pase = self.pase.borrow(); |         { | ||||||
|         let session = pase.session.as_ref().ok_or(ErrorCode::NoSession)?; |             let pase = self.pase.borrow(); | ||||||
|  |             let session = pase.session.as_ref().ok_or(ErrorCode::NoSession)?; | ||||||
| 
 | 
 | ||||||
|         let root = tlv::get_root_node(rx.as_slice())?; |             let root = tlv::get_root_node(rx.as_slice())?; | ||||||
|         let a = PBKDFParamReq::from_tlv(&root)?; |             let a = PBKDFParamReq::from_tlv(&root)?; | ||||||
|         if a.passcode_id != 0 { |             if a.passcode_id != 0 { | ||||||
|             error!("Can't yet handle passcode_id != 0"); |                 error!("Can't yet handle passcode_id != 0"); | ||||||
|             Err(ErrorCode::Invalid)?; |                 Err(ErrorCode::Invalid)?; | ||||||
|         } |             } | ||||||
| 
 | 
 | ||||||
|         let mut our_random: [u8; 32] = [0; 32]; |             let mut our_random: [u8; 32] = [0; 32]; | ||||||
|         (self.pase.borrow().rand)(&mut our_random); |             (self.pase.borrow().rand)(&mut our_random); | ||||||
| 
 | 
 | ||||||
|         let local_sessid = exchange.with_session_mgr_mut(|mgr| Ok(mgr.get_next_sess_id()))?; |             let local_sessid = exchange.with_session_mgr_mut(|mgr| Ok(mgr.get_next_sess_id()))?; | ||||||
|         let spake2p_data: u32 = ((local_sessid as u32) << 16) | a.initiator_ssid as u32; |             let spake2p_data: u32 = ((local_sessid as u32) << 16) | a.initiator_ssid as u32; | ||||||
|         spake2p.set_app_data(spake2p_data); |             spake2p.set_app_data(spake2p_data); | ||||||
| 
 | 
 | ||||||
|         // Generate response
 |             // Generate response
 | ||||||
|         tx.reset(); |             tx.reset(); | ||||||
|         tx.set_proto_id(PROTO_ID_SECURE_CHANNEL); |             tx.set_proto_id(PROTO_ID_SECURE_CHANNEL); | ||||||
|         tx.set_proto_opcode(OpCode::PBKDFParamResponse as u8); |             tx.set_proto_opcode(OpCode::PBKDFParamResponse as u8); | ||||||
| 
 | 
 | ||||||
|         let mut tw = TLVWriter::new(tx.get_writebuf()?); |             let mut tw = TLVWriter::new(tx.get_writebuf()?); | ||||||
|         let mut resp = PBKDFParamResp { |             let mut resp = PBKDFParamResp { | ||||||
|             init_random: a.initiator_random, |                 init_random: a.initiator_random, | ||||||
|             our_random: OctetStr(&our_random), |                 our_random: OctetStr(&our_random), | ||||||
|             local_sessid, |                 local_sessid, | ||||||
|             params: None, |                 params: None, | ||||||
|         }; |  | ||||||
|         if !a.has_params { |  | ||||||
|             let params_resp = PBKDFParamRespParams { |  | ||||||
|                 count: session.verifier.count, |  | ||||||
|                 salt: OctetStr(&session.verifier.salt), |  | ||||||
|             }; |             }; | ||||||
|             resp.params = Some(params_resp); |             if !a.has_params { | ||||||
|  |                 let params_resp = PBKDFParamRespParams { | ||||||
|  |                     count: session.verifier.count, | ||||||
|  |                     salt: OctetStr(&session.verifier.salt), | ||||||
|  |                 }; | ||||||
|  |                 resp.params = Some(params_resp); | ||||||
|  |             } | ||||||
|  |             resp.to_tlv(&mut tw, TagType::Anonymous)?; | ||||||
|  | 
 | ||||||
|  |             spake2p.set_context(rx.as_slice(), tx.as_mut_slice())?; | ||||||
|         } |         } | ||||||
|         resp.to_tlv(&mut tw, TagType::Anonymous)?; |  | ||||||
| 
 |  | ||||||
|         spake2p.set_context(rx.as_slice(), tx.as_mut_slice())?; |  | ||||||
| 
 |  | ||||||
|         drop(pase); |  | ||||||
| 
 | 
 | ||||||
|         exchange.exchange(tx, rx).await |         exchange.exchange(tx, rx).await | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     #[allow(clippy::await_holding_refcell_ref)] |  | ||||||
|     async fn update_timeout( |     async fn update_timeout( | ||||||
|         &mut self, |         &mut self, | ||||||
|         exchange: &mut Exchange<'_>, |         exchange: &mut Exchange<'_>, | ||||||
|  | @ -314,36 +312,38 @@ impl<'a> Pake<'a> { | ||||||
|     ) -> Result<(), Error> { |     ) -> Result<(), Error> { | ||||||
|         self.check_session(exchange, tx).await?; |         self.check_session(exchange, tx).await?; | ||||||
| 
 | 
 | ||||||
|         let mut pase = self.pase.borrow_mut(); |         let status = { | ||||||
|  |             let mut pase = self.pase.borrow_mut(); | ||||||
| 
 | 
 | ||||||
|         if pase |             if pase | ||||||
|             .timeout |                 .timeout | ||||||
|             .as_ref() |                 .as_ref() | ||||||
|             .map(|sd| sd.is_sess_expired(pase.epoch)) |                 .map(|sd| sd.is_sess_expired(pase.epoch)) | ||||||
|             .unwrap_or(false) |                 .unwrap_or(false) | ||||||
|         { |             { | ||||||
|             pase.timeout = None; |                 pase.timeout = None; | ||||||
|         } |             } | ||||||
| 
 | 
 | ||||||
|         let status = if let Some(sd) = pase.timeout.as_mut() { |             if let Some(sd) = pase.timeout.as_mut() { | ||||||
|             if &sd.exch_id != exchange.id() { |                 if &sd.exch_id != exchange.id() { | ||||||
|                 info!("Other PAKE session in progress"); |                     info!("Other PAKE session in progress"); | ||||||
|                 Some(SCStatusCodes::Busy) |                     Some(SCStatusCodes::Busy) | ||||||
|             } else { |                 } else { | ||||||
|                 None |                     None | ||||||
|  |                 } | ||||||
|  |             } else if new { | ||||||
|  |                 None | ||||||
|  |             } else { | ||||||
|  |                 error!("PAKE session not found or expired"); | ||||||
|  |                 Some(SCStatusCodes::SessionNotFound) | ||||||
|             } |             } | ||||||
|         } else if new { |  | ||||||
|             None |  | ||||||
|         } else { |  | ||||||
|             error!("PAKE session not found or expired"); |  | ||||||
|             Some(SCStatusCodes::SessionNotFound) |  | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         if let Some(status) = status { |         if let Some(status) = status { | ||||||
|             drop(pase); |  | ||||||
| 
 |  | ||||||
|             complete_with_status(exchange, tx, status, None).await |             complete_with_status(exchange, tx, status, None).await | ||||||
|         } else { |         } else { | ||||||
|  |             let mut pase = self.pase.borrow_mut(); | ||||||
|  | 
 | ||||||
|             pase.timeout = Some(Timeout::new(exchange, pase.epoch)); |             pase.timeout = Some(Timeout::new(exchange, pase.epoch)); | ||||||
| 
 | 
 | ||||||
|             Ok(()) |             Ok(()) | ||||||
|  |  | ||||||
|  | @ -397,7 +397,6 @@ impl<'a> Matter<'a> { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     #[inline(always)] |     #[inline(always)] | ||||||
|     #[cfg_attr(feature = "nightly", allow(clippy::await_holding_refcell_ref))] // Fine because of the async mutex
 |  | ||||||
|     pub async fn handle_exchange<H>( |     pub async fn handle_exchange<H>( | ||||||
|         &self, |         &self, | ||||||
|         tx_buf: &mut [u8; MAX_TX_BUF_SIZE], |         tx_buf: &mut [u8; MAX_TX_BUF_SIZE], | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue