rework BasicConstraints and Extension.
diff --git a/docs/x509.rst b/docs/x509.rst
index 8024258..7eb47a3 100644
--- a/docs/x509.rst
+++ b/docs/x509.rst
@@ -280,7 +280,11 @@
 
     .. versionadded:: 0.9
 
-    All X.509 extensions are registered against this interface.
+    .. attribute:: oid
+
+        :type: :class:`ObjectIdentifier`
+
+        The attribute OID.
 
     .. attribute:: critical
 
@@ -288,13 +292,18 @@
 
         Determines whether a given extension is critical or not.
 
+    .. attribute:: value
+
+        Returns an instance of the extension type corresponding to the OID.
+
 .. class:: BasicConstraints
 
     .. versionadded:: 0.9
 
-    Basic constraints is an X.509 extension that defines whether a given
+    Basic constraints is an X.509 extension type that defines whether a given
     certificate is allowed to sign additional certificates and what path
-    length restrictions may exist.
+    length restrictions may exist. It corresponds to
+    :data:`OID_BASIC_CONSTRAINTS`.
 
     .. attribute:: ca
 
diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py
index 510e9c6..d64d61f 100644
--- a/src/cryptography/x509.py
+++ b/src/cryptography/x509.py
@@ -42,6 +42,7 @@
     "1.2.840.10040.4.3": "dsa-with-sha1",
     "2.16.840.1.101.3.4.3.1": "dsa-with-sha224",
     "2.16.840.1.101.3.4.3.2": "dsa-with-sha256",
+    "2.5.29.19": "basicConstraints",
 }
 
 
@@ -144,26 +145,36 @@
 OID_BASIC_CONSTRAINTS = ObjectIdentifier("2.5.29.19")
 
 
-@six.add_metaclass(abc.ABCMeta)
 class Extension(object):
-    @abc.abstractproperty
-    def critical(self):
-        """
-        Returns the boolean value of the critical extension field.
-        """
-
-
-@utils.register_interface(Extension)
-class BasicConstraints(object):
-    oid = OID_BASIC_CONSTRAINTS
-
-    def __init__(self, ca, path_length, critical):
-        if not isinstance(ca, bool):
-            raise TypeError("ca must be a boolean value")
+    def __init__(self, oid, critical, value):
+        if not isinstance(oid, ObjectIdentifier):
+            raise TypeError(
+                "oid argument must be an ObjectIdentifier instance."
+            )
 
         if not isinstance(critical, bool):
             raise TypeError("critical must be a boolean value")
 
+        self._oid = oid
+        self._critical = critical
+        self._value = value
+
+    oid = utils.read_only_property("_oid")
+    critical = utils.read_only_property("_critical")
+    value = utils.read_only_property("_value")
+
+    def __repr__(self):
+        return ("<Extension(oid={oid}, "
+                "critical={critical}, value={value})>").format(
+            oid=self.oid, critical=self.critical, value=self.value
+        )
+
+
+class BasicConstraints(object):
+    def __init__(self, ca, path_length):
+        if not isinstance(ca, bool):
+            raise TypeError("ca must be a boolean value")
+
         if path_length is not None and ca is False:
             raise ValueError("path_length must be None when ca is False")
 
@@ -175,17 +186,14 @@
 
         self._ca = ca
         self._path_length = path_length
-        self._critical = critical
 
     ca = utils.read_only_property("_ca")
     path_length = utils.read_only_property("_path_length")
-    critical = utils.read_only_property("_critical")
 
     def __repr__(self):
         return ("<BasicConstraints(ca={ca}, "
-                "path_length={path_length}, "
-                "critical={critical})>").format(
-            ca=self.ca, path_length=self.path_length, critical=self.critical
+                "path_length={path_length})>").format(
+            ca=self.ca, path_length=self.path_length
         )
 
 
diff --git a/tests/test_x509_ext.py b/tests/test_x509_ext.py
index 9fde1be..de3ca31 100644
--- a/tests/test_x509_ext.py
+++ b/tests/test_x509_ext.py
@@ -9,32 +9,49 @@
 from cryptography import x509
 
 
+class TestExtension(object):
+    def test_not_an_oid(self):
+        bc = x509.BasicConstraints(False, None)
+        with pytest.raises(TypeError):
+            x509.Extension("notanoid", True, bc)
+
+    def test_critical_not_a_bool(self):
+        bc = x509.BasicConstraints(False, None)
+        with pytest.raises(TypeError):
+            x509.Extension(x509.OID_BASIC_CONSTRAINTS, "notabool", bc)
+
+    def test_repr(self):
+        bc = x509.BasicConstraints(False, None)
+        ext = x509.Extension(x509.OID_BASIC_CONSTRAINTS, True, bc)
+        assert repr(ext) == (
+            "<Extension(oid=<ObjectIdentifier(oid=2.5.29.19, name=basicConst"
+            "raints)>, critical=True, value=<BasicConstraints(ca=False, path"
+            "_length=None)>)>"
+        )
+
+
 class TestBasicConstraints(object):
     def test_ca_not_boolean(self):
         with pytest.raises(TypeError):
-            x509.BasicConstraints("notbool", None, False)
-
-    def test_critical_not_boolean(self):
-        with pytest.raises(TypeError):
-            x509.BasicConstraints(False, None, "notbool")
+            x509.BasicConstraints("notbool", None)
 
     def test_path_length_not_ca(self):
         with pytest.raises(ValueError):
-            x509.BasicConstraints(False, 0, True)
+            x509.BasicConstraints(False, 0)
 
     def test_path_length_not_int(self):
         with pytest.raises(TypeError):
-            x509.BasicConstraints(True, 1.1, True)
+            x509.BasicConstraints(True, 1.1)
 
         with pytest.raises(TypeError):
-            x509.BasicConstraints(True, "notint", True)
+            x509.BasicConstraints(True, "notint")
 
     def test_path_length_negative(self):
         with pytest.raises(TypeError):
-            x509.BasicConstraints(True, -1, True)
+            x509.BasicConstraints(True, -1)
 
     def test_repr(self):
-        na = x509.BasicConstraints(True, None, True)
+        na = x509.BasicConstraints(True, None)
         assert repr(na) == (
-            "<BasicConstraints(ca=True, path_length=None, critical=True)>"
+            "<BasicConstraints(ca=True, path_length=None)>"
         )