Merge pull request #2188 from reaperhulk/improve-changelog

Improve changelog
diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst
index ea44a46..d400e66 100644
--- a/docs/development/test-vectors.rst
+++ b/docs/development/test-vectors.rst
@@ -233,6 +233,8 @@
 * ``cp_user_notice_no_explicit_text.pem`` - An RSA 2048 bit self-signed
   certificate containing a certificate policies extension with a user notice
   with no explicit text.
+* ``cp_invalid.pem`` - An RSA 2048 bit self-signed certificate containing a
+  certificate policies extension with invalid data.
 * ``ian_uri.pem`` - An RSA 2048 bit certificate containing an issuer
   alternative name extension with a ``URI`` general name.
 * ``ocsp_nocheck.pem`` - An RSA 2048 bit self-signed certificate containing
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
index db4f963..5ab46d4 100644
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -1577,13 +1577,15 @@
             if format is serialization.PrivateFormat.PKCS8:
                 write_bio = self._lib.PEM_write_bio_PKCS8PrivateKey
                 key = evp_pkey
-            elif format is serialization.PrivateFormat.TraditionalOpenSSL:
+            else:
+                assert format is serialization.PrivateFormat.TraditionalOpenSSL
                 if evp_pkey.type == self._lib.EVP_PKEY_RSA:
                     write_bio = self._lib.PEM_write_bio_RSAPrivateKey
                 elif evp_pkey.type == self._lib.EVP_PKEY_DSA:
                     write_bio = self._lib.PEM_write_bio_DSAPrivateKey
-                elif (self._lib.Cryptography_HAS_EC == 1 and
-                      evp_pkey.type == self._lib.EVP_PKEY_EC):
+                else:
+                    assert self._lib.Cryptography_HAS_EC == 1
+                    assert evp_pkey.type == self._lib.EVP_PKEY_EC
                     write_bio = self._lib.PEM_write_bio_ECPrivateKey
 
                 key = cdata
@@ -1600,7 +1602,8 @@
                 return self._private_key_bytes_traditional_der(
                     evp_pkey.type, cdata
                 )
-            elif format is serialization.PrivateFormat.PKCS8:
+            else:
+                assert format is serialization.PrivateFormat.PKCS8
                 write_bio = self._lib.i2d_PKCS8PrivateKey_bio
                 key = evp_pkey
         else:
@@ -1625,7 +1628,8 @@
         elif (self._lib.Cryptography_HAS_EC == 1 and
               key_type == self._lib.EVP_PKEY_EC):
             write_bio = self._lib.i2d_ECPrivateKey_bio
-        elif key_type == self._lib.EVP_PKEY_DSA:
+        else:
+            assert key_type == self._lib.EVP_PKEY_DSA
             write_bio = self._lib.i2d_DSAPrivateKey_bio
 
         bio = self._create_mem_bio()
@@ -1640,7 +1644,8 @@
         if format is serialization.PublicFormat.SubjectPublicKeyInfo:
             if encoding is serialization.Encoding.PEM:
                 write_bio = self._lib.PEM_write_bio_PUBKEY
-            elif encoding is serialization.Encoding.DER:
+            else:
+                assert encoding is serialization.Encoding.DER
                 write_bio = self._lib.i2d_PUBKEY_bio
 
             key = evp_pkey
@@ -1649,7 +1654,8 @@
             assert evp_pkey.type == self._lib.EVP_PKEY_RSA
             if encoding is serialization.Encoding.PEM:
                 write_bio = self._lib.PEM_write_bio_RSAPublicKey
-            elif encoding is serialization.Encoding.DER:
+            else:
+                assert encoding is serialization.Encoding.DER
                 write_bio = self._lib.i2d_RSAPublicKey_bio
 
             key = cdata
diff --git a/src/cryptography/hazmat/backends/openssl/rsa.py b/src/cryptography/hazmat/backends/openssl/rsa.py
index 21414c0..822c730 100644
--- a/src/cryptography/hazmat/backends/openssl/rsa.py
+++ b/src/cryptography/hazmat/backends/openssl/rsa.py
@@ -268,8 +268,9 @@
                     self._backend._lib.RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE):
                 reason = ("Salt length too long for key size. Try using "
                           "MAX_LENGTH instead.")
-            elif (errors[0].reason ==
-                    self._backend._lib.RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY):
+            else:
+                assert (errors[0].reason ==
+                        self._backend._lib.RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY)
                 reason = "Digest too large for key size. Use a larger key."
             assert reason is not None
             raise ValueError(reason)
diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py
index 63e4a17..ee9a3bb 100644
--- a/src/cryptography/hazmat/backends/openssl/x509.py
+++ b/src/cryptography/hazmat/backends/openssl/x509.py
@@ -235,7 +235,13 @@
                     )
             else:
                 d2i = backend._lib.X509V3_EXT_d2i(ext)
