mirror of
https://github.com/rustdesk/hbb_common.git
synced 2026-10-11 19:23:59 +00:00
stream: refuse a key exchange version set_negotiated_key does not know
Version 1 is matched explicitly and any other picked version is an error, so adding a version without its arm here fails instead of running as version 1. WebRTC takes only version 0, as both handshakes already require. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019aokqJuhjvB3kijXtAg5Ns
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
cbc8772d4a
commit
cee8cf3dc3
+34
-13
@@ -1,4 +1,4 @@
|
||||
use crate::{config, tcp, websocket, ResultType};
|
||||
use crate::{bail, config, tcp, websocket, ResultType};
|
||||
#[cfg(feature = "webrtc")]
|
||||
use crate::webrtc;
|
||||
use sodiumoxide::crypto::secretbox::Key;
|
||||
@@ -81,8 +81,8 @@ impl Stream {
|
||||
}
|
||||
|
||||
/// The stream key for the key exchange version in `t.picked`: version 0 is `set_key`, and
|
||||
/// later versions derive one key per direction from the transcript. `is_initiator` is the
|
||||
/// side that sent the sealed key.
|
||||
/// version 1 derives one key per direction from the transcript. Any other version is refused
|
||||
/// rather than run as one of these. `is_initiator` is the side that sent the sealed key.
|
||||
#[inline]
|
||||
pub fn set_negotiated_key(
|
||||
&mut self,
|
||||
@@ -90,18 +90,18 @@ impl Stream {
|
||||
is_initiator: bool,
|
||||
t: &tcp::KxTranscript,
|
||||
) -> ResultType<()> {
|
||||
if t.picked == 0 {
|
||||
self.set_key(key);
|
||||
return Ok(());
|
||||
}
|
||||
match self {
|
||||
#[cfg(feature = "webrtc")]
|
||||
Stream::WebRTC(s) => {
|
||||
s.set_key(key);
|
||||
match t.picked {
|
||||
0 => {
|
||||
self.set_key(key);
|
||||
Ok(())
|
||||
}
|
||||
Stream::WebSocket(s) => s.set_key_split(key, is_initiator, t),
|
||||
Stream::Tcp(s) => s.set_key_split(key, is_initiator, t),
|
||||
1 => match self {
|
||||
#[cfg(feature = "webrtc")]
|
||||
Stream::WebRTC(_) => bail!("key exchange version 1 does not apply to WebRTC"),
|
||||
Stream::WebSocket(s) => s.set_key_split(key, is_initiator, t),
|
||||
Stream::Tcp(s) => s.set_key_split(key, is_initiator, t),
|
||||
},
|
||||
v => bail!("unsupported key exchange version {}", v),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,3 +313,24 @@ impl Drop for Stream {
|
||||
self.close_webrtc();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_set_negotiated_key_refuses_unknown_versions() {
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap();
|
||||
let addr = listener.local_addr().unwrap();
|
||||
let mut stream = Stream::from(TcpStream::connect(addr).await.unwrap(), addr);
|
||||
let t = |picked| tcp::KxTranscript {
|
||||
initiator_pk: &[1u8; 32],
|
||||
responder_pk: &[2u8; 32],
|
||||
advertised: 1,
|
||||
picked,
|
||||
};
|
||||
let mut set = |picked| stream.set_negotiated_key(Key([0u8; 32]), true, &t(picked));
|
||||
assert!(set(2).is_err());
|
||||
assert!(set(1).is_ok());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user