summaryrefslogtreecommitdiff
path: root/OpenSSL/test/test_ssl.py
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSSL/test/test_ssl.py')
-rw-r--r--OpenSSL/test/test_ssl.py648
1 files changed, 486 insertions, 162 deletions
diff --git a/OpenSSL/test/test_ssl.py b/OpenSSL/test/test_ssl.py
index 2ab67fd..3e4e3da 100644
--- a/OpenSSL/test/test_ssl.py
+++ b/OpenSSL/test/test_ssl.py
@@ -2,7 +2,7 @@
# See LICENSE for details.
"""
-Unit tests for L{OpenSSL.SSL}.
+Unit tests for :py:obj:`OpenSSL.SSL`.
"""
from gc import collect
@@ -10,7 +10,7 @@ from errno import ECONNREFUSED, EINPROGRESS, EWOULDBLOCK
from sys import platform, version_info
from socket import error, socket
from os import makedirs
-from os.path import join
+from os.path import join, dirname
from unittest import main
from weakref import ref
@@ -26,9 +26,16 @@ from OpenSSL.SSL import SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, TLSv1_METHOD
from OpenSSL.SSL import OP_NO_SSLv2, OP_NO_SSLv3, OP_SINGLE_DH_USE
from OpenSSL.SSL import (
VERIFY_PEER, VERIFY_FAIL_IF_NO_PEER_CERT, VERIFY_CLIENT_ONCE, VERIFY_NONE)
+
+from OpenSSL.SSL import (
+ SESS_CACHE_OFF, SESS_CACHE_CLIENT, SESS_CACHE_SERVER, SESS_CACHE_BOTH,
+ SESS_CACHE_NO_AUTO_CLEAR, SESS_CACHE_NO_INTERNAL_LOOKUP,
+ SESS_CACHE_NO_INTERNAL_STORE, SESS_CACHE_NO_INTERNAL)
+
from OpenSSL.SSL import (
Error, SysCallError, WantReadError, ZeroReturnError, SSLeay_version)
-from OpenSSL.SSL import Context, ContextType, Connection, ConnectionType
+from OpenSSL.SSL import (
+ Context, ContextType, Session, Connection, ConnectionType)
from OpenSSL.test.util import TestCase, bytes, b
from OpenSSL.test.test_crypto import (
@@ -50,6 +57,16 @@ try:
except ImportError:
OP_NO_TICKET = None
+try:
+ from OpenSSL.SSL import OP_NO_COMPRESSION
+except ImportError:
+ OP_NO_COMPRESSION = None
+
+try:
+ from OpenSSL.SSL import MODE_RELEASE_BUFFERS
+except ImportError:
+ MODE_RELEASE_BUFFERS = None
+
from OpenSSL.SSL import (
SSL_ST_CONNECT, SSL_ST_ACCEPT, SSL_ST_MASK, SSL_ST_INIT, SSL_ST_BEFORE,
SSL_ST_OK, SSL_ST_RENEGOTIATE,
@@ -172,16 +189,30 @@ class _LoopbackMixin:
Helper mixin which defines methods for creating a connected socket pair and
for forcing two connected SSL sockets to talk to each other via memory BIOs.
"""
- def _loopback(self):
- (server, client) = socket_pair()
+ def _loopbackClientFactory(self, socket):
+ client = Connection(Context(TLSv1_METHOD), socket)
+ client.set_connect_state()
+ return client
+
+ def _loopbackServerFactory(self, socket):
ctx = Context(TLSv1_METHOD)
ctx.use_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
ctx.use_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
- server = Connection(ctx, server)
+ server = Connection(ctx, socket)
server.set_accept_state()
- client = Connection(Context(TLSv1_METHOD), client)
- client.set_connect_state()
+ return server
+
+
+ def _loopback(self, serverFactory=None, clientFactory=None):
+ if serverFactory is None:
+ serverFactory = self._loopbackServerFactory
+ if clientFactory is None:
+ clientFactory = self._loopbackClientFactory
+
+ (server, client) = socket_pair()
+ server = serverFactory(server)
+ client = clientFactory(client)
handshake(client, server)
@@ -192,10 +223,10 @@ class _LoopbackMixin:
def _interactInMemory(self, client_conn, server_conn):
"""
- Try to read application bytes from each of the two L{Connection}
+ Try to read application bytes from each of the two :py:obj:`Connection`
objects. Copy bytes back and forth between their send/receive buffers
for as long as there is anything to copy. When there is nothing more
- to copy, return C{None}. If one of them actually manages to deliver
+ to copy, return :py:obj:`None`. If one of them actually manages to deliver
some application bytes, return a two-tuple of the connection from which
the bytes were read and the bytes themselves.
"""
@@ -241,12 +272,12 @@ class _LoopbackMixin:
class VersionTests(TestCase):
"""
Tests for version information exposed by
- L{OpenSSL.SSL.SSLeay_version} and
- L{OpenSSL.SSL.OPENSSL_VERSION_NUMBER}.
+ :py:obj:`OpenSSL.SSL.SSLeay_version` and
+ :py:obj:`OpenSSL.SSL.OPENSSL_VERSION_NUMBER`.
"""
def test_OPENSSL_VERSION_NUMBER(self):
"""
- L{OPENSSL_VERSION_NUMBER} is an integer with status in the low
+ :py:obj:`OPENSSL_VERSION_NUMBER` is an integer with status in the low
byte and the patch, fix, minor, and major versions in the
nibbles above that.
"""
@@ -255,7 +286,7 @@ class VersionTests(TestCase):
def test_SSLeay_version(self):
"""
- L{SSLeay_version} takes a version type indicator and returns
+ :py:obj:`SSLeay_version` takes a version type indicator and returns
one of a number of version strings based on that indicator.
"""
versions = {}
@@ -270,19 +301,19 @@ class VersionTests(TestCase):
class ContextTests(TestCase, _LoopbackMixin):
"""
- Unit tests for L{OpenSSL.SSL.Context}.
+ Unit tests for :py:obj:`OpenSSL.SSL.Context`.
"""
def test_method(self):
"""
- L{Context} can be instantiated with one of L{SSLv2_METHOD},
- L{SSLv3_METHOD}, L{SSLv23_METHOD}, or L{TLSv1_METHOD}.
+ :py:obj:`Context` can be instantiated with one of :py:obj:`SSLv2_METHOD`,
+ :py:obj:`SSLv3_METHOD`, :py:obj:`SSLv23_METHOD`, or :py:obj:`TLSv1_METHOD`.
"""
for meth in [SSLv3_METHOD, SSLv23_METHOD, TLSv1_METHOD]:
Context(meth)
try:
Context(SSLv2_METHOD)
- except ValueError:
+ except (Error, ValueError):
# Some versions of OpenSSL have SSLv2, some don't.
# Difficult to say in advance.
pass
@@ -293,7 +324,7 @@ class ContextTests(TestCase, _LoopbackMixin):
def test_type(self):
"""
- L{Context} and L{ContextType} refer to the same type object and can be
+ :py:obj:`Context` and :py:obj:`ContextType` refer to the same type object and can be
used to create instances of that type.
"""
self.assertIdentical(Context, ContextType)
@@ -302,7 +333,7 @@ class ContextTests(TestCase, _LoopbackMixin):
def test_use_privatekey(self):
"""
- L{Context.use_privatekey} takes an L{OpenSSL.crypto.PKey} instance.
+ :py:obj:`Context.use_privatekey` takes an :py:obj:`OpenSSL.crypto.PKey` instance.
"""
key = PKey()
key.generate_key(TYPE_RSA, 128)
@@ -313,7 +344,7 @@ class ContextTests(TestCase, _LoopbackMixin):
def test_set_app_data_wrong_args(self):
"""
- L{Context.set_app_data} raises L{TypeError} if called with other than
+ :py:obj:`Context.set_app_data` raises :py:obj:`TypeError` if called with other than
one argument.
"""
context = Context(TLSv1_METHOD)
@@ -323,7 +354,7 @@ class ContextTests(TestCase, _LoopbackMixin):
def test_get_app_data_wrong_args(self):
"""
- L{Context.get_app_data} raises L{TypeError} if called with any
+ :py:obj:`Context.get_app_data` raises :py:obj:`TypeError` if called with any
arguments.
"""
context = Context(TLSv1_METHOD)
@@ -332,8 +363,8 @@ class ContextTests(TestCase, _LoopbackMixin):
def test_app_data(self):
"""
- L{Context.set_app_data} stores an object for later retrieval using
- L{Context.get_app_data}.
+ :py:obj:`Context.set_app_data` stores an object for later retrieval using
+ :py:obj:`Context.get_app_data`.
"""
app_data = object()
context = Context(TLSv1_METHOD)
@@ -343,8 +374,8 @@ class ContextTests(TestCase, _LoopbackMixin):
def test_set_options_wrong_args(self):
"""
- L{Context.set_options} raises L{TypeError} if called with the wrong
- number of arguments or a non-C{int} argument.
+ :py:obj:`Context.set_options` raises :py:obj:`TypeError` if called with the wrong
+ number of arguments or a non-:py:obj:`int` argument.
"""
context = Context(TLSv1_METHOD)
self.assertRaises(TypeError, context.set_options)
@@ -352,10 +383,34 @@ class ContextTests(TestCase, _LoopbackMixin):
self.assertRaises(TypeError, context.set_options, 1, None)
+ def test_set_mode_wrong_args(self):
+ """
+ :py:obj:`Context.set`mode} raises :py:obj:`TypeError` if called with the wrong
+ number of arguments or a non-:py:obj:`int` argument.
+ """
+ context = Context(TLSv1_METHOD)
+ self.assertRaises(TypeError, context.set_mode)
+ self.assertRaises(TypeError, context.set_mode, None)
+ self.assertRaises(TypeError, context.set_mode, 1, None)
+
+
+ if MODE_RELEASE_BUFFERS is not None:
+ def test_set_mode(self):
+ """
+ :py:obj:`Context.set_mode` accepts a mode bitvector and returns the newly
+ set mode.
+ """
+ context = Context(TLSv1_METHOD)
+ self.assertTrue(
+ MODE_RELEASE_BUFFERS & context.set_mode(MODE_RELEASE_BUFFERS))
+ else:
+ "MODE_RELEASE_BUFFERS unavailable - OpenSSL version may be too old"
+
+
def test_set_timeout_wrong_args(self):
"""
- L{Context.set_timeout} raises L{TypeError} if called with the wrong
- number of arguments or a non-C{int} argument.
+ :py:obj:`Context.set_timeout` raises :py:obj:`TypeError` if called with the wrong
+ number of arguments or a non-:py:obj:`int` argument.
"""
context = Context(TLSv1_METHOD)
self.assertRaises(TypeError, context.set_timeout)
@@ -365,7 +420,7 @@ class ContextTests(TestCase, _LoopbackMixin):
def test_get_timeout_wrong_args(self):
"""
- L{Context.get_timeout} raises L{TypeError} if called with any arguments.
+ :py:obj:`Context.get_timeout` raises :py:obj:`TypeError` if called with any arguments.
"""
context = Context(TLSv1_METHOD)
self.assertRaises(TypeError, context.get_timeout, None)
@@ -373,8 +428,8 @@ class ContextTests(TestCase, _LoopbackMixin):
def test_timeout(self):
"""
- L{Context.set_timeout} sets the session timeout for all connections
- created using the context object. L{Context.get_timeout} retrieves this
+ :py:obj:`Context.set_timeout` sets the session timeout for all connections
+ created using the context object. :py:obj:`Context.get_timeout` retrieves this
value.
"""
context = Context(TLSv1_METHOD)
@@ -384,8 +439,8 @@ class ContextTests(TestCase, _LoopbackMixin):
def test_set_verify_depth_wrong_args(self):
"""
- L{Context.set_verify_depth} raises L{TypeError} if called with the wrong
- number of arguments or a non-C{int} argument.
+ :py:obj:`Context.set_verify_depth` raises :py:obj:`TypeError` if called with the wrong
+ number of arguments or a non-:py:obj:`int` argument.
"""
context = Context(TLSv1_METHOD)
self.assertRaises(TypeError, context.set_verify_depth)
@@ -395,7 +450,7 @@ class ContextTests(TestCase, _LoopbackMixin):
def test_get_verify_depth_wrong_args(self):
"""
- L{Context.get_verify_depth} raises L{TypeError} if called with any arguments.
+ :py:obj:`Context.get_verify_depth` raises :py:obj:`TypeError` if called with any arguments.
"""
context = Context(TLSv1_METHOD)
self.assertRaises(TypeError, context.get_verify_depth, None)
@@ -403,9 +458,9 @@ class ContextTests(TestCase, _LoopbackMixin):
def test_verify_depth(self):
"""
- L{Context.set_verify_depth} sets the number of certificates in a chain
+ :py:obj:`Context.set_verify_depth` sets the number of certificates in a chain
to follow before giving up. The value can be retrieved with
- L{Context.get_verify_depth}.
+ :py:obj:`Context.get_verify_depth`.
"""
context = Context(TLSv1_METHOD)
context.set_verify_depth(11)
@@ -429,7 +484,7 @@ class ContextTests(TestCase, _LoopbackMixin):
def test_set_passwd_cb_wrong_args(self):
"""
- L{Context.set_passwd_cb} raises L{TypeError} if called with the
+ :py:obj:`Context.set_passwd_cb` raises :py:obj:`TypeError` if called with the
wrong arguments or with a non-callable first argument.
"""
context = Context(TLSv1_METHOD)
@@ -440,7 +495,7 @@ class ContextTests(TestCase, _LoopbackMixin):
def test_set_passwd_cb(self):
"""
- L{Context.set_passwd_cb} accepts a callable which will be invoked when
+ :py:obj:`Context.set_passwd_cb` accepts a callable which will be invoked when
a private key is loaded from an encrypted PEM.
"""
passphrase = b("foobar")
@@ -460,7 +515,7 @@ class ContextTests(TestCase, _LoopbackMixin):
def test_passwd_callback_exception(self):
"""
- L{Context.use_privatekey_file} propagates any exception raised by the
+ :py:obj:`Context.use_privatekey_file` propagates any exception raised by the
passphrase callback.
"""
pemFile = self._write_encrypted_pem(b("monkeys are nice"))
@@ -474,7 +529,7 @@ class ContextTests(TestCase, _LoopbackMixin):
def test_passwd_callback_false(self):
"""
- L{Context.use_privatekey_file} raises L{OpenSSL.SSL.Error} if the
+ :py:obj:`Context.use_privatekey_file` raises :py:obj:`OpenSSL.SSL.Error` if the
passphrase callback returns a false value.
"""
pemFile = self._write_encrypted_pem(b("monkeys are nice"))
@@ -488,7 +543,7 @@ class ContextTests(TestCase, _LoopbackMixin):
def test_passwd_callback_non_string(self):
"""
- L{Context.use_privatekey_file} raises L{OpenSSL.SSL.Error} if the
+ :py:obj:`Context.use_privatekey_file` raises :py:obj:`OpenSSL.SSL.Error` if the
passphrase callback returns a true non-string value.
"""
pemFile = self._write_encrypted_pem(b("monkeys are nice"))
@@ -521,7 +576,7 @@ class ContextTests(TestCase, _LoopbackMixin):
def test_set_info_callback(self):
"""
- L{Context.set_info_callback} accepts a callable which will be invoked
+ :py:obj:`Context.set_info_callback` accepts a callable which will be invoked
when certain information about an SSL connection is available.
"""
(server, client) = socket_pair()
@@ -556,8 +611,8 @@ class ContextTests(TestCase, _LoopbackMixin):
def _load_verify_locations_test(self, *args):
"""
Create a client context which will verify the peer certificate and call
- its C{load_verify_locations} method with C{*args}. Then connect it to a
- server and ensure that the handshake succeeds.
+ its :py:obj:`load_verify_locations` method with the given arguments.
+ Then connect it to a server and ensure that the handshake succeeds.
"""
(server, client) = socket_pair()
@@ -593,7 +648,7 @@ class ContextTests(TestCase, _LoopbackMixin):
def test_load_verify_file(self):
"""
- L{Context.load_verify_locations} accepts a file name and uses the
+ :py:obj:`Context.load_verify_locations` accepts a file name and uses the
certificates within for verification purposes.
"""
cafile = self.mktemp()
@@ -606,7 +661,7 @@ class ContextTests(TestCase, _LoopbackMixin):
def test_load_verify_invalid_file(self):
"""
- L{Context.load_verify_locations} raises L{Error} when passed a
+ :py:obj:`Context.load_verify_locations` raises :py:obj:`Error` when passed a
non-existent cafile.
"""
clientContext = Context(TLSv1_METHOD)
@@ -616,7 +671,7 @@ class ContextTests(TestCase, _LoopbackMixin):
def test_load_verify_directory(self):
"""
- L{Context.load_verify_locations} accepts a directory name and uses
+ :py:obj:`Context.load_verify_locations` accepts a directory name and uses
the certificates within for verification purposes.
"""
capath = self.mktemp()
@@ -635,8 +690,8 @@ class ContextTests(TestCase, _LoopbackMixin):
def test_load_verify_locations_wrong_args(self):
"""
- L{Context.load_verify_locations} raises L{TypeError} if called with
- the wrong number of arguments or with non-C{str} arguments.
+ :py:obj:`Context.load_verify_locations` raises :py:obj:`TypeError` if called with
+ the wrong number of arguments or with non-:py:obj:`str` arguments.
"""
context = Context(TLSv1_METHOD)
self.assertRaises(TypeError, context.load_verify_locations)
@@ -651,7 +706,7 @@ class ContextTests(TestCase, _LoopbackMixin):
else:
def test_set_default_verify_paths(self):
"""
- L{Context.set_default_verify_paths} causes the platform-specific CA
+ :py:obj:`Context.set_default_verify_paths` causes the platform-specific CA
certificate locations to be used for verification purposes.
"""
# Testing this requires a server with a certificate signed by one of
@@ -680,8 +735,8 @@ class ContextTests(TestCase, _LoopbackMixin):
def test_set_default_verify_paths_signature(self):
"""
- L{Context.set_default_verify_paths} takes no arguments and raises
- L{TypeError} if given any.
+ :py:obj:`Context.set_default_verify_paths` takes no arguments and raises
+ :py:obj:`TypeError` if given any.
"""
context = Context(TLSv1_METHOD)
self.assertRaises(TypeError, context.set_default_verify_paths, None)
@@ -691,9 +746,9 @@ class ContextTests(TestCase, _LoopbackMixin):
def test_add_extra_chain_cert_invalid_cert(self):
"""
- L{Context.add_extra_chain_cert} raises L{TypeError} if called with
+ :py:obj:`Context.add_extra_chain_cert` raises :py:obj:`TypeError` if called with
other than one argument or if called with an object which is not an
- instance of L{X509}.
+ instance of :py:obj:`X509`.
"""
context = Context(TLSv1_METHOD)
self.assertRaises(TypeError, context.add_extra_chain_cert)
@@ -726,10 +781,10 @@ class ContextTests(TestCase, _LoopbackMixin):
def test_add_extra_chain_cert(self):
"""
- L{Context.add_extra_chain_cert} accepts an L{X509} instance to add to
+ :py:obj:`Context.add_extra_chain_cert` accepts an :py:obj:`X509` instance to add to
the certificate chain.
- See L{_create_certificate_chain} for the details of the certificate
+ See :py:obj:`_create_certificate_chain` for the details of the certificate
chain tested.
The chain is tested by starting a server with scert and connecting
@@ -770,7 +825,7 @@ class ContextTests(TestCase, _LoopbackMixin):
def test_use_certificate_chain_file(self):
"""
- L{Context.use_certificate_chain_file} reads a certificate chain from
+ :py:obj:`Context.use_certificate_chain_file` reads a certificate chain from
the specified file.
The chain is tested by starting a server with scert and connecting
@@ -809,7 +864,7 @@ class ContextTests(TestCase, _LoopbackMixin):
def test_get_verify_mode_wrong_args(self):
"""
- L{Context.get_verify_mode} raises L{TypeError} if called with any
+ :py:obj:`Context.get_verify_mode` raises :py:obj:`TypeError` if called with any
arguments.
"""
context = Context(TLSv1_METHOD)
@@ -818,8 +873,8 @@ class ContextTests(TestCase, _LoopbackMixin):
def test_get_verify_mode(self):
"""
- L{Context.get_verify_mode} returns the verify mode flags previously
- passed to L{Context.set_verify}.
+ :py:obj:`Context.get_verify_mode` returns the verify mode flags previously
+ passed to :py:obj:`Context.set_verify`.
"""
context = Context(TLSv1_METHOD)
self.assertEquals(context.get_verify_mode(), 0)
@@ -831,8 +886,8 @@ class ContextTests(TestCase, _LoopbackMixin):
def test_load_tmp_dh_wrong_args(self):
"""
- L{Context.load_tmp_dh} raises L{TypeError} if called with the wrong
- number of arguments or with a non-C{str} argument.
+ :py:obj:`Context.load_tmp_dh` raises :py:obj:`TypeError` if called with the wrong
+ number of arguments or with a non-:py:obj:`str` argument.
"""
context = Context(TLSv1_METHOD)
self.assertRaises(TypeError, context.load_tmp_dh)
@@ -842,7 +897,7 @@ class ContextTests(TestCase, _LoopbackMixin):
def test_load_tmp_dh_missing_file(self):
"""
- L{Context.load_tmp_dh} raises L{OpenSSL.SSL.Error} if the specified file
+ :py:obj:`Context.load_tmp_dh` raises :py:obj:`OpenSSL.SSL.Error` if the specified file
does not exist.
"""
context = Context(TLSv1_METHOD)
@@ -851,7 +906,7 @@ class ContextTests(TestCase, _LoopbackMixin):
def test_load_tmp_dh(self):
"""
- L{Context.load_tmp_dh} loads Diffie-Hellman parameters from the
+ :py:obj:`Context.load_tmp_dh` loads Diffie-Hellman parameters from the
specified file.
"""
context = Context(TLSv1_METHOD)
@@ -865,7 +920,7 @@ class ContextTests(TestCase, _LoopbackMixin):
def test_set_cipher_list(self):
"""
- L{Context.set_cipher_list} accepts a C{str} naming the ciphers which
+ :py:obj:`Context.set_cipher_list` accepts a :py:obj:`str` naming the ciphers which
connections created with the context object will be able to choose from.
"""
context = Context(TLSv1_METHOD)
@@ -874,15 +929,46 @@ class ContextTests(TestCase, _LoopbackMixin):
self.assertEquals(conn.get_cipher_list(), ["EXP-RC4-MD5"])
+ def test_set_session_cache_mode_wrong_args(self):
+ """
+ L{Context.set_session_cache_mode} raises L{TypeError} if called with
+ other than one integer argument.
+ """
+ context = Context(TLSv1_METHOD)
+ self.assertRaises(TypeError, context.set_session_cache_mode)
+ self.assertRaises(TypeError, context.set_session_cache_mode, object())
+
+
+ def test_get_session_cache_mode_wrong_args(self):
+ """
+ L{Context.get_session_cache_mode} raises L{TypeError} if called with any
+ arguments.
+ """
+ context = Context(TLSv1_METHOD)
+ self.assertRaises(TypeError, context.get_session_cache_mode, 1)
+
+
+ def test_session_cache_mode(self):
+ """
+ L{Context.set_session_cache_mode} specifies how sessions are cached.
+ The setting can be retrieved via L{Context.get_session_cache_mode}.
+ """
+ context = Context(TLSv1_METHOD)
+ old = context.set_session_cache_mode(SESS_CACHE_OFF)
+ off = context.set_session_cache_mode(SESS_CACHE_BOTH)
+ self.assertEqual(SESS_CACHE_OFF, off)
+ self.assertEqual(SESS_CACHE_BOTH, context.get_session_cache_mode())
+
+
class ServerNameCallbackTests(TestCase, _LoopbackMixin):
"""
- Tests for L{Context.set_tlsext_servername_callback} and its interaction with
- L{Connection}.
+ Tests for :py:obj:`Context.set_tlsext_servername_callback` and its interaction with
+ :py:obj:`Connection`.
"""
def test_wrong_args(self):
"""
- L{Context.set_tlsext_servername_callback} raises L{TypeError} if called
+ :py:obj:`Context.set_tlsext_servername_callback` raises :py:obj:`TypeError` if called
with other than one argument.
"""
context = Context(TLSv1_METHOD)
@@ -892,7 +978,7 @@ class ServerNameCallbackTests(TestCase, _LoopbackMixin):
def test_old_callback_forgotten(self):
"""
- If L{Context.set_tlsext_servername_callback} is used to specify a new
+ If :py:obj:`Context.set_tlsext_servername_callback` is used to specify a new
callback, the one it replaces is dereferenced.
"""
def callback(connection):
@@ -915,8 +1001,8 @@ class ServerNameCallbackTests(TestCase, _LoopbackMixin):
def test_no_servername(self):
"""
When a client specifies no server name, the callback passed to
- L{Context.set_tlsext_servername_callback} is invoked and the result of
- L{Connection.get_servername} is C{None}.
+ :py:obj:`Context.set_tlsext_servername_callback` is invoked and the result of
+ :py:obj:`Connection.get_servername` is :py:obj:`None`.
"""
args = []
def servername(conn):
@@ -948,8 +1034,8 @@ class ServerNameCallbackTests(TestCase, _LoopbackMixin):
def test_servername(self):
"""
When a client specifies a server name in its hello message, the callback
- passed to L{Contexts.set_tlsext_servername_callback} is invoked and the
- result of L{Connection.get_servername} is that server name.
+ passed to :py:obj:`Contexts.set_tlsext_servername_callback` is invoked and the
+ result of :py:obj:`Connection.get_servername` is that server name.
"""
args = []
def servername(conn):
@@ -975,9 +1061,33 @@ class ServerNameCallbackTests(TestCase, _LoopbackMixin):
+class SessionTests(TestCase):
+ """
+ Unit tests for :py:obj:`OpenSSL.SSL.Session`.
+ """
+ def test_construction(self):
+ """
+ :py:class:`Session` can be constructed with no arguments, creating a new
+ instance of that type.
+ """
+ new_session = Session()
+ self.assertTrue(isinstance(new_session, Session))
+
+
+ def test_construction_wrong_args(self):
+ """
+ If any arguments are passed to :py:class:`Session`, :py:obj:`TypeError`
+ is raised.
+ """
+ self.assertRaises(TypeError, Session, 123)
+ self.assertRaises(TypeError, Session, "hello")
+ self.assertRaises(TypeError, Session, object())
+
+
+
class ConnectionTests(TestCase, _LoopbackMixin):
"""
- Unit tests for L{OpenSSL.SSL.Connection}.
+ Unit tests for :py:obj:`OpenSSL.SSL.Connection`.
"""
# XXX want_write
# XXX want_read
@@ -999,7 +1109,7 @@ class ConnectionTests(TestCase, _LoopbackMixin):
def test_type(self):
"""
- L{Connection} and L{ConnectionType} refer to the same type object and
+ :py:obj:`Connection` and :py:obj:`ConnectionType` refer to the same type object and
can be used to create instances of that type.
"""
self.assertIdentical(Connection, ConnectionType)
@@ -1009,8 +1119,8 @@ class ConnectionTests(TestCase, _LoopbackMixin):
def test_get_context(self):
"""
- L{Connection.get_context} returns the L{Context} instance used to
- construct the L{Connection} instance.
+ :py:obj:`Connection.get_context` returns the :py:obj:`Context` instance used to
+ construct the :py:obj:`Connection` instance.
"""
context = Context(TLSv1_METHOD)
connection = Connection(context, None)
@@ -1019,7 +1129,7 @@ class ConnectionTests(TestCase, _LoopbackMixin):
def test_get_context_wrong_args(self):
"""
- L{Connection.get_context} raises L{TypeError} if called with any
+ :py:obj:`Connection.get_context` raises :py:obj:`TypeError` if called with any
arguments.
"""
connection = Connection(Context(TLSv1_METHOD), None)
@@ -1028,8 +1138,8 @@ class ConnectionTests(TestCase, _LoopbackMixin):
def test_set_context_wrong_args(self):
"""
- L{Connection.set_context} raises L{TypeError} if called with a
- non-L{Context} instance argument or with any number of arguments other
+ :py:obj:`Connection.set_context` raises :py:obj:`TypeError` if called with a
+ non-:py:obj:`Context` instance argument or with any number of arguments other
than 1.
"""
ctx = Context(TLSv1_METHOD)
@@ -1046,7 +1156,7 @@ class ConnectionTests(TestCase, _LoopbackMixin):
def test_set_context(self):
"""
- L{Connection.set_context} specifies a new L{Context} instance to be used
+ :py:obj:`Connection.set_context` specifies a new :py:obj:`Context` instance to be used
for the connection.
"""
original = Context(SSLv23_METHOD)
@@ -1062,9 +1172,9 @@ class ConnectionTests(TestCase, _LoopbackMixin):
def test_set_tlsext_host_name_wrong_args(self):
"""
- If L{Connection.set_tlsext_host_name} is called with a non-byte string
+ If :py:obj:`Connection.set_tlsext_host_name` is called with a non-byte string
argument or a byte string with an embedded NUL or other than one
- argument, L{TypeError} is raised.
+ argument, :py:obj:`TypeError` is raised.
"""
conn = Connection(Context(TLSv1_METHOD), None)
self.assertRaises(TypeError, conn.set_tlsext_host_name)
@@ -1082,7 +1192,7 @@ class ConnectionTests(TestCase, _LoopbackMixin):
def test_get_servername_wrong_args(self):
"""
- L{Connection.get_servername} raises L{TypeError} if called with any
+ :py:obj:`Connection.get_servername` raises :py:obj:`TypeError` if called with any
arguments.
"""
connection = Connection(Context(TLSv1_METHOD), None)
@@ -1093,7 +1203,7 @@ class ConnectionTests(TestCase, _LoopbackMixin):
def test_pending(self):
"""
- L{Connection.pending} returns the number of bytes available for
+ :py:obj:`Connection.pending` returns the number of bytes available for
immediate read.
"""
connection = Connection(Context(TLSv1_METHOD), None)
@@ -1102,7 +1212,7 @@ class ConnectionTests(TestCase, _LoopbackMixin):
def test_pending_wrong_args(self):
"""
- L{Connection.pending} raises L{TypeError} if called with any arguments.
+ :py:obj:`Connection.pending` raises :py:obj:`TypeError` if called with any arguments.
"""
connection = Connection(Context(TLSv1_METHOD), None)
self.assertRaises(TypeError, connection.pending, None)
@@ -1110,7 +1220,7 @@ class ConnectionTests(TestCase, _LoopbackMixin):
def test_connect_wrong_args(self):
"""
- L{Connection.connect} raises L{TypeError} if called with a non-address
+ :py:obj:`Connection.connect` raises :py:obj:`TypeError` if called with a non-address
argument or with the wrong number of arguments.
"""
connection = Connection(Context(TLSv1_METHOD), socket())
@@ -1121,7 +1231,7 @@ class ConnectionTests(TestCase, _LoopbackMixin):
def test_connect_refused(self):
"""
- L{Connection.connect} raises L{socket.error} if the underlying socket
+ :py:obj:`Connection.connect` raises :py:obj:`socket.error` if the underlying socket
connect method raises it.
"""
client = socket()
@@ -1133,7 +1243,7 @@ class ConnectionTests(TestCase, _LoopbackMixin):
def test_connect(self):
"""
- L{Connection.connect} establishes a connection to the specified address.
+ :py:obj:`Connection.connect` establishes a connection to the specified address.
"""
port = socket()
port.bind(('', 0))
@@ -1149,7 +1259,7 @@ class ConnectionTests(TestCase, _LoopbackMixin):
else:
def test_connect_ex(self):
"""
- If there is a connection error, L{Connection.connect_ex} returns the
+ If there is a connection error, :py:obj:`Connection.connect_ex` returns the
errno instead of raising an exception.
"""
port = socket()
@@ -1166,7 +1276,7 @@ class ConnectionTests(TestCase, _LoopbackMixin):
def test_accept_wrong_args(self):
"""
- L{Connection.accept} raises L{TypeError} if called with any arguments.
+ :py:obj:`Connection.accept` raises :py:obj:`TypeError` if called with any arguments.
"""
connection = Connection(Context(TLSv1_METHOD), socket())
self.assertRaises(TypeError, connection.accept, None)
@@ -1174,8 +1284,8 @@ class ConnectionTests(TestCase, _LoopbackMixin):
def test_accept(self):
"""
- L{Connection.accept} accepts a pending connection attempt and returns a
- tuple of a new L{Connection} (the accepted client) and the address the
+ :py:obj:`Connection.accept` accepts a pending connection attempt and returns a
+ tuple of a new :py:obj:`Connection` (the accepted client) and the address the
connection originated from.
"""
ctx = Context(TLSv1_METHOD)
@@ -1201,7 +1311,7 @@ class ConnectionTests(TestCase, _LoopbackMixin):
def test_shutdown_wrong_args(self):
"""
- L{Connection.shutdown} raises L{TypeError} if called with the wrong
+ :py:obj:`Connection.shutdown` raises :py:obj:`TypeError` if called with the wrong
number of arguments or with arguments other than integers.
"""
connection = Connection(Context(TLSv1_METHOD), None)
@@ -1214,7 +1324,7 @@ class ConnectionTests(TestCase, _LoopbackMixin):
def test_shutdown(self):
"""
- L{Connection.shutdown} performs an SSL-level connection shutdown.
+ :py:obj:`Connection.shutdown` performs an SSL-level connection shutdown.
"""
server, client = self._loopback()
self.assertFalse(server.shutdown())
@@ -1229,7 +1339,7 @@ class ConnectionTests(TestCase, _LoopbackMixin):
def test_set_shutdown(self):
"""
- L{Connection.set_shutdown} sets the state of the SSL connection shutdown
+ :py:obj:`Connection.set_shutdown` sets the state of the SSL connection shutdown
process.
"""
connection = Connection(Context(TLSv1_METHOD), socket())
@@ -1239,8 +1349,8 @@ class ConnectionTests(TestCase, _LoopbackMixin):
def test_app_data_wrong_args(self):
"""
- L{Connection.set_app_data} raises L{TypeError} if called with other than
- one argument. L{Connection.get_app_data} raises L{TypeError} if called
+ :py:obj:`Connection.set_app_data` raises :py:obj:`TypeError` if called with other than
+ one argument. :py:obj:`Connection.get_app_data` raises :py:obj:`TypeError` if called
with any arguments.
"""
conn = Connection(Context(TLSv1_METHOD), None)
@@ -1252,8 +1362,8 @@ class ConnectionTests(TestCase, _LoopbackMixin):
def test_app_data(self):
"""
Any object can be set as app data by passing it to
- L{Connection.set_app_data} and later retrieved with
- L{Connection.get_app_data}.
+ :py:obj:`Connection.set_app_data` and later retrieved with
+ :py:obj:`Connection.get_app_data`.
"""
conn = Connection(Context(TLSv1_METHOD), None)
app_data = object()
@@ -1263,8 +1373,8 @@ class ConnectionTests(TestCase, _LoopbackMixin):
def test_makefile(self):
"""
- L{Connection.makefile} is not implemented and calling that method raises
- L{NotImplementedError}.
+ :py:obj:`Connection.makefile` is not implemented and calling that method raises
+ :py:obj:`NotImplementedError`.
"""
conn = Connection(Context(TLSv1_METHOD), None)
self.assertRaises(NotImplementedError, conn.makefile)
@@ -1272,7 +1382,7 @@ class ConnectionTests(TestCase, _LoopbackMixin):
def test_get_peer_cert_chain_wrong_args(self):
"""
- L{Connection.get_peer_cert_chain} raises L{TypeError} if called with any
+ :py:obj:`Connection.get_peer_cert_chain` raises :py:obj:`TypeError` if called with any
arguments.
"""
conn = Connection(Context(TLSv1_METHOD), None)
@@ -1284,7 +1394,7 @@ class ConnectionTests(TestCase, _LoopbackMixin):
def test_get_peer_cert_chain(self):
"""
- L{Connection.get_peer_cert_chain} returns a list of certificates which
+ :py:obj:`Connection.get_peer_cert_chain` returns a list of certificates which
the connected server returned for the certification verification.
"""
chain = _create_certificate_chain()
@@ -1318,7 +1428,7 @@ class ConnectionTests(TestCase, _LoopbackMixin):
def test_get_peer_cert_chain_none(self):
"""
- L{Connection.get_peer_cert_chain} returns C{None} if the peer sends no
+ :py:obj:`Connection.get_peer_cert_chain` returns :py:obj:`None` if the peer sends no
certificate chain.
"""
ctx = Context(TLSv1_METHOD)
@@ -1332,14 +1442,151 @@ class ConnectionTests(TestCase, _LoopbackMixin):
self.assertIdentical(None, server.get_peer_cert_chain())
+ def test_get_session_wrong_args(self):
+ """
+ :py:obj:`Connection.get_session` raises :py:obj:`TypeError` if called
+ with any arguments.
+ """
+ ctx = Context(TLSv1_METHOD)
+ server = Connection(ctx, None)
+ self.assertRaises(TypeError, server.get_session, 123)
+ self.assertRaises(TypeError, server.get_session, "hello")
+ self.assertRaises(TypeError, server.get_session, object())
+
+
+ def test_get_session_unconnected(self):
+ """
+ :py:obj:`Connection.get_session` returns :py:obj:`None` when used with
+ an object which has not been connected.
+ """
+ ctx = Context(TLSv1_METHOD)
+ server = Connection(ctx, None)
+ session = server.get_session()
+ self.assertIdentical(None, session)
+
+
+ def test_server_get_session(self):
+ """
+ On the server side of a connection, :py:obj:`Connection.get_session`
+ returns a :py:class:`Session` instance representing the SSL session for
+ that connection.
+ """
+ server, client = self._loopback()
+ session = server.get_session()
+ self.assertTrue(session, Session)
+
+
+ def test_client_get_session(self):
+ """
+ On the client side of a connection, :py:obj:`Connection.get_session`
+ returns a :py:class:`Session` instance representing the SSL session for
+ that connection.
+ """
+ server, client = self._loopback()
+ session = client.get_session()
+ self.assertTrue(session, Session)
+
+
+ def test_set_session_wrong_args(self):
+ """
+ If called with an object that is not an instance of :py:class:`Session`,
+ or with other than one argument, :py:obj:`Connection.set_session` raises
+ :py:obj:`TypeError`.
+ """
+ ctx = Context(TLSv1_METHOD)
+ connection = Connection(ctx, None)
+ self.assertRaises(TypeError, connection.set_session)
+ self.assertRaises(TypeError, connection.set_session, 123)
+ self.assertRaises(TypeError, connection.set_session, "hello")
+ self.assertRaises(TypeError, connection.set_session, object())
+ self.assertRaises(
+ TypeError, connection.set_session, Session(), Session())
+
+
+ def test_client_set_session(self):
+ """
+ :py:obj:`Connection.set_session`, when used prior to a connection being
+ established, accepts a :py:class:`Session` instance and causes an
+ attempt to re-use the session it represents when the SSL handshake is
+ performed.
+ """
+ key = load_privatekey(FILETYPE_PEM, server_key_pem)
+ cert = load_certificate(FILETYPE_PEM, server_cert_pem)
+ ctx = Context(TLSv1_METHOD)
+ ctx.use_privatekey(key)
+ ctx.use_certificate(cert)
+ ctx.set_session_id("unity-test")
+
+ def makeServer(socket):
+ server = Connection(ctx, socket)
+ server.set_accept_state()
+ return server
+
+ originalServer, originalClient = self._loopback(
+ serverFactory=makeServer)
+ originalSession = originalClient.get_session()
+
+ def makeClient(socket):
+ client = self._loopbackClientFactory(socket)
+ client.set_session(originalSession)
+ return client
+ resumedServer, resumedClient = self._loopback(
+ serverFactory=makeServer,
+ clientFactory=makeClient)
+
+ # This is a proxy: in general, we have no access to any unique
+ # identifier for the session (new enough versions of OpenSSL expose a
+ # hash which could be usable, but "new enough" is very, very new).
+ # Instead, exploit the fact that the master key is re-used if the
+ # session is re-used. As long as the master key for the two connections
+ # is the same, the session was re-used!
+ self.assertEqual(
+ originalServer.master_key(), resumedServer.master_key())
+
+
+ def test_set_session_wrong_method(self):
+ """
+ If :py:obj:`Connection.set_session` is passed a :py:class:`Session`
+ instance associated with a context using a different SSL method than the
+ :py:obj:`Connection` is using, a :py:class:`OpenSSL.SSL.Error` is
+ raised.
+ """
+ key = load_privatekey(FILETYPE_PEM, server_key_pem)
+ cert = load_certificate(FILETYPE_PEM, server_cert_pem)
+ ctx = Context(TLSv1_METHOD)
+ ctx.use_privatekey(key)
+ ctx.use_certificate(cert)
+ ctx.set_session_id("unity-test")
+
+ def makeServer(socket):
+ server = Connection(ctx, socket)
+ server.set_accept_state()
+ return server
+
+ originalServer, originalClient = self._loopback(
+ serverFactory=makeServer)
+ originalSession = originalClient.get_session()
+
+ def makeClient(socket):
+ # Intentionally use a different, incompatible method here.
+ client = Connection(Context(SSLv3_METHOD), socket)
+ client.set_connect_state()
+ client.set_session(originalSession)
+ return client
+
+ self.assertRaises(
+ Error,
+ self._loopback, clientFactory=makeClient, serverFactory=makeServer)
+
+
class ConnectionGetCipherListTests(TestCase):
"""
- Tests for L{Connection.get_cipher_list}.
+ Tests for :py:obj:`Connection.get_cipher_list`.
"""
def test_wrong_args(self):
"""
- L{Connection.get_cipher_list} raises L{TypeError} if called with any
+ :py:obj:`Connection.get_cipher_list` raises :py:obj:`TypeError` if called with any
arguments.
"""
connection = Connection(Context(TLSv1_METHOD), None)
@@ -1348,7 +1595,7 @@ class ConnectionGetCipherListTests(TestCase):
def test_result(self):
"""
- L{Connection.get_cipher_list} returns a C{list} of C{str} giving the
+ :py:obj:`Connection.get_cipher_list` returns a :py:obj:`list` of :py:obj:`str` giving the
names of the ciphers which might be used.
"""
connection = Connection(Context(TLSv1_METHOD), None)
@@ -1361,12 +1608,12 @@ class ConnectionGetCipherListTests(TestCase):
class ConnectionSendTests(TestCase, _LoopbackMixin):
"""
- Tests for L{Connection.send}
+ Tests for :py:obj:`Connection.send`
"""
def test_wrong_args(self):
"""
When called with arguments other than a single string,
- L{Connection.send} raises L{TypeError}.
+ :py:obj:`Connection.send` raises :py:obj:`TypeError`.
"""
connection = Connection(Context(TLSv1_METHOD), None)
self.assertRaises(TypeError, connection.send)
@@ -1376,7 +1623,7 @@ class ConnectionSendTests(TestCase, _LoopbackMixin):
def test_short_bytes(self):
"""
- When passed a short byte string, L{Connection.send} transmits all of it
+ When passed a short byte string, :py:obj:`Connection.send` transmits all of it
and returns the number of bytes sent.
"""
server, client = self._loopback()
@@ -1392,7 +1639,7 @@ class ConnectionSendTests(TestCase, _LoopbackMixin):
def test_short_memoryview(self):
"""
When passed a memoryview onto a small number of bytes,
- L{Connection.send} transmits all of them and returns the number of
+ :py:obj:`Connection.send` transmits all of them and returns the number of
bytes sent.
"""
server, client = self._loopback()
@@ -1404,12 +1651,12 @@ class ConnectionSendTests(TestCase, _LoopbackMixin):
class ConnectionSendallTests(TestCase, _LoopbackMixin):
"""
- Tests for L{Connection.sendall}.
+ Tests for :py:obj:`Connection.sendall`.
"""
def test_wrong_args(self):
"""
When called with arguments other than a single string,
- L{Connection.sendall} raises L{TypeError}.
+ :py:obj:`Connection.sendall` raises :py:obj:`TypeError`.
"""
connection = Connection(Context(TLSv1_METHOD), None)
self.assertRaises(TypeError, connection.sendall)
@@ -1419,7 +1666,7 @@ class ConnectionSendallTests(TestCase, _LoopbackMixin):
def test_short(self):
"""
- L{Connection.sendall} transmits all of the bytes in the string passed to
+ :py:obj:`Connection.sendall` transmits all of the bytes in the string passed to
it.
"""
server, client = self._loopback()
@@ -1435,7 +1682,7 @@ class ConnectionSendallTests(TestCase, _LoopbackMixin):
def test_short_memoryview(self):
"""
When passed a memoryview onto a small number of bytes,
- L{Connection.sendall} transmits all of them.
+ :py:obj:`Connection.sendall` transmits all of them.
"""
server, client = self._loopback()
server.sendall(memoryview(b('x')))
@@ -1444,7 +1691,7 @@ class ConnectionSendallTests(TestCase, _LoopbackMixin):
def test_long(self):
"""
- L{Connection.sendall} transmits all of the bytes in the string passed to
+ :py:obj:`Connection.sendall` transmits all of the bytes in the string passed to
it even if this requires multiple calls of an underlying write function.
"""
server, client = self._loopback()
@@ -1464,7 +1711,7 @@ class ConnectionSendallTests(TestCase, _LoopbackMixin):
def test_closed(self):
"""
- If the underlying socket is closed, L{Connection.sendall} propagates the
+ If the underlying socket is closed, :py:obj:`Connection.sendall` propagates the
write error from the low level write call.
"""
server, client = self._loopback()
@@ -1479,7 +1726,7 @@ class ConnectionRenegotiateTests(TestCase, _LoopbackMixin):
"""
def test_renegotiate_wrong_args(self):
"""
- L{Connection.renegotiate} raises L{TypeError} if called with any
+ :py:obj:`Connection.renegotiate` raises :py:obj:`TypeError` if called with any
arguments.
"""
connection = Connection(Context(TLSv1_METHOD), None)
@@ -1488,7 +1735,7 @@ class ConnectionRenegotiateTests(TestCase, _LoopbackMixin):
def test_total_renegotiations_wrong_args(self):
"""
- L{Connection.total_renegotiations} raises L{TypeError} if called with
+ :py:obj:`Connection.total_renegotiations` raises :py:obj:`TypeError` if called with
any arguments.
"""
connection = Connection(Context(TLSv1_METHOD), None)
@@ -1497,7 +1744,7 @@ class ConnectionRenegotiateTests(TestCase, _LoopbackMixin):
def test_total_renegotiations(self):
"""
- L{Connection.total_renegotiations} returns C{0} before any
+ :py:obj:`Connection.total_renegotiations` returns :py:obj:`0` before any
renegotiations have happened.
"""
connection = Connection(Context(TLSv1_METHOD), None)
@@ -1528,11 +1775,11 @@ class ConnectionRenegotiateTests(TestCase, _LoopbackMixin):
class ErrorTests(TestCase):
"""
- Unit tests for L{OpenSSL.SSL.Error}.
+ Unit tests for :py:obj:`OpenSSL.SSL.Error`.
"""
def test_type(self):
"""
- L{Error} is an exception type.
+ :py:obj:`Error` is an exception type.
"""
self.assertTrue(issubclass(Error, Exception))
self.assertEqual(Error.__name__, 'Error')
@@ -1541,7 +1788,7 @@ class ErrorTests(TestCase):
class ConstantsTests(TestCase):
"""
- Tests for the values of constants exposed in L{OpenSSL.SSL}.
+ Tests for the values of constants exposed in :py:obj:`OpenSSL.SSL`.
These are values defined by OpenSSL intended only to be used as flags to
OpenSSL APIs. The only assertions it seems can be made about them is
@@ -1551,8 +1798,8 @@ class ConstantsTests(TestCase):
if OP_NO_QUERY_MTU is not None:
def test_op_no_query_mtu(self):
"""
- The value of L{OpenSSL.SSL.OP_NO_QUERY_MTU} is 0x1000, the value of
- I{SSL_OP_NO_QUERY_MTU} defined by I{openssl/ssl.h}.
+ The value of :py:obj:`OpenSSL.SSL.OP_NO_QUERY_MTU` is 0x1000, the value of
+ :py:const:`SSL_OP_NO_QUERY_MTU` defined by :file:`openssl/ssl.h`.
"""
self.assertEqual(OP_NO_QUERY_MTU, 0x1000)
else:
@@ -1562,8 +1809,8 @@ class ConstantsTests(TestCase):
if OP_COOKIE_EXCHANGE is not None:
def test_op_cookie_exchange(self):
"""
- The value of L{OpenSSL.SSL.OP_COOKIE_EXCHANGE} is 0x2000, the value
- of I{SSL_OP_COOKIE_EXCHANGE} defined by I{openssl/ssl.h}.
+ The value of :py:obj:`OpenSSL.SSL.OP_COOKIE_EXCHANGE` is 0x2000, the value
+ of :py:const:`SSL_OP_COOKIE_EXCHANGE` defined by :file:`openssl/ssl.h`.
"""
self.assertEqual(OP_COOKIE_EXCHANGE, 0x2000)
else:
@@ -1573,23 +1820,100 @@ class ConstantsTests(TestCase):
if OP_NO_TICKET is not None:
def test_op_no_ticket(self):
"""
- The value of L{OpenSSL.SSL.OP_NO_TICKET} is 0x4000, the value of
- I{SSL_OP_NO_TICKET} defined by I{openssl/ssl.h}.
+ The value of :py:obj:`OpenSSL.SSL.OP_NO_TICKET` is 0x4000, the value of
+ :py:const:`SSL_OP_NO_TICKET` defined by :file:`openssl/ssl.h`.
"""
self.assertEqual(OP_NO_TICKET, 0x4000)
else:
"OP_NO_TICKET unavailable - OpenSSL version may be too old"
+ if OP_NO_COMPRESSION is not None:
+ def test_op_no_compression(self):
+ """
+ The value of :py:obj:`OpenSSL.SSL.OP_NO_COMPRESSION` is 0x20000, the value
+ of :py:const:`SSL_OP_NO_COMPRESSION` defined by :file:`openssl/ssl.h`.
+ """
+ self.assertEqual(OP_NO_COMPRESSION, 0x20000)
+ else:
+ "OP_NO_COMPRESSION unavailable - OpenSSL version may be too old"
+
+
+ def test_sess_cache_off(self):
+ """
+ The value of L{OpenSSL.SSL.SESS_CACHE_OFF} 0x0, the value of
+ L{SSL_SESS_CACHE_OFF} defined by I{openssl/ssl.h}.
+ """
+ self.assertEqual(0x0, SESS_CACHE_OFF)
+
+
+ def test_sess_cache_client(self):
+ """
+ The value of L{OpenSSL.SSL.SESS_CACHE_CLIENT} 0x1, the value of
+ L{SSL_SESS_CACHE_CLIENT} defined by I{openssl/ssl.h}.
+ """
+ self.assertEqual(0x1, SESS_CACHE_CLIENT)
+
+
+ def test_sess_cache_server(self):
+ """
+ The value of L{OpenSSL.SSL.SESS_CACHE_SERVER} 0x2, the value of
+ L{SSL_SESS_CACHE_SERVER} defined by I{openssl/ssl.h}.
+ """
+ self.assertEqual(0x2, SESS_CACHE_SERVER)
+
+
+ def test_sess_cache_both(self):
+ """
+ The value of L{OpenSSL.SSL.SESS_CACHE_BOTH} 0x3, the value of
+ L{SSL_SESS_CACHE_BOTH} defined by I{openssl/ssl.h}.
+ """
+ self.assertEqual(0x3, SESS_CACHE_BOTH)
+
+
+ def test_sess_cache_no_auto_clear(self):
+ """
+ The value of L{OpenSSL.SSL.SESS_CACHE_NO_AUTO_CLEAR} 0x80, the value of
+ L{SSL_SESS_CACHE_NO_AUTO_CLEAR} defined by I{openssl/ssl.h}.
+ """
+ self.assertEqual(0x80, SESS_CACHE_NO_AUTO_CLEAR)
+
+
+ def test_sess_cache_no_internal_lookup(self):
+ """
+ The value of L{OpenSSL.SSL.SESS_CACHE_NO_INTERNAL_LOOKUP} 0x100, the
+ value of L{SSL_SESS_CACHE_NO_INTERNAL_LOOKUP} defined by
+ I{openssl/ssl.h}.
+ """
+ self.assertEqual(0x100, SESS_CACHE_NO_INTERNAL_LOOKUP)
+
+
+ def test_sess_cache_no_internal_store(self):
+ """
+ The value of L{OpenSSL.SSL.SESS_CACHE_NO_INTERNAL_STORE} 0x200, the
+ value of L{SSL_SESS_CACHE_NO_INTERNAL_STORE} defined by
+ I{openssl/ssl.h}.
+ """
+ self.assertEqual(0x200, SESS_CACHE_NO_INTERNAL_STORE)
+
+
+ def test_sess_cache_no_internal(self):
+ """
+ The value of L{OpenSSL.SSL.SESS_CACHE_NO_INTERNAL} 0x300, the value of
+ L{SSL_SESS_CACHE_NO_INTERNAL} defined by I{openssl/ssl.h}.
+ """
+ self.assertEqual(0x300, SESS_CACHE_NO_INTERNAL)
+
+
class MemoryBIOTests(TestCase, _LoopbackMixin):
"""
- Tests for L{OpenSSL.SSL.Connection} using a memory BIO.
+ Tests for :py:obj:`OpenSSL.SSL.Connection` using a memory BIO.
"""
def _server(self, sock):
"""
- Create a new server-side SSL L{Connection} object wrapped around
- C{sock}.
+ Create a new server-side SSL :py:obj:`Connection` object wrapped around
+ :py:obj:`sock`.
"""
# Create the server side Connection. This is mostly setup boilerplate
# - use TLSv1, use a particular certificate, etc.
@@ -1610,8 +1934,8 @@ class MemoryBIOTests(TestCase, _LoopbackMixin):
def _client(self, sock):
"""
- Create a new client-side SSL L{Connection} object wrapped around
- C{sock}.
+ Create a new client-side SSL :py:obj:`Connection` object wrapped around
+ :py:obj:`sock`.
"""
# Now create the client side Connection. Similar boilerplate to the
# above.
@@ -1630,7 +1954,7 @@ class MemoryBIOTests(TestCase, _LoopbackMixin):
def test_memoryConnect(self):
"""
- Two L{Connection}s which use memory BIOs can be manually connected by
+ Two :py:obj:`Connection`s which use memory BIOs can be manually connected by
reading from the output of each and writing those bytes to the input of
the other and in this way establish a connection and exchange
application-level bytes with each other.
@@ -1674,10 +1998,10 @@ class MemoryBIOTests(TestCase, _LoopbackMixin):
def test_socketConnect(self):
"""
- Just like L{test_memoryConnect} but with an actual socket.
+ Just like :py:obj:`test_memoryConnect` but with an actual socket.
This is primarily to rule out the memory BIO code as the source of
- any problems encountered while passing data over a L{Connection} (if
+ any problems encountered while passing data over a :py:obj:`Connection` (if
this test fails, there must be a problem outside the memory BIO
code, as no memory BIO is involved here). Even though this isn't a
memory BIO test, it's convenient to have it here.
@@ -1698,8 +2022,8 @@ class MemoryBIOTests(TestCase, _LoopbackMixin):
def test_socketOverridesMemory(self):
"""
- Test that L{OpenSSL.SSL.bio_read} and L{OpenSSL.SSL.bio_write} don't
- work on L{OpenSSL.SSL.Connection}() that use sockets.
+ Test that :py:obj:`OpenSSL.SSL.bio_read` and :py:obj:`OpenSSL.SSL.bio_write` don't
+ work on :py:obj:`OpenSSL.SSL.Connection`() that use sockets.
"""
context = Context(SSLv3_METHOD)
client = socket()
@@ -1712,7 +2036,7 @@ class MemoryBIOTests(TestCase, _LoopbackMixin):
def test_outgoingOverflow(self):
"""
If more bytes than can be written to the memory BIO are passed to
- L{Connection.send} at once, the number of bytes which were written is
+ :py:obj:`Connection.send` at once, the number of bytes which were written is
returned and that many bytes from the beginning of the input can be
read from the other end of the connection.
"""
@@ -1738,8 +2062,8 @@ class MemoryBIOTests(TestCase, _LoopbackMixin):
def test_shutdown(self):
"""
- L{Connection.bio_shutdown} signals the end of the data stream from
- which the L{Connection} reads.
+ :py:obj:`Connection.bio_shutdown` signals the end of the data stream from
+ which the :py:obj:`Connection` reads.
"""
server = self._server(None)
server.bio_shutdown()
@@ -1751,13 +2075,13 @@ class MemoryBIOTests(TestCase, _LoopbackMixin):
def _check_client_ca_list(self, func):
"""
- Verify the return value of the C{get_client_ca_list} method for server and client connections.
+ Verify the return value of the :py:obj:`get_client_ca_list` method for server and client connections.
- @param func: A function which will be called with the server context
+ :param func: A function which will be called with the server context
before the client and server are connected to each other. This
function should specify a list of CAs for the server to send to the
client and return that same list. The list will be used to verify
- that C{get_client_ca_list} returns the proper value at various
+ that :py:obj:`get_client_ca_list` returns the proper value at various
times.
"""
server = self._server(None)
@@ -1775,7 +2099,7 @@ class MemoryBIOTests(TestCase, _LoopbackMixin):
def test_set_client_ca_list_errors(self):
"""
- L{Context.set_client_ca_list} raises a L{TypeError} if called with a
+ :py:obj:`Context.set_client_ca_list` raises a :py:obj:`TypeError` if called with a
non-list or a list that contains objects other than X509Names.
"""
ctx = Context(TLSv1_METHOD)
@@ -1786,9 +2110,9 @@ class MemoryBIOTests(TestCase, _LoopbackMixin):
def test_set_empty_ca_list(self):
"""
- If passed an empty list, L{Context.set_client_ca_list} configures the
+ If passed an empty list, :py:obj:`Context.set_client_ca_list` configures the
context to send no CA names to the client and, on both the server and
- client sides, L{Connection.get_client_ca_list} returns an empty list
+ client sides, :py:obj:`Connection.get_client_ca_list` returns an empty list
after the connection is set up.
"""
def no_ca(ctx):
@@ -1800,9 +2124,9 @@ class MemoryBIOTests(TestCase, _LoopbackMixin):
def test_set_one_ca_list(self):
"""
If passed a list containing a single X509Name,
- L{Context.set_client_ca_list} configures the context to send that CA
+ :py:obj:`Context.set_client_ca_list` configures the context to send that CA
name to the client and, on both the server and client sides,
- L{Connection.get_client_ca_list} returns a list containing that
+ :py:obj:`Connection.get_client_ca_list` returns a list containing that
X509Name after the connection is set up.
"""
cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
@@ -1816,9 +2140,9 @@ class MemoryBIOTests(TestCase, _LoopbackMixin):
def test_set_multiple_ca_list(self):
"""
If passed a list containing multiple X509Name objects,
- L{Context.set_client_ca_list} configures the context to send those CA
+ :py:obj:`Context.set_client_ca_list` configures the context to send those CA
names to the client and, on both the server and client sides,
- L{Connection.get_client_ca_list} returns a list containing those
+ :py:obj:`Connection.get_client_ca_list` returns a list containing those
X509Names after the connection is set up.
"""
secert = load_certificate(FILETYPE_PEM, server_cert_pem)
@@ -1837,7 +2161,7 @@ class MemoryBIOTests(TestCase, _LoopbackMixin):
def test_reset_ca_list(self):
"""
If called multiple times, only the X509Names passed to the final call
- of L{Context.set_client_ca_list} are used to configure the CA names
+ of :py:obj:`Context.set_client_ca_list` are used to configure the CA names
sent to the client.
"""
cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
@@ -1857,7 +2181,7 @@ class MemoryBIOTests(TestCase, _LoopbackMixin):
def test_mutated_ca_list(self):
"""
- If the list passed to L{Context.set_client_ca_list} is mutated
+ If the list passed to :py:obj:`Context.set_client_ca_list` is mutated
afterwards, this does not affect the list of CA names sent to the
client.
"""
@@ -1877,7 +2201,7 @@ class MemoryBIOTests(TestCase, _LoopbackMixin):
def test_add_client_ca_errors(self):
"""
- L{Context.add_client_ca} raises L{TypeError} if called with a non-X509
+ :py:obj:`Context.add_client_ca` raises :py:obj:`TypeError` if called with a non-X509
object or with a number of arguments other than one.
"""
ctx = Context(TLSv1_METHOD)
@@ -1890,7 +2214,7 @@ class MemoryBIOTests(TestCase, _LoopbackMixin):
def test_one_add_client_ca(self):
"""
A certificate's subject can be added as a CA to be sent to the client
- with L{Context.add_client_ca}.
+ with :py:obj:`Context.add_client_ca`.
"""
cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
cadesc = cacert.get_subject()
@@ -1903,7 +2227,7 @@ class MemoryBIOTests(TestCase, _LoopbackMixin):
def test_multiple_add_client_ca(self):
"""
Multiple CA names can be sent to the client by calling
- L{Context.add_client_ca} with multiple X509 objects.
+ :py:obj:`Context.add_client_ca` with multiple X509 objects.
"""
cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
secert = load_certificate(FILETYPE_PEM, server_cert_pem)
@@ -1920,8 +2244,8 @@ class MemoryBIOTests(TestCase, _LoopbackMixin):
def test_set_and_add_client_ca(self):
"""
- A call to L{Context.set_client_ca_list} followed by a call to
- L{Context.add_client_ca} results in using the CA names from the first
+ A call to :py:obj:`Context.set_client_ca_list` followed by a call to
+ :py:obj:`Context.add_client_ca` results in using the CA names from the first
call and the CA name from the second call.
"""
cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
@@ -1941,8 +2265,8 @@ class MemoryBIOTests(TestCase, _LoopbackMixin):
def test_set_after_add_client_ca(self):
"""
- A call to L{Context.set_client_ca_list} after a call to
- L{Context.add_client_ca} replaces the CA name specified by the former
+ A call to :py:obj:`Context.set_client_ca_list` after a call to
+ :py:obj:`Context.add_client_ca` replaces the CA name specified by the former
call with the names specified by the latter cal.
"""
cacert = load_certificate(FILETYPE_PEM, root_cert_pem)