pyopenssl icon indicating copy to clipboard operation
pyopenssl copied to clipboard

test_verify_with_time test fails on i686

Open raboof opened this issue 3 years ago • 4 comments

When packaging on NixOS, we noticed a test failure when building pyOpenSSL 20.0.0 for the i686 architecture:

============================= test session starts ==============================
platform linux -- Python 3.8.6, pytest-6.1.2, py-1.9.0, pluggy-0.13.1
OpenSSL: b'OpenSSL 1.1.1h  22 Sep 2020'
cryptography: 3.2.1
rootdir: /build/pyOpenSSL-20.0.0, configfile: setup.cfg, testpaths: tests
plugins: flaky-3.7.0
collected 525 items / 8 deselected / 517 selected                              

tests/test_crypto.py ................................................... [  9%]
........................................................................ [ 23%]
........................................................................ [ 37%]
.........................................................F.............. [ 51%]
...............                                                          [ 54%]
tests/test_debug.py .                                                    [ 54%]
tests/test_rand.py ....                                                  [ 55%]
tests/test_ssl.py ...................................................... [ 65%]
........................................................................ [ 79%]
........................................ss.............s................ [ 93%]
...............................                                          [ 99%]
tests/test_util.py .                                                     [100%]

=================================== FAILURES ===================================
__________________ TestX509StoreContext.test_verify_with_time __________________

self = <tests.test_crypto.TestX509StoreContext object at 0xf60239d0>

    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)

tests/test_crypto.py:4111:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <OpenSSL.crypto.X509Store object at 0xf6023b98>
vfy_time = datetime.datetime(2047, 12, 20, 17, 11, 20)

    def set_time(self, vfy_time):
        """
        Set the time against which the certificates are verified.

        Normally the current time is used.

        .. note::

          For example, you can determine if a certificate was valid at a given
          time.

        .. versionadded:: 17.0.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()
        param = _ffi.gc(param, _lib.X509_VERIFY_PARAM_free)

>       _lib.X509_VERIFY_PARAM_set_time(
            param, calendar.timegm(vfy_time.timetuple())
        )
E       OverflowError: integer 2460474680 does not fit '32-bit int'

/nix/store/8z8f06f2m5j99g8jip6wk1s7fl1gjhl4-python3.8-pyOpenSSL-20.0.0/lib/python3.8/site-packages/OpenSSL/crypto.py:1679: OverflowError
=============================== warnings summary ===============================
../../nix/store/a5f5xkh9jbclv1yqq7j7rj49wivkvrmd-python3.8-pytest-6.1.2/lib/python3.8/site-packages/_pytest/config/__init__.py:1230
  /nix/store/a5f5xkh9jbclv1yqq7j7rj49wivkvrmd-python3.8-pytest-6.1.2/lib/python3.8/site-packages/_pytest/config/__init__.py:1230: PytestConfigWarning: Unknown config option: strict

    self._warn_or_fail_if_strict("Unknown config option: {}\n".format(key))

tests/test_crypto.py:39
  /build/pyOpenSSL-20.0.0/tests/test_crypto.py:39: DeprecationWarning: PKCS#7 support in pyOpenSSL is deprecated. You should use the APIs in cryptography.
    from OpenSSL.crypto import PKCS7, load_pkcs7_data

tests/test_crypto.py:40
  /build/pyOpenSSL-20.0.0/tests/test_crypto.py:40: DeprecationWarning: PKCS#12 support in pyOpenSSL is deprecated. You should use the APIs in cryptography.
    from OpenSSL.crypto import PKCS12, load_pkcs12

tests/test_ssl.py::TestContext::test_set_cipher_list[hello world:AES128-SHA1]
  /build/pyOpenSSL-20.0.0/tests/test_ssl.py:493: DeprecationWarning: str for cipher_list is no longer accepted, use bytes
    context.set_cipher_list(cipher_string)

tests/test_ssl.py::TestConnection::test_client_set_session
  /build/pyOpenSSL-20.0.0/tests/test_ssl.py:2637: DeprecationWarning: str for buf is no longer accepted, use bytes
    ctx.set_session_id("unity-test")

-- Docs: https://docs.pytest.org/en/stable/warnings.html
===Flaky Test Report===

test_gmtime_adj_notBefore passed 1 out of the required 1 times. Success!
test_gmtime_adj_notAfter passed 1 out of the required 1 times. Success!
test_set_cipher_list_no_cipher_match passed 1 out of the required 1 times. Success!

===End Flaky Test Report===
=========================== short test summary info ============================
FAILED tests/test_crypto.py::TestX509StoreContext::test_verify_with_time - Ov...
===== 1 failed, 513 passed, 3 skipped, 8 deselected, 5 warnings in 11.38s ======

https://github.com/NixOS/nixpkgs/pull/105454#issuecomment-743973848

raboof avatar Dec 13 '20 09:12 raboof

Was this test passing previously? This logic changed in https://github.com/pyca/pyopenssl/pull/907, but fundamentally this OpenSSL API still takes a time_t, which on x86 (not x86_64) time_t is defined as a 32-bit value. Unfortunately this means verification past int32 max won't work. OpenSSL may have other APIs for this, but someone will need to do the research.

reaperhulk avatar Dec 13 '20 21:12 reaperhulk

Was this test passing previously?

It does seem to pass on version 19.1.0 (tested with python 3.8). It also seems to succeed on 19.1.0 with #907 cherry-picked on top of it. I'm not sure I can easily bisect where it started failing, though.

raboof avatar Dec 15 '20 11:12 raboof

I would expect https://github.com/pyca/pyopenssl/pull/927 is what caused the failure since that's where we updated the root cert to expire > 2038.

reaperhulk avatar Dec 16 '20 17:12 reaperhulk

Same test fails on 32-bit arm (https://bugs.gentoo.org/763993), and this issue looks similar to #684

DarthGandalf avatar Jan 06 '21 14:01 DarthGandalf