Skip to content

Commit 8ff977d

Browse files
committed
get_channel_binding
1 parent aba082c commit 8ff977d

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

stdlib/src/ssl.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,6 +1172,49 @@ mod _ssl {
11721172
}
11731173
}
11741174

1175+
#[pymethod]
1176+
fn get_channel_binding(
1177+
&self,
1178+
cb_type: OptionalArg<PyStrRef>,
1179+
vm: &VirtualMachine,
1180+
) -> PyResult<Option<PyObjectRef>> {
1181+
const CB_MAXLEN: usize = 512;
1182+
1183+
let cb_type_str = cb_type.as_ref().map_or("tls-unique", |s| s.as_str());
1184+
1185+
if cb_type_str != "tls-unique" {
1186+
return Err(vm.new_value_error(format!(
1187+
"Unsupported channel binding type '{}'",
1188+
cb_type_str
1189+
)));
1190+
}
1191+
1192+
let stream = self.stream.read();
1193+
let ssl_ptr = stream.ssl().as_ptr();
1194+
1195+
unsafe {
1196+
let session_reused = sys::SSL_session_reused(ssl_ptr) != 0;
1197+
let is_client = matches!(self.socket_type, SslServerOrClient::Client);
1198+
1199+
// Use XOR logic from CPython
1200+
let use_finished = session_reused ^ is_client;
1201+
1202+
let mut buf = vec![0u8; CB_MAXLEN];
1203+
let len = if use_finished {
1204+
sys::SSL_get_finished(ssl_ptr, buf.as_mut_ptr() as *mut _, CB_MAXLEN)
1205+
} else {
1206+
sys::SSL_get_peer_finished(ssl_ptr, buf.as_mut_ptr() as *mut _, CB_MAXLEN)
1207+
};
1208+
1209+
if len == 0 {
1210+
Ok(None)
1211+
} else {
1212+
buf.truncate(len);
1213+
Ok(Some(vm.ctx.new_bytes(buf).into()))
1214+
}
1215+
}
1216+
}
1217+
11751218
#[cfg(osslconf = "OPENSSL_NO_COMP")]
11761219
#[pymethod]
11771220
fn compression(&self) -> Option<&'static str> {

0 commit comments

Comments
 (0)