summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Paul Calderone <exarkun@twistedmatrix.com>2014-03-30 10:45:00 -0400
committerJean-Paul Calderone <exarkun@twistedmatrix.com>2014-03-30 10:45:00 -0400
commit7c556ef6ab9e721b25f2704c306d0ef2dd66dae0 (patch)
tree13e17d7df7515f2953a9f913feb90bb5ba0a5196
parent416f4a1d5cfd3c76736ebd68f33c4f76af27568b (diff)
parentf31707592c248784b2605affa06303a2cb6eb694 (diff)
downloadpyopenssl-7c556ef6ab9e721b25f2704c306d0ef2dd66dae0.tar.gz
merge master
-rw-r--r--.travis.yml27
-rw-r--r--CONTRIBUTING.rst43
-rw-r--r--ChangeLog12
-rw-r--r--OpenSSL/SSL.py55
-rw-r--r--OpenSSL/test/test_ssl.py78
-rw-r--r--OpenSSL/test/test_tsafe.py24
-rw-r--r--OpenSSL/tsafe.py2
-rw-r--r--doc/api/ssl.rst30
-rw-r--r--setup.cfg3
9 files changed, 263 insertions, 11 deletions
diff --git a/.travis.yml b/.travis.yml
index 659677a..52f1032 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -11,5 +11,30 @@ python:
- "3.2"
- "3.3"
+matrix:
+ include:
+ - python: "2.6"
+ env: CRYPTOGRAPHY_GIT_MASTER=true
+ - python: "2.7"
+ env: CRYPTOGRAPHY_GIT_MASTER=true
+ - python: "3.2"
+ env: CRYPTOGRAPHY_GIT_MASTER=true
+ - python: "3.3"
+ env: CRYPTOGRAPHY_GIT_MASTER=true
+ - python: "pypy"
+ env: CRYPTOGRAPHY_GIT_MASTER=true
+ allow_failures:
+ - env: CRYPTOGRAPHY_GIT_MASTER=true
+
+before_install:
+ - if [ -n "$CRYPTOGRAPHY_GIT_MASTER" ]; then pip install git+https://github.com/pyca/cryptography.git;fi
+
+install:
+ # Install the wheel library explicitly here. It is not really a setup
+ # dependency. It is not an install dependency. It is only a dependency for
+ # the script directive below - because we want to exercise wheel building on
+ # travis.
+ - pip install wheel
+
script:
- - python setup.py test
+ - python setup.py bdist_wheel test
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
new file mode 100644
index 0000000..a4040e4
--- /dev/null
+++ b/CONTRIBUTING.rst
@@ -0,0 +1,43 @@
+Contributing
+============
+
+First of all, thank you for your interest in contributing to pyOpenSSL!
+
+Filing bug reports
+------------------
+
+Bug reports are very welcome.
+Please file them on the Github issue tracker.
+Good bug reports come with extensive descriptions of the error and how to reproduce it.
+Reporters are strongly encouraged to include an `short, self contained, correct example <http://www.sscce.org/>`_.
+
+Patches
+-------
+
+All patches to pyOpenSSL should be submitted in the form of pull requests to the main pyOpenSSL repository, ``pyca/pyopenssl``.
+These pull requests should satisfy the following properties:
+
+- The branch referenced should be a `feature branch`_ focusing on one particular improvement to pyOpenSSL.
+ Create different branches and different pull requests for unrelated features or bugfixes.
+- The branch referenced should have a distinctive name (in particular, please do not open pull requests for your ``master`` branch).
+- Code should follow `PEP 8`_, especially in the "do what code around you does" sense.
+ One notable way pyOpenSSL code differs, for example, is that there should be three empty lines between module-level elements,and two empty lines between class-level elements.
+ Methods and functions are named in ``snake_case``.
+ Follow OpenSSL naming for callables whenever possible is preferred.
+- Pull requests that introduce code must test all new behavior they introduce as well as for previously untested or poorly tested behavior that they touch.
+- Pull requests are not allowed to break existing tests.
+- Pull requests that introduce features or fix bugs should note those changes in the ``ChangeLog`` text file in the root of the repository.
+ They should also document the changes, both in docstrings and in the documentation in the ``doc/`` directory.
+
+Finally, pull requests must be reviewed before merging.
+This process mirrors the `cryptography code review process`_.
+Everyone can perform reviews; this is a very valuable way to contribute, and is highly encouraged.
+
+Pull requests are merged by members of the `pyopenssl-committers team <https://github.com/orgs/pyca/teams/pyopenssl-committers>`_.
+They should, of course, keep all the requirements detailed in this document as well as the pyca/cryptography merge requirements in mind.
+
+The final responsibility for the reviewing of merged code lies with the person merging it; since pyOpenSSL is obviously a sensitive project from a security perspective, so reviewers are strongly encouraged to take this review and merge process very seriously.
+
+.. _PEP 8: http://legacy.python.org/dev/peps/pep-0008/
+.. _cryptography code review process: https://cryptography.io/en/latest/development/reviewing-patches/
+.. _feature branch: http://nvie.com/posts/a-successful-git-branching-model/
diff --git a/ChangeLog b/ChangeLog
index c37fa8a..dec311f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,4 @@
-2014-03-28 Fedor Brunner <fedor.brunner@azet.sk>
+2014-03-30 Fedor Brunner <fedor.brunner@azet.sk>
* OpenSSL/ssl.py: Add ``get_finished``, ``get_peer_finished``
methods to ``Connection``. If you use these methods to
@@ -7,6 +7,16 @@
<https://www.ietf.org/mail-archive/web/tls/current/msg11337.html>
<https://secure-resumption.com/tlsauth.pdf>
+2014-03-29 Fedor Brunner <fedor.brunner@azet.sk>
+
+ * OpenSSL/SSL.py: Add ``get_cipher_name``, ``get_cipher_bits``,
+ and ``get_cipher_version`` to ``Connection``.
+
+2014-03-28 Jean-Paul Calderone <exarkun@twistedmatrix.com>
+
+ * OpenSSL/tsafe.py: Replace the use of ``apply`` (which has been
+ removed in Python 3) with the equivalent syntax.
+
2014-03-02 Stephen Holsapple <sholsapp@gmail.com>
* OpenSSL/crypto.py: Add ``get_extensions`` method to ``X509Req``.
diff --git a/OpenSSL/SSL.py b/OpenSSL/SSL.py
index 41d764d..6134a10 100644
--- a/OpenSSL/SSL.py
+++ b/OpenSSL/SSL.py
@@ -81,7 +81,10 @@ except AttributeError:
OP_NO_QUERY_MTU = _lib.SSL_OP_NO_QUERY_MTU
OP_COOKIE_EXCHANGE = _lib.SSL_OP_COOKIE_EXCHANGE
-OP_NO_TICKET = _lib.SSL_OP_NO_TICKET
+try:
+ OP_NO_TICKET = _lib.SSL_OP_NO_TICKET
+except AttributeError:
+ pass
OP_ALL = _lib.SSL_OP_ALL
@@ -1417,6 +1420,7 @@ class Connection(object):
if not result:
_raise_current_error()
+
def get_finished(self):
"""
Obtain latest Finished message that we sent.
@@ -1455,6 +1459,55 @@ class Connection(object):
else:
return _ffi.buffer(buf, result)[:]
+
+ def get_cipher_name(self):
+ """
+ Obtain the name of the currently used cipher.
+
+ :returns: The name of the currently used cipher or :py:obj:`None`
+ if no connection has been established.
+ :rtype: :py:class:`unicode` or :py:class:`NoneType`
+ """
+ cipher = _lib.SSL_get_current_cipher(self._ssl)
+ if cipher == _ffi.NULL:
+ return None
+ else:
+ name = _ffi.string(_lib.SSL_CIPHER_get_name(cipher))
+ return name.decode("utf-8")
+
+
+ def get_cipher_bits(self):
+ """
+ Obtain the number of secret bits of the currently used cipher.
+
+ :returns: The number of secret bits of the currently used cipher
+ or :py:obj:`None` if no connection has been established.
+ :rtype: :py:class:`int` or :py:class:`NoneType`
+ """
+ cipher = _lib.SSL_get_current_cipher(self._ssl)
+ if cipher == _ffi.NULL:
+ return None
+ else:
+ return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL)
+
+
+ def get_cipher_version(self):
+ """
+ Obtain the protocol version of the currently used cipher.
+
+ :returns: The protocol name of the currently used cipher
+ or :py:obj:`None` if no connection has been established.
+ :rtype: :py:class:`unicode` or :py:class:`NoneType`
+ """
+ cipher = _lib.SSL_get_current_cipher(self._ssl)
+ if cipher == _ffi.NULL:
+ return None
+ else:
+ version =_ffi.string(_lib.SSL_CIPHER_get_version(cipher))
+ return version.decode("utf-8")
+
+
+
ConnectionType = Connection
# This is similar to the initialization calls at the end of OpenSSL/crypto.py
diff --git a/OpenSSL/test/test_ssl.py b/OpenSSL/test/test_ssl.py
index 5af8d86..6c125c1 100644
--- a/OpenSSL/test/test_ssl.py
+++ b/OpenSSL/test/test_ssl.py
@@ -14,7 +14,7 @@ from os.path import join
from unittest import main
from weakref import ref
-from six import PY3, u
+from six import PY3, text_type, u
from OpenSSL.crypto import TYPE_RSA, FILETYPE_PEM
from OpenSSL.crypto import PKey, X509, X509Extension, X509Store
@@ -1990,6 +1990,82 @@ class ConnectionTests(TestCase, _LoopbackMixin):
self.assertEqual(server.get_finished(), client.get_peer_finished())
self.assertEqual(client.get_finished(), server.get_peer_finished())
+ def test_get_cipher_name_before_connect(self):
+ """
+ :py:obj:`Connection.get_cipher_name` returns :py:obj:`None`
+ if no connection has been established.
+ """
+ ctx = Context(TLSv1_METHOD)
+ conn = Connection(ctx, None)
+ self.assertIdentical(conn.get_cipher_name(), None)
+
+
+ def test_get_cipher_name(self):
+ """
+ :py:obj:`Connection.get_cipher_name` returns a :py:class:`unicode`
+ string giving the name of the currently used cipher.
+ """
+ server, client = self._loopback()
+ server_cipher_name, client_cipher_name = \
+ server.get_cipher_name(), client.get_cipher_name()
+
+ self.assertIsInstance(server_cipher_name, text_type)
+ self.assertIsInstance(client_cipher_name, text_type)
+
+ self.assertEqual(server_cipher_name, client_cipher_name)
+
+
+ def test_get_cipher_version_before_connect(self):
+ """
+ :py:obj:`Connection.get_cipher_version` returns :py:obj:`None`
+ if no connection has been established.
+ """
+ ctx = Context(TLSv1_METHOD)
+ conn = Connection(ctx, None)
+ self.assertIdentical(conn.get_cipher_version(), None)
+
+
+ def test_get_cipher_version(self):
+ """
+ :py:obj:`Connection.get_cipher_version` returns a :py:class:`unicode`
+ string giving the protocol name of the currently used cipher.
+ """
+ server, client = self._loopback()
+ server_cipher_version, client_cipher_version = \
+ server.get_cipher_version(), client.get_cipher_version()
+
+ self.assertIsInstance(server_cipher_version, text_type)
+ self.assertIsInstance(client_cipher_version, text_type)
+
+ self.assertEqual(server_cipher_version, client_cipher_version)
+
+
+ def test_get_cipher_bits_before_connect(self):
+ """
+ :py:obj:`Connection.get_cipher_bits` returns :py:obj:`None`
+ if no connection has been established.
+ """
+ ctx = Context(TLSv1_METHOD)
+ conn = Connection(ctx, None)
+ self.assertIdentical(conn.get_cipher_bits(), None)
+
+
+ def test_get_cipher_bits(self):
+ """
+ :py:obj:`Connection.get_cipher_bits` returns the number of secret bits of the currently
+ used cipher.
+ """
+ server, client = self._loopback()
+ server_cipher_bits, client_cipher_bits = \
+ server.get_cipher_bits(), client.get_cipher_bits()
+
+ self.assertIsInstance(server_cipher_bits, int)
+ self.assertIsInstance(client_cipher_bits, int)
+
+ self.assertEqual(server_cipher_bits, client_cipher_bits)
+
+
+
class ConnectionGetCipherListTests(TestCase):
"""
Tests for :py:obj:`Connection.get_cipher_list`.
diff --git a/OpenSSL/test/test_tsafe.py b/OpenSSL/test/test_tsafe.py
new file mode 100644
index 0000000..0456957
--- /dev/null
+++ b/OpenSSL/test/test_tsafe.py
@@ -0,0 +1,24 @@
+# Copyright (C) Jean-Paul Calderone
+# See LICENSE for details.
+
+"""
+Unit tests for :py:obj:`OpenSSL.tsafe`.
+"""
+
+from OpenSSL.SSL import TLSv1_METHOD, Context
+from OpenSSL.tsafe import Connection
+from OpenSSL.test.util import TestCase
+
+
+class ConnectionTest(TestCase):
+ """
+ Tests for :py:obj:`OpenSSL.tsafe.Connection`.
+ """
+ def test_instantiation(self):
+ """
+ :py:obj:`OpenSSL.tsafe.Connection` can be instantiated.
+ """
+ # The following line should not throw an error. This isn't an ideal
+ # test. It would be great to refactor the other Connection tests so
+ # they could automatically be applied to this class too.
+ Connection(Context(TLSv1_METHOD), None)
diff --git a/OpenSSL/tsafe.py b/OpenSSL/tsafe.py
index 9d7ad2f..3a9c710 100644
--- a/OpenSSL/tsafe.py
+++ b/OpenSSL/tsafe.py
@@ -8,7 +8,7 @@ del threading
class Connection:
def __init__(self, *args):
- self._ssl_conn = apply(_ssl.Connection, args)
+ self._ssl_conn = _ssl.Connection(*args)
self._lock = _RLock()
for f in ('get_context', 'pending', 'send', 'write', 'recv', 'read',
diff --git a/doc/api/ssl.rst b/doc/api/ssl.rst
index df21a1d..dfeb158 100644
--- a/doc/api/ssl.rst
+++ b/doc/api/ssl.rst
@@ -83,12 +83,6 @@ Context, Connection.
:py:const:`OP_NO_*` constant may be undefined.
-.. py:data:: MODE_NO_COMPRESSION
-
- Constant used with :py:meth:`set_mode` of Context objects to disable
- automatic compression of application traffic.
-
-
.. py:data:: SSLEAY_VERSION
SSLEAY_CFLAGS
SSLEAY_BUILT_ON
@@ -765,6 +759,7 @@ Connection objects have the following methods:
.. versionadded:: 0.14
+
.. py:method:: Connection.get_finished()
Obtain latest TLS Finished message that we sent, or :py:obj:`None` if
@@ -772,6 +767,7 @@ Connection objects have the following methods:
.. versionadded:: 0.15
+
.. py:method:: Connection.get_peer_finished()
Obtain latest TLS Finished message that we expected from peer, or
@@ -779,6 +775,28 @@ Connection objects have the following methods:
.. versionadded:: 0.15
+
+.. py:method:: Connection.get_cipher_name()
+
+ Obtain the name of the currently used cipher.
+
+ .. versionadded:: 0.15
+
+
+.. py:method:: Connection.get_cipher_bits()
+
+ Obtain the number of secret bits of the currently used cipher.
+
+ .. versionadded:: 0.15
+
+
+.. py:method:: Connection.get_cipher_version()
+
+ Obtain the protocol name of the currently used cipher.
+
+ .. versionadded:: 0.15
+
+
.. Rubric:: Footnotes
.. [#connection-context-socket] Actually, all that is required is an object that
diff --git a/setup.cfg b/setup.cfg
index 92e6568..ec1218d 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,6 +1,9 @@
[sdist]
force_manifest=1
+[wheel]
+universal = 1
+
# bdist_rpm settings contributed by Mihai Ibanescu <misa@redhat.com>
[bdist_rpm]
release = 1