-                assert d2i != backend._ffi.NULL
+                if d2i == backend._ffi.NULL:
+                    backend._consume_errors()
+                    raise ValueError(
+                        "The {0} extension is invalid and can't be "
+                        "parsed".format(oid)
+                    )
+
                 value = handler(backend, d2i)
                 extensions.append(x509.Extension(oid, critical, value))
 
@@ -384,7 +390,8 @@
                         pqi.d.cpsuri.data, pqi.d.cpsuri.length
                     )[:].decode('ascii')
                     qualifiers.append(cpsuri)
-                elif pqualid == x509.OID_CPS_USER_NOTICE:
+                else:
+                    assert pqualid == x509.OID_CPS_USER_NOTICE
                     user_notice = _decode_user_notice(
                         backend, pqi.d.usernotice
                     )
@@ -744,35 +751,33 @@
         return self._backend._read_mem_bio(bio)
 
 
+_EXTENSION_HANDLERS = {
+    x509.OID_BASIC_CONSTRAINTS: _decode_basic_constraints,
+    x509.OID_SUBJECT_KEY_IDENTIFIER: _decode_subject_key_identifier,
+    x509.OID_KEY_USAGE: _decode_key_usage,
+    x509.OID_SUBJECT_ALTERNATIVE_NAME: _decode_subject_alt_name,
+    x509.OID_EXTENDED_KEY_USAGE: _decode_extended_key_usage,
+    x509.OID_AUTHORITY_KEY_IDENTIFIER: _decode_authority_key_identifier,
+    x509.OID_AUTHORITY_INFORMATION_ACCESS: (
+        _decode_authority_information_access
+    ),
+    x509.OID_CERTIFICATE_POLICIES: _decode_certificate_policies,
+    x509.OID_CRL_DISTRIBUTION_POINTS: _decode_crl_distribution_points,
+    x509.OID_OCSP_NO_CHECK: _decode_ocsp_no_check,
+    x509.OID_INHIBIT_ANY_POLICY: _decode_inhibit_any_policy,
+    x509.OID_ISSUER_ALTERNATIVE_NAME: _decode_issuer_alt_name,
+    x509.OID_NAME_CONSTRAINTS: _decode_name_constraints,
+}
+
+
 _CERTIFICATE_EXTENSION_PARSER = _X509ExtensionParser(
     ext_count=lambda backend, x: backend._lib.X509_get_ext_count(x),
     get_ext=lambda backend, x, i: backend._lib.X509_get_ext(x, i),
-    handlers={
-        x509.OID_BASIC_CONSTRAINTS: _decode_basic_constraints,
-        x509.OID_SUBJECT_KEY_IDENTIFIER: _decode_subject_key_identifier,
-        x509.OID_KEY_USAGE: _decode_key_usage,
-        x509.OID_SUBJECT_ALTERNATIVE_NAME: _decode_subject_alt_name,
-        x509.OID_EXTENDED_KEY_USAGE: _decode_extended_key_usage,
-        x509.OID_AUTHORITY_KEY_IDENTIFIER: _decode_authority_key_identifier,
-        x509.OID_AUTHORITY_INFORMATION_ACCESS: (
-            _decode_authority_information_access
-        ),
-        x509.OID_CERTIFICATE_POLICIES: _decode_certificate_policies,
-        x509.OID_CRL_DISTRIBUTION_POINTS: _decode_crl_distribution_points,
-        x509.OID_OCSP_NO_CHECK: _decode_ocsp_no_check,
-        x509.OID_INHIBIT_ANY_POLICY: _decode_inhibit_any_policy,
-        x509.OID_ISSUER_ALTERNATIVE_NAME: _decode_issuer_alt_name,
-        x509.OID_NAME_CONSTRAINTS: _decode_name_constraints,
-    }
+    handlers=_EXTENSION_HANDLERS
 )
 
 _CSR_EXTENSION_PARSER = _X509ExtensionParser(
     ext_count=lambda backend, x: backend._lib.sk_X509_EXTENSION_num(x),
     get_ext=lambda backend, x, i: backend._lib.sk_X509_EXTENSION_value(x, i),
-    handlers={
-        x509.OID_BASIC_CONSTRAINTS: _decode_basic_constraints,
-        x509.OID_KEY_USAGE: _decode_key_usage,
-        x509.OID_SUBJECT_ALTERNATIVE_NAME: _decode_subject_alt_name,
-        x509.OID_EXTENDED_KEY_USAGE: _decode_extended_key_usage,
-    }
+    handlers=_EXTENSION_HANDLERS
 )
diff --git a/tests/test_utils.py b/tests/test_utils.py
index f71264e..210e929 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -3045,8 +3045,13 @@
     assert expected == load_kasvs_dh_vectors(vector_data)
 
 
