diff options
-rw-r--r-- | OpenSSL/crypto.py | 18 | ||||
-rw-r--r-- | OpenSSL/test/test_crypto.py | 18 |
2 files changed, 35 insertions, 1 deletions
diff --git a/OpenSSL/crypto.py b/OpenSSL/crypto.py index c3d4c9b..5093745 100644 --- a/OpenSSL/crypto.py +++ b/OpenSSL/crypto.py @@ -1404,6 +1404,10 @@ class X509StoreContext(object): self._store_ctx = _ffi.gc(store_ctx, _lib.X509_STORE_CTX_free) self._store = store self._cert = certificate + # Make the store context available for use after instantiating this + # class by initializing it now. Per testing, subsequent calls to + # :py:meth:`_init` have no adverse affect. + self._init() def _init(self): @@ -1420,7 +1424,7 @@ class X509StoreContext(object): Internally cleans up the store context. The store context can then be reused with a new call to - :py:meth:`init`. + :py:meth:`_init`. """ _lib.X509_STORE_CTX_cleanup(self._store_ctx) @@ -1448,6 +1452,16 @@ class X509StoreContext(object): return X509StoreContextError(errors, pycert) + def set_store(self, store): + """ + Set the context's trust store. + + :param X509Store store: The certificates which will be trusted for the + purposes of any *future* verifications. + """ + self._store = store + + def verify_certificate(self): """ Verify a certificate in a context. @@ -1455,6 +1469,8 @@ class X509StoreContext(object): :param store_ctx: The :py:class:`X509StoreContext` to verify. :raises: Error """ + # Always re-initialize the store context in case + # :py:meth:`verify_certificate` is called multiple times. self._init() ret = _lib.X509_verify_cert(self._store_ctx) self._cleanup() diff --git a/OpenSSL/test/test_crypto.py b/OpenSSL/test/test_crypto.py index 0aac1e5..ca54176 100644 --- a/OpenSSL/test/test_crypto.py +++ b/OpenSSL/test/test_crypto.py @@ -3257,6 +3257,24 @@ class X509StoreContextTests(TestCase): self.assertEqual(e.certificate.get_subject().CN, 'intermediate-service') + def test_modification_pre_verify(self): + """ + :py:obj:`verify_certificate` can use a store context modified after + instantiation. + """ + store_bad = X509Store() + store_bad.add_cert(self.intermediate_cert) + store_good = X509Store() + store_good.add_cert(self.root_cert) + store_good.add_cert(self.intermediate_cert) + store_ctx = X509StoreContext(store_bad, self.intermediate_server_cert) + e = self.assertRaises(X509StoreContextError, store_ctx.verify_certificate) + self.assertEqual(e.args[0][2], 'unable to get issuer certificate') + self.assertEqual(e.certificate.get_subject().CN, 'intermediate') + store_ctx.set_store(store_good) + self.assertEqual(store_ctx.verify_certificate(), None) + + class SignVerifyTests(TestCase): """ |