@@ -1360,54 +1360,83 @@ If the optional argument is True, returns a DER-encoded copy of the\n\
13601360peer certificate, or None if no certificate was provided. This will\n\
13611361return the certificate even if it wasn't validated." );
13621362
1363- static PyObject * PySSL_cipher (PySSLSocket * self ) {
1364-
1365- PyObject * retval , * v ;
1366- const SSL_CIPHER * current ;
1367- char * cipher_name ;
1368- char * cipher_protocol ;
1369-
1370- if (self -> ssl == NULL )
1371- Py_RETURN_NONE ;
1372- current = SSL_get_current_cipher (self -> ssl );
1373- if (current == NULL )
1374- Py_RETURN_NONE ;
1375-
1376- retval = PyTuple_New (3 );
1363+ static PyObject *
1364+ cipher_to_tuple (const SSL_CIPHER * cipher )
1365+ {
1366+ const char * cipher_name , * cipher_protocol ;
1367+ PyObject * v , * retval = PyTuple_New (3 );
13771368 if (retval == NULL )
13781369 return NULL ;
13791370
1380- cipher_name = ( char * ) SSL_CIPHER_get_name (current );
1371+ cipher_name = SSL_CIPHER_get_name (cipher );
13811372 if (cipher_name == NULL ) {
13821373 Py_INCREF (Py_None );
13831374 PyTuple_SET_ITEM (retval , 0 , Py_None );
13841375 } else {
13851376 v = PyUnicode_FromString (cipher_name );
13861377 if (v == NULL )
1387- goto fail0 ;
1378+ goto fail ;
13881379 PyTuple_SET_ITEM (retval , 0 , v );
13891380 }
1390- cipher_protocol = (char * ) SSL_CIPHER_get_version (current );
1381+
1382+ cipher_protocol = SSL_CIPHER_get_version (cipher );
13911383 if (cipher_protocol == NULL ) {
13921384 Py_INCREF (Py_None );
13931385 PyTuple_SET_ITEM (retval , 1 , Py_None );
13941386 } else {
13951387 v = PyUnicode_FromString (cipher_protocol );
13961388 if (v == NULL )
1397- goto fail0 ;
1389+ goto fail ;
13981390 PyTuple_SET_ITEM (retval , 1 , v );
13991391 }
1400- v = PyLong_FromLong (SSL_CIPHER_get_bits (current , NULL ));
1392+
1393+ v = PyLong_FromLong (SSL_CIPHER_get_bits (cipher , NULL ));
14011394 if (v == NULL )
1402- goto fail0 ;
1395+ goto fail ;
14031396 PyTuple_SET_ITEM (retval , 2 , v );
1397+
14041398 return retval ;
14051399
1406- fail0 :
1400+ fail :
14071401 Py_DECREF (retval );
14081402 return NULL ;
14091403}
14101404
1405+ static PyObject * PySSL_shared_ciphers (PySSLSocket * self )
1406+ {
1407+ STACK_OF (SSL_CIPHER ) * ciphers ;
1408+ int i ;
1409+ PyObject * res ;
1410+
1411+ if (!self -> ssl -> session || !self -> ssl -> session -> ciphers )
1412+ Py_RETURN_NONE ;
1413+ ciphers = self -> ssl -> session -> ciphers ;
1414+ res = PyList_New (sk_SSL_CIPHER_num (ciphers ));
1415+ if (!res )
1416+ return NULL ;
1417+ for (i = 0 ; i < sk_SSL_CIPHER_num (ciphers ); i ++ ) {
1418+ PyObject * tup = cipher_to_tuple (sk_SSL_CIPHER_value (ciphers , i ));
1419+ if (!tup ) {
1420+ Py_DECREF (res );
1421+ return NULL ;
1422+ }
1423+ PyList_SET_ITEM (res , i , tup );
1424+ }
1425+ return res ;
1426+ }
1427+
1428+ static PyObject * PySSL_cipher (PySSLSocket * self )
1429+ {
1430+ const SSL_CIPHER * current ;
1431+
1432+ if (self -> ssl == NULL )
1433+ Py_RETURN_NONE ;
1434+ current = SSL_get_current_cipher (self -> ssl );
1435+ if (current == NULL )
1436+ Py_RETURN_NONE ;
1437+ return cipher_to_tuple (current );
1438+ }
1439+
14111440static PyObject * PySSL_version (PySSLSocket * self )
14121441{
14131442 const char * version ;
@@ -2019,6 +2048,7 @@ static PyMethodDef PySSLMethods[] = {
20192048 {"peer_certificate" , (PyCFunction )PySSL_peercert , METH_VARARGS ,
20202049 PySSL_peercert_doc },
20212050 {"cipher" , (PyCFunction )PySSL_cipher , METH_NOARGS },
2051+ {"shared_ciphers" , (PyCFunction )PySSL_shared_ciphers , METH_NOARGS },
20222052 {"version" , (PyCFunction )PySSL_version , METH_NOARGS },
20232053#ifdef OPENSSL_NPN_NEGOTIATED
20242054 {"selected_npn_protocol" , (PyCFunction )PySSL_selected_npn_protocol , METH_NOARGS },
0 commit comments