e65c7f
From 53e182c619774669ad4e54d3ed9fc03155cd2741 Mon Sep 17 00:00:00 2001
e65c7f
From: Christian Heimes <cheimes@redhat.com>
e65c7f
Date: Mon, 13 Feb 2017 21:28:02 -0600
e65c7f
Subject: [PATCH 3/4] Refactor binding initialization to allow specified errors
e65c7f
 (#3278)
e65c7f
e65c7f
If pyca/cryptography sees any errors on the error stack during its own
e65c7f
initialization it immediately raises InternalError and refuses to
e65c7f
proceed. This was a safety measure since we weren't sure if it was
e65c7f
safe to proceed. However, reality has intervened and we have to
e65c7f
bow to the god of pragmatism and just clear the error queue. In
e65c7f
practice this is safe since we religiously check the error queue
e65c7f
in operation.
e65c7f
e65c7f
Fixes RHBZ #1402235
e65c7f
---
e65c7f
 src/cryptography/hazmat/bindings/openssl/binding.py |  7 ++++++-
e65c7f
 tests/hazmat/bindings/test_openssl.py               | 16 +++++++++++++++-
e65c7f
 2 files changed, 21 insertions(+), 2 deletions(-)
e65c7f
e65c7f
diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py
e65c7f
index 39750abc..096faf5c 100644
e65c7f
--- a/src/cryptography/hazmat/bindings/openssl/binding.py
e65c7f
+++ b/src/cryptography/hazmat/bindings/openssl/binding.py
e65c7f
@@ -111,7 +111,12 @@ class Binding(object):
e65c7f
 
e65c7f
     @classmethod
e65c7f
     def _register_osrandom_engine(cls):
e65c7f
-        _openssl_assert(cls.lib, cls.lib.ERR_peek_error() == 0)
e65c7f
+        # Clear any errors extant in the queue before we start. In many
e65c7f
+        # scenarios other things may be interacting with OpenSSL in the same
e65c7f
+        # process space and it has proven untenable to assume that they will
e65c7f
+        # reliably clear the error queue. Once we clear it here we will
e65c7f
+        # error on any subsequent unexpected item in the stack.
e65c7f
+        cls.lib.ERR_clear_error()
e65c7f
         cls._osrandom_engine_id = cls.lib.Cryptography_osrandom_engine_id
e65c7f
         cls._osrandom_engine_name = cls.lib.Cryptography_osrandom_engine_name
e65c7f
         result = cls.lib.Cryptography_add_osrandom_engine()
e65c7f
diff --git a/tests/hazmat/bindings/test_openssl.py b/tests/hazmat/bindings/test_openssl.py
e65c7f
index 3e01717c..854615f1 100644
e65c7f
--- a/tests/hazmat/bindings/test_openssl.py
e65c7f
+++ b/tests/hazmat/bindings/test_openssl.py
e65c7f
@@ -8,7 +8,8 @@ import pytest
e65c7f
 
e65c7f
 from cryptography.exceptions import InternalError
e65c7f
 from cryptography.hazmat.bindings.openssl.binding import (
e65c7f
-    Binding, _OpenSSLErrorWithText, _openssl_assert, _verify_openssl_version
e65c7f
+    Binding, _OpenSSLErrorWithText, _consume_errors, _openssl_assert,
e65c7f
+    _verify_openssl_version
e65c7f
 )
e65c7f
 
e65c7f
 
e65c7f
@@ -108,8 +109,21 @@ class TestOpenSSL(object):
e65c7f
             )
e65c7f
         )]
e65c7f
 
e65c7f
+
e65c7f
     def test_verify_openssl_version(self, monkeypatch):
e65c7f
         monkeypatch.delenv("CRYPTOGRAPHY_ALLOW_OPENSSL_100", raising=False)
e65c7f
         with pytest.raises(RuntimeError):
e65c7f
             # OpenSSL 1.0.0
e65c7f
             _verify_openssl_version(0x100000F)
e65c7f
+
e65c7f
+    def test_check_startup_errors_are_allowed(self):
e65c7f
+        b = Binding()
e65c7f
+        b.lib.ERR_put_error(
e65c7f
+            b.lib.ERR_LIB_EVP,
e65c7f
+            b.lib.EVP_F_EVP_ENCRYPTFINAL_EX,
e65c7f
+            b.lib.EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH,
e65c7f
+            b"",
e65c7f
+            -1
e65c7f
+        )
e65c7f
+        b._register_osrandom_engine()
e65c7f
+        assert _consume_errors(b.lib) == []
e65c7f
-- 
e65c7f
2.13.5
e65c7f