Skip to content

Commit 1878e3d

Browse files
committed
get_channel_binding
1 parent 02d49fa commit 1878e3d

File tree

1 file changed

+44
-1
lines changed

1 file changed

+44
-1
lines changed

stdlib/src/ssl.rs

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ mod _ssl {
3939
socket::{self, PySocket},
4040
vm::{
4141
Py, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine,
42-
builtins::{PyBaseExceptionRef, PyListRef, PyStrRef, PyType, PyTypeRef, PyWeak},
42+
builtins::{PyBaseExceptionRef, PyBytesRef, PyListRef, PyStrRef, PyType, PyTypeRef, PyWeak},
4343
class_or_notimplemented,
4444
convert::{ToPyException, ToPyObject},
4545
exceptions,
@@ -1139,6 +1139,49 @@ mod _ssl {
11391139
}
11401140
}
11411141

1142+
#[pymethod]
1143+
fn get_channel_binding(
1144+
&self,
1145+
cb_type: OptionalArg<PyStrRef>,
1146+
vm: &VirtualMachine,
1147+
) -> PyResult<Option<PyBytesRef>> {
1148+
const CB_MAXLEN: usize = 512;
1149+
1150+
let cb_type_str = cb_type.as_ref().map_or("tls-unique", |s| s.as_str());
1151+
1152+
if cb_type_str != "tls-unique" {
1153+
return Err(vm.new_value_error(format!(
1154+
"Unsupported channel binding type '{}'",
1155+
cb_type_str
1156+
)));
1157+
}
1158+
1159+
let stream = self.stream.read();
1160+
let ssl_ptr = stream.ssl().as_ptr();
1161+
1162+
unsafe {
1163+
let session_reused = sys::SSL_session_reused(ssl_ptr) != 0;
1164+
let is_client = matches!(self.socket_type, SslServerOrClient::Client);
1165+
1166+
// Use XOR logic from CPython
1167+
let use_finished = session_reused ^ is_client;
1168+
1169+
let mut buf = vec![0u8; CB_MAXLEN];
1170+
let len = if use_finished {
1171+
sys::SSL_get_finished(ssl_ptr, buf.as_mut_ptr() as *mut _, CB_MAXLEN)
1172+
} else {
1173+
sys::SSL_get_peer_finished(ssl_ptr, buf.as_mut_ptr() as *mut _, CB_MAXLEN)
1174+
};
1175+
1176+
if len == 0 {
1177+
Ok(None)
1178+
} else {
1179+
buf.truncate(len);
1180+
Ok(Some(vm.ctx.new_bytes(buf)))
1181+
}
1182+
}
1183+
}
1184+
11421185
#[cfg(osslconf = "OPENSSL_NO_COMP")]
11431186
#[pymethod]
11441187
fn compression(&self) -> Option<&'static str> {

0 commit comments

Comments
 (0)