Blame SOURCES/0004-Enlarge-_oid2txt-buffer-to-handle-larger-OIDs-3612.patch

bd0556
From fb637b7c58e42d7c99558276ffaabec1878bf97d Mon Sep 17 00:00:00 2001
bd0556
From: Christian Heimes <cheimes@redhat.com>
bd0556
Date: Mon, 29 May 2017 16:33:20 -0500
bd0556
Subject: [PATCH 4/4] Enlarge _oid2txt buffer to handle larger OIDs (#3612)
bd0556
bd0556
The OpenSSL manual recommends a buffer size of 80 for OBJ_oid2txt:
bd0556
https://www.openssl.org/docs/crypto/OBJ_nid2ln.html#return_values.
bd0556
But OIDs longer than this occur in real life (e.g. Active Directory
bd0556
makes some very long OIDs).  If the length of the stringified OID
bd0556
exceeds the buffer size, allocate a new buffer that is big enough to
bd0556
hold the stringified OID, and re-do the conversion into the new
bd0556
buffer.
bd0556
bd0556
NOTE: bigoid.pem has been moved to tests/.
bd0556
bd0556
Fixes RHBZ #1455755
bd0556
---
bd0556
 docs/development/test-vectors.rst                  |  3 ++
bd0556
 .../hazmat/backends/openssl/decode_asn1.py         | 14 ++++++++++
bd0556
 tests/bigoid.pem                                   | 32 ++++++++++++++++++++++
bd0556
 tests/test_x509_ext.py                             | 19 +++++++++++++
bd0556
 4 files changed, 68 insertions(+)
bd0556
 create mode 100644 tests/bigoid.pem
bd0556
bd0556
diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst
bd0556
index fb72240d..bc72a470 100644
bd0556
--- a/docs/development/test-vectors.rst
bd0556
+++ b/docs/development/test-vectors.rst
bd0556
@@ -127,6 +127,9 @@ X.509
bd0556
 * ``alternate-rsa-sha1-oid.pem`` - A certificate from an
bd0556
   `unknown signature OID`_ Mozilla bug that uses an alternate signature OID for
bd0556
   RSA with SHA1.
bd0556
+* ``bigoid.pem`` - A certificate with a rather long OID in the
bd0556
+  Certificate Policies extension.  We need to make sure we can parse
bd0556
+  long OIDs.
bd0556
 
bd0556
 Custom X.509 Vectors
bd0556
 ~~~~~~~~~~~~~~~~~~~~
bd0556
diff --git a/src/cryptography/hazmat/backends/openssl/decode_asn1.py b/src/cryptography/hazmat/backends/openssl/decode_asn1.py
bd0556
index 2cbc349e..5a23da25 100644
bd0556
--- a/src/cryptography/hazmat/backends/openssl/decode_asn1.py
bd0556
+++ b/src/cryptography/hazmat/backends/openssl/decode_asn1.py
bd0556
@@ -24,9 +24,23 @@ from cryptography.x509.oid import (
bd0556
 def _obj2txt(backend, obj):
bd0556
     # Set to 80 on the recommendation of
bd0556
     # https://www.openssl.org/docs/crypto/OBJ_nid2ln.html#return_values
bd0556
+    #
bd0556
+    # But OIDs longer than this occur in real life (e.g. Active
bd0556
+    # Directory makes some very long OIDs).  So we need to detect
bd0556
+    # and properly handle the case where the default buffer is not
bd0556
+    # big enough.
bd0556
+    #
bd0556
     buf_len = 80
bd0556
     buf = backend._ffi.new("char[]", buf_len)
bd0556
+
bd0556
+    # 'res' is the number of bytes that *would* be written if the
bd0556
+    # buffer is large enough.  If 'res' > buf_len - 1, we need to
bd0556
+    # alloc a big-enough buffer and go again.
bd0556
     res = backend._lib.OBJ_obj2txt(buf, buf_len, obj, 1)
bd0556
+    if res > buf_len - 1:  # account for terminating null byte
bd0556
+        buf_len = res + 1
bd0556
+        buf = backend._ffi.new("char[]", buf_len)
bd0556
+        res = backend._lib.OBJ_obj2txt(buf, buf_len, obj, 1)
bd0556
     backend.openssl_assert(res > 0)
bd0556
     return backend._ffi.buffer(buf, res)[:].decode()
bd0556
 
bd0556
diff --git a/tests/bigoid.pem b/tests/bigoid.pem
bd0556
new file mode 100644
bd0556
index 00000000..7bf865bf
bd0556
--- /dev/null
bd0556
+++ b/tests/bigoid.pem
bd0556
@@ -0,0 +1,32 @@
bd0556
+-----BEGIN CERTIFICATE-----
bd0556
+MIIFiTCCBHGgAwIBAgITSAAAAAd1bEC5lsOdnQAAAAAABzANBgkqhkiG9w0BAQsF
bd0556
+ADBLMRUwEwYKCZImiZPyLGQBGRYFbG9jYWwxEjAQBgoJkiaJk/IsZAEZFgJhZDEe
bd0556
+MBwGA1UEAxMVYWQtV0lOLVBQSzAxNUY5TURRLUNBMB4XDTE3MDUyNTIzNDg0NVoX
bd0556
+DTE5MDUyNTIzNTg0NVowNDESMBAGA1UEChMJSVBBLkxPQ0FMMR4wHAYDVQQDExVD
bd0556
+ZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
bd0556
+AoIBAQDyyuty6irlL89hdaSW0UyAGLsOOMgAuJwBAeuRUorR159rsSnUXLcTHIsm
bd0556
+EszKhwxp3NkkawRWx/s0UN1m2+RUwMl6gvlw+G80Mz0S77C77M+2lO8HRmZGm+Wu
bd0556
+zBNcc9SANHuDQ1NISfZgLiscMS0+l0T3g6/Iqtg1kPWrq/tMevfh6tJEIedSBGo4
bd0556
+3xKEMSDkrvaeTuSVrgn/QT0m+WNccZa0c7X35L/hgR22/l5sr057Ef8F9vL8zUH5
bd0556
+TttFBIuiWJo8A8XX9I1zYIFhWjW3OVDZPBUnhGHH6yNyXGxXMRfcrrc74eTw8ivC
bd0556
+080AQuRtgwvDErB/JPDJ5w5t/ielAgMBAAGjggJ7MIICdzA9BgkrBgEEAYI3FQcE
bd0556
+MDAuBiYrBgEEAYI3FQiEoqJGhYq1PoGllQqGi+F4nacAgRODs5gfgozzAAIBZAIB
bd0556
+BTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUnSrC
bd0556
+yW3CR0e3ilJdN6kL06P3KHMwHwYDVR0jBBgwFoAUj69xtyUNwp8on+NWO+HlxKyg
bd0556
+X7AwgdgGA1UdHwSB0DCBzTCByqCBx6CBxIaBwWxkYXA6Ly8vQ049YWQtV0lOLVBQ
bd0556
+SzAxNUY5TURRLUNBLENOPVdJTi1QUEswMTVGOU1EUSxDTj1DRFAsQ049UHVibGlj
bd0556
+JTIwS2V5JTIwU2VydmljZXMsQ049U2VydmljZXMsQ049Q29uZmlndXJhdGlvbixE
bd0556
+Qz1hZCxEQz1sb2NhbD9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0P2Jhc2U/b2Jq
bd0556
+ZWN0Q2xhc3M9Y1JMRGlzdHJpYnV0aW9uUG9pbnQwgcQGCCsGAQUFBwEBBIG3MIG0
bd0556
+MIGxBggrBgEFBQcwAoaBpGxkYXA6Ly8vQ049YWQtV0lOLVBQSzAxNUY5TURRLUNB
bd0556
+LENOPUFJQSxDTj1QdWJsaWMlMjBLZXklMjBTZXJ2aWNlcyxDTj1TZXJ2aWNlcyxD
bd0556
+Tj1Db25maWd1cmF0aW9uLERDPWFkLERDPWxvY2FsP2NBQ2VydGlmaWNhdGU/YmFz
bd0556
+ZT9vYmplY3RDbGFzcz1jZXJ0aWZpY2F0aW9uQXV0aG9yaXR5MDMGA1UdIAQsMCow
bd0556
+KAYmKwYBBAGCNxUIhKKiRoWKtT6BpZUKhovheJ2nAIEThrXzUYabpA4wDQYJKoZI
bd0556
+hvcNAQELBQADggEBAIsFS+Qc/ufTrkuHbMmzksOpxq+OIi9rot8zy9/1Vmj6d+iP
bd0556
+kB+vQ1u4/IhdQArJFNhsBzWSY9Pi8ZclovpepFeEZfXPUenyeRCU43HdMXcHXnlP
bd0556
+YZfyLQWOugdo1WxK6S9qQSOSlC7BSGZWvKkiAPAwr4zNbbS+ROA2w0xaYMv0rr5W
bd0556
+A4UAyzZAdqaGRJBRvCZ/uFHM5wMw0LzNCL4CqKW9jfZX0Fc2tdGx8zbTYxIdgr2D
bd0556
+PL25as32r3S/m4uWqoQaK0lxK5Y97eusK2rrmidy32Jctzwl29UWq8kpjRAuD8iR
bd0556
+CSc7sKqOf+fn3+fKITR2/DcSVvb0SGCr5fVVnjQ=
bd0556
+-----END CERTIFICATE-----
bd0556
diff --git a/tests/test_x509_ext.py b/tests/test_x509_ext.py
bd0556
index 00cf0a6f..91df35db 100644
bd0556
--- a/tests/test_x509_ext.py
bd0556
+++ b/tests/test_x509_ext.py
bd0556
@@ -409,6 +409,7 @@ class TestPolicyInformation(object):
bd0556
         assert pi != object()
bd0556
 
bd0556
 
bd0556
+@pytest.mark.requires_backend_interface(interface=X509Backend)
bd0556
 class TestCertificatePolicies(object):
bd0556
     def test_invalid_policies(self):
bd0556
         pq = [u"string"]
bd0556
@@ -481,6 +482,24 @@ class TestCertificatePolicies(object):
bd0556
         assert cp[-1] == cp[4]
bd0556
         assert cp[2:6:2] == [cp[2], cp[4]]
bd0556
 
bd0556
+    def test_long_oid(self, backend):
bd0556
+        """
bd0556
+        Test that parsing a CertificatePolicies ext with
bd0556
+        a very long OID succeeds.
bd0556
+        """
bd0556
+        here = os.path.dirname(os.path.abspath(__file__))
bd0556
+        with open(os.path.join(here, "bigoid.pem"), 'rb') as f:
bd0556
+            cert = x509.load_pem_x509_certificate(f.read(), backend)
bd0556
+        ext = cert.extensions.get_extension_for_class(
bd0556
+            x509.CertificatePolicies)
bd0556
+
bd0556
+        oid = x509.ObjectIdentifier(
bd0556
+            "1.3.6.1.4.1.311.21.8.8950086.10656446.2706058"
bd0556
+            ".12775672.480128.147.13466065.13029902"
bd0556
+        )
bd0556
+
bd0556
+        assert ext.value[0].policy_identifier == oid
bd0556
+
bd0556
 
bd0556
 @pytest.mark.requires_backend_interface(interface=RSABackend)
bd0556
 @pytest.mark.requires_backend_interface(interface=X509Backend)
bd0556
-- 
bd0556
2.13.5
bd0556