summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Paul Calderone <exarkun@twistedmatrix.com>2013-03-06 10:29:21 -0800
committerJean-Paul Calderone <exarkun@twistedmatrix.com>2013-03-06 10:29:21 -0800
commit173cff9ff499246703d3e1cf78ed75f5be9f51f0 (patch)
tree408aec912154fbb787120ca882d4d85f5b7253b8
parente6f32b8404e539a7dd5746b1effe9765b9d3237e (diff)
downloadpyopenssl-173cff9ff499246703d3e1cf78ed75f5be9f51f0.tar.gz
Fixes and more tests for Context.use_certificate_file and Context.use_certificate
-rw-r--r--OpenSSL/SSL.py33
-rw-r--r--OpenSSL/test/test_ssl.py88
2 files changed, 112 insertions, 9 deletions
diff --git a/OpenSSL/SSL.py b/OpenSSL/SSL.py
index 1ef3006..866fb8a 100644
--- a/OpenSSL/SSL.py
+++ b/OpenSSL/SSL.py
@@ -186,11 +186,12 @@ class Context(object):
context = _api.ffi.gc(context, _api.SSL_CTX_free)
self._context = context
+ self._passphrase_helper = None
self._passphrase_callback = None
+ self._passphrase_userdata = None
self._verify_callback = None
self._info_callback = None
self._tlsext_servername_callback = None
- self._passphrase_userdata = None
self._app_data = None
# SSL_CTX_set_app_data(self->ctx, self);
@@ -278,7 +279,7 @@ class Context(object):
_raise_current_error(Error)
- def use_certificate_file(self, certfile, filetype=_unspecified):
+ def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
"""
Load a certificate from a file
@@ -286,6 +287,15 @@ class Context(object):
:param filetype: (optional) The encoding of the file, default is PEM
:return: None
"""
+ if not isinstance(certfile, bytes):
+ raise TypeError("certfile must be a byte string")
+ if not isinstance(filetype, int):
+ raise TypeError("filetype must be an integer")
+
+ use_result = _api.SSL_CTX_use_certificate_file(self._context, certfile, filetype)
+ if not use_result:
+ _raise_current_error(Error)
+
def use_certificate(self, cert):
"""
@@ -299,7 +309,7 @@ class Context(object):
use_result = _api.SSL_CTX_use_certificate(self._context, cert._x509)
if not use_result:
- 1/0
+ _raise_current_error(Error)
def add_extra_chain_cert(self, certobj):
@@ -319,6 +329,15 @@ class Context(object):
# _raise_current_error(Error)
1/0
+
+ def _raise_passphrase_exception(self):
+ if self._passphrase_helper is None:
+ _raise_current_error(Error)
+ exception = self._passphrase_helper.raise_if_problem(Error)
+ if exception is not None:
+ raise exception
+
+
def use_privatekey_file(self, keyfile, filetype=_unspecified):
"""
Load a private key from a file
@@ -338,9 +357,7 @@ class Context(object):
use_result = _api.SSL_CTX_use_PrivateKey_file(
self._context, keyfile, filetype)
if not use_result:
- exception = self._passphrase_helper.raise_if_problem(Error)
- if exception is not None:
- raise exception
+ self._raise_passphrase_exception()
def use_privatekey(self, pkey):
@@ -355,9 +372,7 @@ class Context(object):
use_result = _api.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
if not use_result:
- exception = self._passphrase_helper.raise_if_problem(Error)
- if exception is not None:
- raise exception
+ self._raise_passphrase_exception()
def check_privatekey(self):
diff --git a/OpenSSL/test/test_ssl.py b/OpenSSL/test/test_ssl.py
index bdb497e..884801a 100644
--- a/OpenSSL/test/test_ssl.py
+++ b/OpenSSL/test/test_ssl.py
@@ -342,6 +342,94 @@ class ContextTests(TestCase, _LoopbackMixin):
self.assertRaises(TypeError, ctx.use_privatekey, "")
+ def test_use_privatekey_file_missing(self):
+ """
+ :py:obj:`Context.use_privatekey_file` raises :py:obj:`OpenSSL.SSL.Error`
+ when passed the name of a file which does not exist.
+ """
+ ctx = Context(TLSv1_METHOD)
+ self.assertRaises(Error, ctx.use_privatekey_file, self.mktemp())
+
+
+ def test_use_certificate_wrong_args(self):
+ """
+ :py:obj:`Context.use_certificate_wrong_args` raises :py:obj:`TypeError`
+ when not passed exactly one :py:obj:`OpenSSL.crypto.X509` instance as an
+ argument.
+ """
+ ctx = Context(TLSv1_METHOD)
+ self.assertRaises(TypeError, ctx.use_certificate)
+ self.assertRaises(TypeError, ctx.use_certificate, "hello, world")
+ self.assertRaises(TypeError, ctx.use_certificate, X509(), "hello, world")
+
+
+ def test_use_certificate_uninitialized(self):
+ """
+ :py:obj:`Context.use_certificate` raises :py:obj:`OpenSSL.SSL.Error`
+ when passed a :py:obj:`OpenSSL.crypto.X509` instance which has not been
+ initialized (ie, which does not actually have any certificate data).
+ """
+ ctx = Context(TLSv1_METHOD)
+ self.assertRaises(Error, ctx.use_certificate, X509())
+
+
+ def test_use_certificate(self):
+ """
+ :py:obj:`Context.use_certificate` sets the certificate which will be
+ used to identify connections created using the context.
+ """
+ # TODO
+ # Hard to assert anything. But we could set a privatekey then ask
+ # OpenSSL if the cert and key agree using check_privatekey. Then as
+ # long as check_privatekey works right we're good...
+ ctx = Context(TLSv1_METHOD)
+ ctx.use_certificate(load_certificate(FILETYPE_PEM, cleartextCertificatePEM))
+
+
+ def test_use_certificate_file_wrong_args(self):
+ """
+ :py:obj:`Context.use_certificate_file` raises :py:obj:`TypeError` if
+ called with zero arguments or more than two arguments, or if the first
+ argument is not a byte string or the second argumnent is not an integer.
+ """
+ ctx = Context(TLSv1_METHOD)
+ self.assertRaises(TypeError, ctx.use_certificate_file)
+ self.assertRaises(TypeError, ctx.use_certificate_file, b"somefile", object())
+ self.assertRaises(
+ TypeError, ctx.use_certificate_file, b"somefile", FILETYPE_PEM, object())
+ self.assertRaises(
+ TypeError, ctx.use_certificate_file, object(), FILETYPE_PEM)
+ self.assertRaises(
+ TypeError, ctx.use_certificate_file, b"somefile", object())
+
+
+ def test_use_certificate_file_missing(self):
+ """
+ :py:obj:`Context.use_certificate_file` raises
+ `:py:obj:`OpenSSL.SSL.Error` if passed the name of a file which does not
+ exist.
+ """
+ ctx = Context(TLSv1_METHOD)
+ self.assertRaises(Error, ctx.use_certificate_file, self.mktemp())
+
+
+ def test_use_certificate_file(self):
+ """
+ :py:obj:`Context.use_certificate` sets the certificate which will be
+ used to identify connections created using the context.
+ """
+ # TODO
+ # Hard to assert anything. But we could set a privatekey then ask
+ # OpenSSL if the cert and key agree using check_privatekey. Then as
+ # long as check_privatekey works right we're good...
+ pem_filename = self.mktemp()
+ with open(pem_filename, "w") as pem_file:
+ pem_file.write(cleartextCertificatePEM)
+
+ ctx = Context(TLSv1_METHOD)
+ ctx.use_certificate_file(pem_filename)
+
+
def test_set_app_data_wrong_args(self):
"""
:py:obj:`Context.set_app_data` raises :py:obj:`TypeError` if called with other than