Enlarge _oid2txt buffer to handle larger OIDs (#3612)

The OpenSSL manual recommends a buffer size of 80 for OBJ_oid2txt:
https://www.openssl.org/docs/crypto/OBJ_nid2ln.html#return_values.
But OIDs longer than this occur in real life (e.g. Active Directory
makes some very long OIDs).  If the length of the stringified OID
exceeds the buffer size, allocate a new buffer that is big enough to
hold the stringified OID, and re-do the conversion into the new
buffer.
diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst
index 868619a..a1d8b11 100644
--- a/docs/development/test-vectors.rst
+++ b/docs/development/test-vectors.rst
@@ -156,6 +156,9 @@
   RSA with SHA1.
 * ``badssl-sct.pem`` - A certificate with the certificate transparency signed
   certificate timestamp extension.
+* ``bigoid.pem`` - A certificate with a rather long OID in the
+  Certificate Policies extension.  We need to make sure we can parse
+  long OIDs.
 
 Custom X.509 Vectors
 ~~~~~~~~~~~~~~~~~~~~
diff --git a/src/cryptography/hazmat/backends/openssl/decode_asn1.py b/src/cryptography/hazmat/backends/openssl/decode_asn1.py
index 19df4c8..282e30f 100644
--- a/src/cryptography/hazmat/backends/openssl/decode_asn1.py
+++ b/src/cryptography/hazmat/backends/openssl/decode_asn1.py
@@ -24,9 +24,23 @@
 def _obj2txt(backend, obj):
     # Set to 80 on the recommendation of
     # https://www.openssl.org/docs/crypto/OBJ_nid2ln.html#return_values
+    #
+    # But OIDs longer than this occur in real life (e.g. Active
+    # Directory makes some very long OIDs).  So we need to detect
+    # and properly handle the case where the default buffer is not
+    # big enough.
+    #
     buf_len = 80
     buf = backend._ffi.new("char[]", buf_len)
+
+    # 'res' is the number of bytes that *would* be written if the
+    # buffer is large enough.  If 'res' > buf_len - 1, we need to
+    # alloc a big-enough buffer and go again.
     res = backend._lib.OBJ_obj2txt(buf, buf_len, obj, 1)
+    if res > buf_len - 1:  # account for terminating null byte
+        buf_len = res + 1
+        buf = backend._ffi.new("char[]", buf_len)
+        res = backend._lib.OBJ_obj2txt(buf, buf_len, obj, 1)
     backend.openssl_assert(res > 0)
     return backend._ffi.buffer(buf, res)[:].decode()
 
diff --git a/tests/test_x509_ext.py b/tests/test_x509_ext.py
index eaf5a51..b89abdd 100644
--- a/tests/test_x509_ext.py
+++ b/tests/test_x509_ext.py
@@ -409,6 +409,7 @@
         assert pi != object()
 
 
+@pytest.mark.requires_backend_interface(interface=X509Backend)
 class TestCertificatePolicies(object):
     def test_invalid_policies(self):
         pq = [u"string"]
@@ -481,6 +482,26 @@
         assert cp[-1] == cp[4]
         assert cp[2:6:2] == [cp[2], cp[4]]
 
+    def test_long_oid(self, backend):
+        """
+        Test that parsing a CertificatePolicies ext with
+        a very long OID succeeds.
+        """
+        cert = _load_cert(
+            os.path.join("x509", "bigoid.pem"),
+            x509.load_pem_x509_certificate,
+            backend
+        )
+        ext = cert.extensions.get_extension_for_class(
+            x509.CertificatePolicies)
+
+        oid = x509.ObjectIdentifier(
+            "1.3.6.1.4.1.311.21.8.8950086.10656446.2706058"
+            ".12775672.480128.147.13466065.13029902"
+        )
+
+        assert ext.value[0].policy_identifier == oid
+
 
 @pytest.mark.requires_backend_interface(interface=RSABackend)
 @pytest.mark.requires_backend_interface(interface=X509Backend)
diff --git a/vectors/cryptography_vectors/x509/bigoid.pem b/vectors/cryptography_vectors/x509/bigoid.pem
new file mode 100644
index 0000000..7bf865b
--- /dev/null
+++ b/vectors/cryptography_vectors/x509/bigoid.pem
@@ -0,0 +1,32 @@
+-----BEGIN CERTIFICATE-----
+MIIFiTCCBHGgAwIBAgITSAAAAAd1bEC5lsOdnQAAAAAABzANBgkqhkiG9w0BAQsF
+ADBLMRUwEwYKCZImiZPyLGQBGRYFbG9jYWwxEjAQBgoJkiaJk/IsZAEZFgJhZDEe
+MBwGA1UEAxMVYWQtV0lOLVBQSzAxNUY5TURRLUNBMB4XDTE3MDUyNTIzNDg0NVoX
+DTE5MDUyNTIzNTg0NVowNDESMBAGA1UEChMJSVBBLkxPQ0FMMR4wHAYDVQQDExVD
+ZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+AoIBAQDyyuty6irlL89hdaSW0UyAGLsOOMgAuJwBAeuRUorR159rsSnUXLcTHIsm
+EszKhwxp3NkkawRWx/s0UN1m2+RUwMl6gvlw+G80Mz0S77C77M+2lO8HRmZGm+Wu
+zBNcc9SANHuDQ1NISfZgLiscMS0+l0T3g6/Iqtg1kPWrq/tMevfh6tJEIedSBGo4
+3xKEMSDkrvaeTuSVrgn/QT0m+WNccZa0c7X35L/hgR22/l5sr057Ef8F9vL8zUH5
+TttFBIuiWJo8A8XX9I1zYIFhWjW3OVDZPBUnhGHH6yNyXGxXMRfcrrc74eTw8ivC
+080AQuRtgwvDErB/JPDJ5w5t/ielAgMBAAGjggJ7MIICdzA9BgkrBgEEAYI3FQcE
+MDAuBiYrBgEEAYI3FQiEoqJGhYq1PoGllQqGi+F4nacAgRODs5gfgozzAAIBZAIB
+BTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUnSrC
+yW3CR0e3ilJdN6kL06P3KHMwHwYDVR0jBBgwFoAUj69xtyUNwp8on+NWO+HlxKyg
+X7AwgdgGA1UdHwSB0DCBzTCByqCBx6CBxIaBwWxkYXA6Ly8vQ049YWQtV0lOLVBQ
+SzAxNUY5TURRLUNBLENOPVdJTi1QUEswMTVGOU1EUSxDTj1DRFAsQ049UHVibGlj
+JTIwS2V5JTIwU2VydmljZXMsQ049U2VydmljZXMsQ049Q29uZmlndXJhdGlvbixE
+Qz1hZCxEQz1sb2NhbD9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0P2Jhc2U/b2Jq
+ZWN0Q2xhc3M9Y1JMRGlzdHJpYnV0aW9uUG9pbnQwgcQGCCsGAQUFBwEBBIG3MIG0
+MIGxBggrBgEFBQcwAoaBpGxkYXA6Ly8vQ049YWQtV0lOLVBQSzAxNUY5TURRLUNB
+LENOPUFJQSxDTj1QdWJsaWMlMjBLZXklMjBTZXJ2aWNlcyxDTj1TZXJ2aWNlcyxD
+Tj1Db25maWd1cmF0aW9uLERDPWFkLERDPWxvY2FsP2NBQ2VydGlmaWNhdGU/YmFz
+ZT9vYmplY3RDbGFzcz1jZXJ0aWZpY2F0aW9uQXV0aG9yaXR5MDMGA1UdIAQsMCow
+KAYmKwYBBAGCNxUIhKKiRoWKtT6BpZUKhovheJ2nAIEThrXzUYabpA4wDQYJKoZI
+hvcNAQELBQADggEBAIsFS+Qc/ufTrkuHbMmzksOpxq+OIi9rot8zy9/1Vmj6d+iP
+kB+vQ1u4/IhdQArJFNhsBzWSY9Pi8ZclovpepFeEZfXPUenyeRCU43HdMXcHXnlP
+YZfyLQWOugdo1WxK6S9qQSOSlC7BSGZWvKkiAPAwr4zNbbS+ROA2w0xaYMv0rr5W
+A4UAyzZAdqaGRJBRvCZ/uFHM5wMw0LzNCL4CqKW9jfZX0Fc2tdGx8zbTYxIdgr2D
+PL25as32r3S/m4uWqoQaK0lxK5Y97eusK2rrmidy32Jctzwl29UWq8kpjRAuD8iR
+CSc7sKqOf+fn3+fKITR2/DcSVvb0SGCr5fVVnjQ=
+-----END CERTIFICATE-----