Refactoring verify_cert
Apply the changes that we've been talking about in
https://github.com/pyca/pyopenssl/pull/155 regarding the placement of
verify_cert, viz., moving verify_cert from top level of crypto into
X509StoreContext.
This makes the pyOpenSSL API slightly different than the OpenSSL API,
but the plan will be to add back a verify_cert to the top level that is
nice to use.
diff --git a/OpenSSL/crypto.py b/OpenSSL/crypto.py
index b6951c0..395f273 100644
--- a/OpenSSL/crypto.py
+++ b/OpenSSL/crypto.py
@@ -32,35 +32,7 @@
"""
-
-def _exception_from_context_error(exception_type, store_ctx):
- """
- Convert a :py:func:`OpenSSL.crypto.verify_cert` failure into a Python
- exception.
-
- When a call to native OpenSSL X509_verify_cert fails, additonal information
- about the failure can be obtained from the store context.
- """
-
- errors = [
- _lib.X509_STORE_CTX_get_error(store_ctx._store_ctx),
- _lib.X509_STORE_CTX_get_error_depth(store_ctx._store_ctx),
- _native(_ffi.string(_lib.X509_verify_cert_error_string(
- _lib.X509_STORE_CTX_get_error(store_ctx._store_ctx)))),
- ]
- _x509 = _lib.X509_STORE_CTX_get_current_cert(store_ctx._store_ctx)
- if _x509 != _ffi.NULL:
- _cert = _lib.X509_dup(_x509)
- pycert = X509.__new__(X509)
- pycert._x509 = _ffi.gc(_cert, _lib.X509_free)
- e = exception_type(errors)
- e.certificate = pycert
- raise e
-
-
-
_raise_current_error = partial(_exception_from_error_queue, Error)
-_raise_context_error = partial(_exception_from_context_error, Error)
@@ -1387,6 +1359,19 @@
X509StoreType = X509Store
+class X509StoreContextError(Exception):
+ """
+ An error occurred while verifying a certificate using
+ `OpenSSL.X509StoreContext.verify_certificate`.
+
+ :param certificate: The certificate which caused verificate failure.
+ :type cert: :class:`X509`
+
+ """
+ def __init__(self, message, certificate):
+ super(X509StoreContextError, self).__init__(message)
+ self.certificate = certificate
+
class X509StoreContext(object):
"""
@@ -1440,6 +1425,42 @@
_lib.X509_STORE_CTX_cleanup(self._store_ctx)
+ def _exception_from_context(self):
+ """
+ Convert an OpenSSL native context error failure into a Python
+ exception.
+
+ When a call to native OpenSSL X509_verify_cert fails, additonal information
+ about the failure can be obtained from the store context.
+ """
+ errors = [
+ _lib.X509_STORE_CTX_get_error(self._store_ctx),
+ _lib.X509_STORE_CTX_get_error_depth(self._store_ctx),
+ _native(_ffi.string(_lib.X509_verify_cert_error_string(
+ _lib.X509_STORE_CTX_get_error(self._store_ctx)))),
+ ]
+ _x509 = _lib.X509_STORE_CTX_get_current_cert(self._store_ctx)
+ if _x509 != _ffi.NULL:
+ _cert = _lib.X509_dup(_x509)
+ pycert = X509.__new__(X509)
+ pycert._x509 = _ffi.gc(_cert, _lib.X509_free)
+ return X509StoreContextError(errors, pycert)
+
+
+ def verify_certificate(self):
+ """
+ Verify a certificate in a context.
+
+ :param store_ctx: The :py:class:`X509StoreContext` to verify.
+ :raises: Error
+ """
+ self._init()
+ ret = _lib.X509_verify_cert(self._store_ctx)
+ self._cleanup()
+ if ret <= 0:
+ raise self._exception_from_context()
+
+
def load_certificate(type, buffer):
"""
@@ -2388,20 +2409,6 @@
_raise_current_error()
-def verify_cert(store_ctx):
- """
- Verify a certificate in a context.
-
- :param store_ctx: The :py:class:`X509StoreContext` to verify.
- :raises: Error
- """
- store_ctx._init()
- ret = _lib.X509_verify_cert(store_ctx._store_ctx)
- store_ctx._cleanup()
- if ret <= 0:
- _raise_context_error(store_ctx)
-
-
def load_crl(type, buffer):
"""
Load a certificate revocation list from a buffer