Skip to content

Commit 02d49fa

Browse files
committed
get_ciphers
1 parent b6a1272 commit 02d49fa

File tree

1 file changed

+59
-1
lines changed

1 file changed

+59
-1
lines changed

stdlib/src/ssl.rs

Lines changed: 59 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, PyStrRef, PyType, PyTypeRef, PyWeak},
42+
builtins::{PyBaseExceptionRef, PyListRef, PyStrRef, PyType, PyTypeRef, PyWeak},
4343
class_or_notimplemented,
4444
convert::{ToPyException, ToPyObject},
4545
exceptions,
@@ -569,6 +569,64 @@ mod _ssl {
569569
})
570570
}
571571

572+
#[pymethod]
573+
fn get_ciphers(&self, vm: &VirtualMachine) -> PyResult<PyListRef> {
574+
let ctx = self.ctx();
575+
let ssl = ssl::Ssl::new(&*ctx).map_err(|e| convert_openssl_error(vm, e))?;
576+
577+
unsafe {
578+
let ciphers_ptr = SSL_get_ciphers(ssl.as_ptr());
579+
if ciphers_ptr.is_null() {
580+
return Ok(vm.ctx.new_list(vec![]));
581+
}
582+
583+
let num_ciphers = sys::OPENSSL_sk_num(ciphers_ptr as *const _);
584+
let mut result = Vec::new();
585+
586+
for i in 0..num_ciphers {
587+
let cipher_ptr =
588+
sys::OPENSSL_sk_value(ciphers_ptr as *const _, i) as *const sys::SSL_CIPHER;
589+
let cipher = ssl::SslCipherRef::from_ptr(cipher_ptr as *mut _);
590+
591+
let (name, version, bits) = cipher_to_tuple(cipher);
592+
let dict = vm.ctx.new_dict();
593+
dict.set_item("name", vm.ctx.new_str(name).into(), vm)?;
594+
dict.set_item("protocol", vm.ctx.new_str(version).into(), vm)?;
595+
dict.set_item("secret_bits", vm.ctx.new_int(bits).into(), vm)?;
596+
result.push(dict.into());
597+
}
598+
599+
Ok(vm.ctx.new_list(result))
600+
}
601+
}
602+
603+
#[pymethod]
604+
fn set_ecdh_curve(&self, name: PyStrRef, vm: &VirtualMachine) -> PyResult<()> {
605+
use openssl::ec::{EcGroup, EcKey};
606+
607+
let curve_name = name.as_str();
608+
if curve_name.contains('\0') {
609+
return Err(exceptions::cstring_error(vm));
610+
}
611+
612+
// Find the NID for the curve name using OBJ_sn2nid
613+
let name_cstr = name.to_cstring(vm)?;
614+
let nid_raw = unsafe { sys::OBJ_sn2nid(name_cstr.as_ptr()) };
615+
if nid_raw == 0 {
616+
return Err(vm.new_value_error(format!("unknown curve name: {}", curve_name)));
617+
}
618+
let nid = Nid::from_raw(nid_raw);
619+
620+
// Create EC key from the curve
621+
let group = EcGroup::from_curve_name(nid).map_err(|e| convert_openssl_error(vm, e))?;
622+
let key = EcKey::from_group(&group).map_err(|e| convert_openssl_error(vm, e))?;
623+
624+
// Set the temporary ECDH key
625+
self.builder()
626+
.set_tmp_ecdh(&key)
627+
.map_err(|e| convert_openssl_error(vm, e))
628+
}
629+
572630
#[pygetset]
573631
fn options(&self) -> libc::c_ulong {
574632
self.ctx.read().options().bits() as _

0 commit comments

Comments
 (0)