=== modified file 'OpenSSL/ssl/connection.c' --- OpenSSL/ssl/connection.c 2012-03-11 01:18:02 +0000 +++ OpenSSL/ssl/connection.c 2013-11-08 10:37:55 +0000 @@ -1396,6 +1396,96 @@ return Py_None; } +static char ssl_Connection_get_cipher_name_doc[] = "\n\ +Get actually used cipher of the established connection\n\ +\n\ +@return: The name of the currently used cipher\n\ +"; +static PyObject * +ssl_Connection_get_cipher_name(ssl_ConnectionObj *self, PyObject *args) +{ + const SSL_CIPHER *cipher; + + if (!PyArg_ParseTuple(args, ":get_cipher_name")) + return NULL; + + cipher = SSL_get_current_cipher(self->ssl); + if (cipher) + return PyText_FromString(SSL_CIPHER_get_name(cipher)); + + Py_INCREF(Py_None); + return Py_None; +} + +static char ssl_Connection_get_cipher_bits_doc[] = "\n\ +Get the number of secret/algorithm bits used of the established connection\n\ +\n\ +@return: The number of bits\n\ +"; +static PyObject * +ssl_Connection_get_cipher_bits(ssl_ConnectionObj *self, PyObject *args) +{ + const SSL_CIPHER *cipher; + + if (!PyArg_ParseTuple(args, ":get_cipher_bits")) + return NULL; + + cipher = SSL_get_current_cipher(self->ssl); + if (cipher) + return PyInt_FromLong(SSL_CIPHER_get_bits(cipher, NULL)); + + Py_INCREF(Py_None); + return Py_None; +} + +static char ssl_Connection_get_cipher_version_doc[] = "\n\ +Get protocol version of the established connection\n\ +\n\ +@return: The protocol version\n\ +"; +static PyObject * +ssl_Connection_get_cipher_version(ssl_ConnectionObj *self, PyObject *args) +{ + const SSL_CIPHER *cipher; + + if (!PyArg_ParseTuple(args, ":get_cipher_version")) + return NULL; + + cipher = SSL_get_current_cipher(self->ssl); + if (cipher) + return PyText_FromString(SSL_CIPHER_get_version(cipher)); + + Py_INCREF(Py_None); + return Py_None; +} + +static char ssl_Connection_get_cipher_description_doc[] = "\n\ +Get a textual description of the cipher used in the established connection\n\ +\n\ +@return: The cipher description\n\ +"; +static PyObject * +ssl_Connection_get_cipher_description(ssl_ConnectionObj *self, PyObject *args) +{ + const SSL_CIPHER *cipher; + + if (!PyArg_ParseTuple(args, ":get_cipher_description")) + return NULL; + + cipher = SSL_get_current_cipher(self->ssl); + if (cipher) + { + /* According to the manpage SSL_CIPHER_description description + buffer must be at least 128 bytes */ + char buffer[1024]; + return PyText_FromString( + SSL_CIPHER_description(cipher, buffer, sizeof(buffer))); + } + + Py_INCREF(Py_None); + return Py_None; +} + /* * Member methods in the Connection object * ADD_METHOD(name) expands to a correct PyMethodDef declaration @@ -1453,6 +1543,10 @@ ADD_METHOD(set_connect_state), ADD_METHOD(get_session), ADD_METHOD(set_session), + ADD_METHOD(get_cipher_name), + ADD_METHOD(get_cipher_bits), + ADD_METHOD(get_cipher_version), + ADD_METHOD(get_cipher_description), { NULL, NULL } }; #undef ADD_ALIAS === modified file 'doc/api/ssl.rst' --- doc/api/ssl.rst 2013-10-03 20:05:00 +0000 +++ doc/api/ssl.rst 2013-11-08 10:07:48 +0000 @@ -758,6 +758,30 @@ .. versionadded:: 0.14 +.. py:method:: Connection.get_cipher_name() + + Get the name of the currently used cipher, when no session has been + established return :py:obj:`None`. + + +.. py:method:: Connection.get_cipher_bits() + + Get the number of secret bits used for the connection, when no session + has been established return :py:obj:`None`. + + +.. py:method:: Connection.get_cipher_version() + + Get the protocol version used for the connection, when no session + has been established return :py:obj:`None`. + + +.. py:method:: Connection.get_cipher_description() + + Get a textual description of the cipher used for the connection, + when no session has been established return :py:obj:`None`. + + .. py:method:: Connection.set_session(session) Set a new SSL session (using a :py:class:`Session` instance) to be used by