Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the ability to set a custom verification time on X509Store #567

Merged
merged 13 commits into from
Nov 22, 2016
3 changes: 2 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ Deprecations:
Changes:
^^^^^^^^

*none*
- Added ``OpenSSL.X509Store.set_time()`` to set a custom verification time when verifying certificate chains.
`#567 <https://github.com/pyca/pyopenssl/pull/567>`_


----
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def find_meta(meta):
package_dir={"": "src"},
install_requires=[
# Fix cryptographyMinimum in tox.ini when changing this!
"cryptography>=1.3.4",
"cryptography>=1.6",
"six>=1.5.2"
],
)
15 changes: 15 additions & 0 deletions src/OpenSSL/crypto.py
Original file line number Diff line number Diff line change
Expand Up @@ -1518,6 +1518,21 @@ def set_flags(self, flags):
"""
_openssl_assert(_lib.X509_STORE_set_flags(self._store, flags) != 0)

def set_time(self, vfy_time):
"""
Set verification time to this store.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Final thing: could you add a few more lines about the what that method is good for? Is that grammar even correct? Honest question. :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No problem. Not sure it was correct. It's updated.


.. versionadded: 16.3.0

:param datetime vfy_time: The verification time to set on this store.
:return: ``None`` if the verification time was successfully set.
"""
param = _lib.X509_VERIFY_PARAM_new()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll need to add a param = _ffi.gc(param, X509_VERIFY_PARAM_free) to this. X509_STORE_set1_param increfs it so without a corresponding free to decref after creation it will leak.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your feedback!

When I try:

from OpenSSL._util import lib
lib.X509_VERIFY_PARAM_free

I got this exception on my system: AttributeError: 'module' object has no attribute 'X509_VERIFY_PARAM_free'

It looks like X509_VERIFY_PARAM_free is not exported, I should do a PR on cryptography to export it? or something is wrong on my side?

Thanks!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, you're quite right it isn't currently exported in cryptography. Please do submit a PR there!

param = _ffi.gc(param, _lib.X509_VERIFY_PARAM_free)

_lib.X509_VERIFY_PARAM_set_time(param, int(vfy_time.strftime('%s')))
_openssl_assert(_lib.X509_STORE_set1_param(self._store, param) != 0)


X509StoreType = X509Store

Expand Down
21 changes: 21 additions & 0 deletions tests/test_crypto.py
Original file line number Diff line number Diff line change
Expand Up @@ -3740,6 +3740,27 @@ def test_modification_pre_verify(self):
store_ctx.set_store(store_good)
self.assertEqual(store_ctx.verify_certificate(), None)

def test_verify_with_time(self):
"""
`verify_certificate` raises error when the verification time is
set at notAfter.
"""
store = X509Store()
store.add_cert(self.root_cert)
store.add_cert(self.intermediate_cert)

expire_time = self.intermediate_server_cert.get_notAfter()
expire_datetime = datetime.strptime(
expire_time.decode('utf-8'), '%Y%m%d%H%M%SZ'
)
store.set_time(expire_datetime)

store_ctx = X509StoreContext(store, self.intermediate_server_cert)
with pytest.raises(X509StoreContextError) as exc:
store_ctx.verify_certificate()

assert exc.value.args[0][2] == 'certificate has expired'


class SignVerifyTests(TestCase):
"""
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ deps =
coverage>=4.2
pytest>=3.0.1
cryptographyMaster: git+https://github.com/pyca/cryptography.git
cryptographyMinimum: cryptography<1.4
cryptographyMinimum: cryptography<1.7
setenv =
# Do not allow the executing environment to pollute the test environment
# with extra packages.
Expand Down