Skip to content

Commit a262e85

Browse files
committed
shared ciphers
1 parent efddfce commit a262e85

File tree

1 file changed

+73
-0
lines changed

1 file changed

+73
-0
lines changed

stdlib/src/ssl.rs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1161,6 +1161,69 @@ mod _ssl {
11611161
.map(cipher_to_tuple)
11621162
}
11631163

1164+
#[pymethod]
1165+
fn shared_ciphers(&self, vm: &VirtualMachine) -> Option<PyListRef> {
1166+
#[cfg(ossl110)]
1167+
{
1168+
let stream = self.stream.read();
1169+
unsafe {
1170+
let server_ciphers = SSL_get_ciphers(stream.ssl().as_ptr());
1171+
if server_ciphers.is_null() {
1172+
return None;
1173+
}
1174+
1175+
let client_ciphers = SSL_get_client_ciphers(stream.ssl().as_ptr());
1176+
if client_ciphers.is_null() {
1177+
return None;
1178+
}
1179+
1180+
let mut result = Vec::new();
1181+
let num_server = sys::OPENSSL_sk_num(server_ciphers as *const _);
1182+
let num_client = sys::OPENSSL_sk_num(client_ciphers as *const _);
1183+
1184+
for i in 0..num_server {
1185+
let server_cipher_ptr = sys::OPENSSL_sk_value(server_ciphers as *const _, i)
1186+
as *const sys::SSL_CIPHER;
1187+
1188+
// Check if client supports this cipher by comparing pointers
1189+
let mut found = false;
1190+
for j in 0..num_client {
1191+
let client_cipher_ptr =
1192+
sys::OPENSSL_sk_value(client_ciphers as *const _, j)
1193+
as *const sys::SSL_CIPHER;
1194+
1195+
if server_cipher_ptr == client_cipher_ptr {
1196+
found = true;
1197+
break;
1198+
}
1199+
}
1200+
1201+
if found {
1202+
let cipher = ssl::SslCipherRef::from_ptr(server_cipher_ptr as *mut _);
1203+
let (name, version, bits) = cipher_to_tuple(cipher);
1204+
let tuple = vm.new_tuple((
1205+
vm.ctx.new_str(name),
1206+
vm.ctx.new_str(version),
1207+
vm.ctx.new_int(bits),
1208+
));
1209+
result.push(tuple.into());
1210+
}
1211+
}
1212+
1213+
if result.is_empty() {
1214+
None
1215+
} else {
1216+
Some(vm.ctx.new_list(result))
1217+
}
1218+
}
1219+
}
1220+
#[cfg(not(ossl110))]
1221+
{
1222+
let _ = vm;
1223+
None
1224+
}
1225+
}
1226+
11641227
#[pymethod]
11651228
fn selected_alpn_protocol(&self) -> Option<String> {
11661229
#[cfg(ossl102)]
@@ -1536,6 +1599,16 @@ mod _ssl {
15361599
unsafe impl Send for PySslMemoryBio {}
15371600
unsafe impl Sync for PySslMemoryBio {}
15381601

1602+
// OpenSSL functions not in openssl-sys
1603+
unsafe extern "C" {
1604+
fn SSL_get_ciphers(ssl: *const sys::SSL) -> *const sys::stack_st_SSL_CIPHER;
1605+
}
1606+
1607+
#[cfg(ossl110)]
1608+
unsafe extern "C" {
1609+
fn SSL_get_client_ciphers(ssl: *const sys::SSL) -> *const sys::stack_st_SSL_CIPHER;
1610+
}
1611+
15391612
// OpenSSL BIO helper functions
15401613
// These are typically macros in OpenSSL, implemented via BIO_ctrl
15411614
const BIO_CTRL_PENDING: libc::c_int = 10;

0 commit comments

Comments
 (0)