basic constraints class & extensions interface
diff --git a/docs/x509.rst b/docs/x509.rst
index 27f1d54..89265df 100644
--- a/docs/x509.rst
+++ b/docs/x509.rst
@@ -273,6 +273,49 @@
 
         The dotted string value of the OID (e.g. ``"2.5.4.3"``)
 
+X.509 Extensions
+~~~~~~~~~~~~~~~~
+
+.. class:: Extension
+
+    .. versionadded:: 0.9
+
+    All X.509 extensions are registered against this interface.
+
+    .. attribute:: critical
+
+        :type: bool
+
+        Determines whether a given extension is critical or not.
+
+.. class:: BasicConstraints
+
+    .. versionadded:: 0.9
+
+    Basic constraints is an X.509 extension that defines whether a given
+    certificate is allowed to sign additional certificates and what path
+    length restrictions may exist.
+
+    .. attribute:: ca
+
+        :type: bool
+
+        Whether the certificate can sign certificates.
+
+    .. attribute:: path_length
+
+        :type: int, None
+
+        The maximum path length for certificates subordinate to this
+        certificate. This attribute only has meaning if ``ca`` is true.
+        If ``ca`` is true then a path length of None means there's no
+        restriction on the number of subordinate CAs in the certificate chain.
+        If it is zero or greater then that number defines the maximum length.
+        For example, a ``path_length`` of 1 means the certificate can sign a
+        subordinate CA, but the subordinate CA is not allowed to create
+        ``ca`` true certificates.
+
+
 Object Identifiers
 ~~~~~~~~~~~~~~~~~~
 
diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py
index ad7ebbe..c053dd6 100644
--- a/src/cryptography/x509.py
+++ b/src/cryptography/x509.py
@@ -141,6 +141,52 @@
         return len(self._attributes)
 
 
+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")
+
+        if not isinstance(critical, bool):
+            raise TypeError("critical 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")
+
+        if path_length is not None and (not isinstance(path_length, int)
+                                        or path_length < 0):
+            raise TypeError(
+                "path_length must be a non-negative integer or None"
+            )
+
+        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={}, path_length={}, critical={})>".format(
+            self.ca, self.path_length, self.critical
+        )
+
+
 OID_COMMON_NAME = ObjectIdentifier("2.5.4.3")
 OID_COUNTRY_NAME = ObjectIdentifier("2.5.4.6")
 OID_LOCALITY_NAME = ObjectIdentifier("2.5.4.7")
diff --git a/tests/test_x509_ext.py b/tests/test_x509_ext.py
new file mode 100644
index 0000000..9fde1be
--- /dev/null
+++ b/tests/test_x509_ext.py
@@ -0,0 +1,40 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+
+from __future__ import absolute_import, division, print_function
+
+import pytest
+
+from cryptography import x509
+
+
+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")
+
+    def test_path_length_not_ca(self):
+        with pytest.raises(ValueError):
+            x509.BasicConstraints(False, 0, True)
+
+    def test_path_length_not_int(self):
+        with pytest.raises(TypeError):
+            x509.BasicConstraints(True, 1.1, True)
+
+        with pytest.raises(TypeError):
+            x509.BasicConstraints(True, "notint", True)
+
+    def test_path_length_negative(self):
+        with pytest.raises(TypeError):
+            x509.BasicConstraints(True, -1, True)
+
+    def test_repr(self):
+        na = x509.BasicConstraints(True, None, True)
+        assert repr(na) == (
+            "<BasicConstraints(ca=True, path_length=None, critical=True)>"
+        )