@@ -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