Skip to content

Commit 3c7f4b0

Browse files
committed
shared ciphers
1 parent a37a4f3 commit 3c7f4b0

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
@@ -1189,6 +1189,69 @@ mod _ssl {
11891189
.map(cipher_to_tuple)
11901190
}
11911191

1192+
#[pymethod]
1193+
fn shared_ciphers(&self, vm: &VirtualMachine) -> Option<PyObjectRef> {
1194+
#[cfg(ossl110)]
1195+
{
1196+
let stream = self.stream.read();
1197+
unsafe {
1198+
let server_ciphers = SSL_get_ciphers(stream.ssl().as_ptr());
1199+
if server_ciphers.is_null() {
1200+
return None;
1201+
}
1202+
1203+
let client_ciphers = SSL_get_client_ciphers(stream.ssl().as_ptr());
1204+
if client_ciphers.is_null() {
1205+
return None;
1206+
}
1207+
1208+
let mut result = Vec::new();
1209+
let num_server = sys::OPENSSL_sk_num(server_ciphers as *const _);
1210+
let num_client = sys::OPENSSL_sk_num(client_ciphers as *const _);
1211+
1212+
for i in 0..num_server {
1213+
let server_cipher_ptr = sys::OPENSSL_sk_value(server_ciphers as *const _, i)
1214+
as *const sys::SSL_CIPHER;
1215+
1216+
// Check if client supports this cipher by comparing pointers
1217+
let mut found = false;
1218+
for j in 0..num_client {
1219+
let client_cipher_ptr =
1220+
sys::OPENSSL_sk_value(client_ciphers as *const _, j)
1221+
as *const sys::SSL_CIPHER;
1222+
1223+
if server_cipher_ptr == client_cipher_ptr {
1224+
found = true;
1225+
break;
1226+
}
1227+
}
1228+
1229+
if found {
1230+
let cipher = ssl::SslCipherRef::from_ptr(server_cipher_ptr as *mut _);
1231+
let (name, version, bits) = cipher_to_tuple(cipher);
1232+
let tuple = vm.new_tuple((
1233+
vm.ctx.new_str(name),
1234+
vm.ctx.new_str(version),
1235+
vm.ctx.new_int(bits),
1236+
));
1237+
result.push(tuple.into());
1238+
}
1239+
}
1240+
1241+
if result.is_empty() {
1242+
None
1243+
} else {
1244+
Some(vm.ctx.new_list(result).into())
1245+
}
1246+
}
1247+
}
1248+
#[cfg(not(ossl110))]
1249+
{
1250+
let _ = vm;
1251+
None
1252+
}
1253+
}
1254+
11921255
#[pymethod]
11931256
fn selected_alpn_protocol(&self) -> Option<String> {
11941257
#[cfg(ossl102)]
@@ -1564,6 +1627,16 @@ mod _ssl {
15641627
unsafe impl Send for PySslMemoryBio {}
15651628
unsafe impl Sync for PySslMemoryBio {}
15661629

1630+
// OpenSSL functions not in openssl-sys
1631+
unsafe extern "C" {
1632+
fn SSL_get_ciphers(ssl: *const sys::SSL) -> *const sys::stack_st_SSL_CIPHER;
1633+
}
1634+
1635+
#[cfg(ossl110)]
1636+
unsafe extern "C" {
1637+
fn SSL_get_client_ciphers(ssl: *const sys::SSL) -> *const sys::stack_st_SSL_CIPHER;
1638+
}
1639+
15671640
// OpenSSL BIO helper functions
15681641
// These are typically macros in OpenSSL, implemented via BIO_ctrl
15691642
const BIO_CTRL_PENDING: libc::c_int = 10;

0 commit comments

Comments
 (0)