+def test_load_kasvs_ecdh_vectors_empty_vector_data():
+    assert [] == load_kasvs_ecdh_vectors([])
+
+
 def test_load_kasvs_ecdh_vectors():
     vector_data = textwrap.dedent("""
+    #  CAVS 11.0
     #  Parameter set(s) supported: EA EB EC ED EE
     #  CAVSid: CAVSid (in hex: 434156536964)
     #  IUTid: In hex: a1b2c3d4e5
diff --git a/tests/test_x509_ext.py b/tests/test_x509_ext.py
index 7b13582..890709a 100644
--- a/tests/test_x509_ext.py
+++ b/tests/test_x509_ext.py
@@ -2853,3 +2853,18 @@
             x509.OID_INHIBIT_ANY_POLICY
         ).value
         assert iap.skip_certs == 5
+
+
+@pytest.mark.requires_backend_interface(interface=RSABackend)
+@pytest.mark.requires_backend_interface(interface=X509Backend)
+class TestInvalidExtension(object):
+    def test_invalid_certificate_policies_data(self, backend):
+        cert = _load_cert(
+            os.path.join(
+                "x509", "custom", "cp_invalid.pem"
+            ),
+            x509.load_pem_x509_certificate,
+            backend
+        )
+        with pytest.raises(ValueError):
+            cert.extensions
diff --git a/tests/utils.py b/tests/utils.py
index 5083d48..7e7abdf 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -539,8 +539,8 @@
             elif line.startswith("Qy = "):
                 key_data["y"] = int(line.split("=")[1], 16)
 
-    if key_data is not None:
-        vectors.append(key_data)
+    assert key_data is not None
+    vectors.append(key_data)
 
     return vectors
 
@@ -559,9 +559,6 @@
     for line in vector_data:
         line = line.strip()
 
-        if not line or line.startswith("#"):
-            continue
-
         curve_match = curve_rx.match(line)
         if curve_match:
             curve_name = _ECDSA_CURVE_NAMES[curve_match.group("curve")]
@@ -593,8 +590,8 @@
             elif line.startswith("Result = "):
                 data["fail"] = line.split("=")[1].strip()[0] == "F"
 
-    if data is not None:
-        vectors.append(data)
+    assert data is not None
+    vectors.append(data)
     return vectors
 
 
diff --git a/vectors/cryptography_vectors/x509/custom/cp_invalid.pem b/vectors/cryptography_vectors/x509/custom/cp_invalid.pem
new file mode 100644
index 0000000..b7bcc07
--- /dev/null
+++ b/vectors/cryptography_vectors/x509/custom/cp_invalid.pem
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE-----
+MIIC8TCCAdmgAwIBAgITBmsoYWX1PCELRmm8qB2WJ2QdDjANBgkqhkiG9w0BAQUFADASMRAwDgYD
+VQQDDAdQeUNBIENBMB4XDTE1MDUxMTE4NTc0NVoXDTE2MDUxMDE4NTc0NVowEjEQMA4GA1UEAwwH
+UHlDQSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK3FTRITEY4b/Y1Uv4CtH61Y
+19TPxK2+H/XuqHwtYlPRyD35LLFES0wykf0V2m1DUmf9jQa9R63jBZxzCgJ/oIJzV28PgSg9P/Nn
+417fNASDduY2GPvYuwwKXcLY2fBBFjBrz7z/5tyXCADjLDkzoUTzQlYPbhOrFU5QwaqlckXBgt/4
+8GRDujoHy4RSMEDNjLUDgwx7Z/JK2ujbGJDguLRuBsHirk2h6xXEmSWxquKDXw4NnakwBqp8kKhQ
+2xTSWXxabNps8FCBM4sC78gKgONy3lbYdHFt/2BU4yAMyowJwtDEYHCqe1g4sVsB839Ol0SXb6vl
+eXQ6dx+zbi8UzTsCAwEAAaNAMD4wPAYDVR0gBDUwMzAxBgtghkgB4DkBAgMEATAiMCAGCCsGAQUF
+BwICFhRodHRwOi8vb3RoZXIuY29tL2NwczANBgkqhkiG9w0BAQUFAAOCAQEADpZIjHvu02euPNI8
+nzzDufRXEnjrF09xc9pudxTjWU2mSVApXPmTDyWzOD+2HmsNKHRE6sWjca5qPDeDbGq4JOw+TzYq
+9eoqwK2Sh0QHUpg5ZaAmIJ1qe5/sNETH5RFlXrlzW9S0rwViLgUaJp6MreTdGZbxdpNsfdkuNd+S
+Tz0MA/3ScbdUcj6uwQQ4JxQiTuPwD35pKwxfUzHjeTmqIEHDuCk17KqIRORdbeD3vFx0R5IQ3mQ6
+9zSGY2AGB0A9oS0qQ2/Mh59A6xyjbPH3Rr7g5MW58PPTWp2FSXkloy7Ze+doQ7wXE6PVmaeKz5qA
+9OGaCHIiC2iG9UcqWxfeWw==
+-----END CERTIFICATE-----