remove a lot of if/elif chains in the certificate builder
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
index c583214..faa3ee5 100644
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -473,6 +473,21 @@
     return pp, r
 
 
+_EXTENSION_ENCODE_HANDLERS = {
+    x509.OID_BASIC_CONSTRAINTS: _encode_basic_constraints,
+    x509.OID_SUBJECT_KEY_IDENTIFIER: _encode_subject_key_identifier,
+    x509.OID_KEY_USAGE: _encode_key_usage,
+    x509.OID_SUBJECT_ALTERNATIVE_NAME: _encode_subject_alt_name,
+    x509.OID_EXTENDED_KEY_USAGE: _encode_extended_key_usage,
+    x509.OID_AUTHORITY_KEY_IDENTIFIER: _encode_authority_key_identifier,
+    x509.OID_AUTHORITY_INFORMATION_ACCESS: (
+        _encode_authority_information_access
+    ),
+    x509.OID_CRL_DISTRIBUTION_POINTS: _encode_crl_distribution_points,
+    x509.OID_INHIBIT_ANY_POLICY: _encode_inhibit_any_policy,
+}
+
+
 @utils.register_interface(CipherBackend)
 @utils.register_interface(CMACBackend)
 @utils.register_interface(DERSerializationBackend)
@@ -1279,29 +1294,10 @@
 
         # Add extensions.
         for i, extension in enumerate(builder._extensions):
-            if isinstance(extension.value, x509.BasicConstraints):
-                pp, r = _encode_basic_constraints(self, extension.value)
-            elif isinstance(extension.value, x509.AuthorityKeyIdentifier):
-                pp, r = _encode_authority_key_identifier(self, extension.value)
-            elif isinstance(extension.value, x509.KeyUsage):
-                pp, r = _encode_key_usage(self, extension.value)
-            elif isinstance(extension.value, x509.InhibitAnyPolicy):
-                pp, r = _encode_inhibit_any_policy(self, extension.value)
-            elif isinstance(extension.value, x509.ExtendedKeyUsage):
-                pp, r = _encode_extended_key_usage(self, extension.value)
-            elif isinstance(extension.value, x509.SubjectAlternativeName):
-                pp, r = _encode_subject_alt_name(self, extension.value)
-            elif isinstance(extension.value, x509.SubjectKeyIdentifier):
-                pp, r = _encode_subject_key_identifier(self, extension.value)
-            elif isinstance(extension.value, x509.AuthorityInformationAccess):
-                pp, r = _encode_authority_information_access(
-                    self, extension.value
-                )
-            elif isinstance(extension.value, x509.CRLDistributionPoints):
-                pp, r = _encode_crl_distribution_points(
-                    self, extension.value
-                )
-            else:
+            try:
+                encode = _EXTENSION_ENCODE_HANDLERS[extension.oid]
+                pp, r = encode(self, extension.value)
+            except KeyError:
                 raise NotImplementedError('Extension not yet supported.')
 
             obj = _txt2obj_gc(self, extension.oid.dotted_string)
diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py
index bcda721..7b1de8b 100644
--- a/src/cryptography/x509.py
+++ b/src/cryptography/x509.py
@@ -1810,40 +1810,10 @@
         """
         Adds an X.509 extension to the certificate.
         """
-        if isinstance(extension, BasicConstraints):
-            extension = Extension(OID_BASIC_CONSTRAINTS, critical, extension)
-        elif isinstance(extension, AuthorityKeyIdentifier):
-            extension = Extension(
-                OID_AUTHORITY_KEY_IDENTIFIER, critical, extension
-            )
-        elif isinstance(extension, KeyUsage):
-            extension = Extension(OID_KEY_USAGE, critical, extension)
-        elif isinstance(extension, InhibitAnyPolicy):
-            extension = Extension(OID_INHIBIT_ANY_POLICY, critical, extension)
-        elif isinstance(extension, ExtendedKeyUsage):
-            extension = Extension(OID_EXTENDED_KEY_USAGE, critical, extension)
-        elif isinstance(extension, SubjectAlternativeName):
-            extension = Extension(
-                OID_SUBJECT_ALTERNATIVE_NAME, critical, extension
-            )
-        elif isinstance(extension, AuthorityInformationAccess):
-            extension = Extension(
-                OID_AUTHORITY_INFORMATION_ACCESS, critical, extension
-            )
-        elif isinstance(extension, SubjectKeyIdentifier):
-            extension = Extension(
-                OID_SUBJECT_KEY_IDENTIFIER, critical, extension
-            )
-        elif isinstance(extension, CRLDistributionPoints):
-            extension = Extension(
-                OID_CRL_DISTRIBUTION_POINTS, critical, extension
-            )
-        elif isinstance(extension, IssuerAlternativeName):
-            extension = Extension(
-                OID_ISSUER_ALTERNATIVE_NAME, critical, extension
-            )
-        else:
-            raise NotImplementedError('Unsupported X.509 extension.')
+        if not isinstance(extension, ExtensionType):
+            raise TypeError("extension must be an ExtensionType")
+
+        extension = Extension(extension.oid, critical, extension)
 
         # TODO: This is quadratic in the number of extensions
         for e in self._extensions:
diff --git a/tests/test_x509.py b/tests/test_x509.py
index b630e33..e0f8d57 100644
--- a/tests/test_x509.py
+++ b/tests/test_x509.py
@@ -1064,10 +1064,10 @@
                 x509.BasicConstraints(ca=False, path_length=None), True,
             )
 
-    def test_add_unsupported_extension(self):
+    def test_add_invalid_extension_type(self):
         builder = x509.CertificateBuilder()
 
-        with pytest.raises(NotImplementedError):
+        with pytest.raises(TypeError):
             builder.add_extension(object(), False)
 
     @pytest.mark.requires_backend_interface(interface=RSABackend)