add keyusage extension
diff --git a/docs/x509.rst b/docs/x509.rst
index af24944..39df4a0 100644
--- a/docs/x509.rst
+++ b/docs/x509.rst
@@ -447,6 +447,99 @@
 
         Returns an instance of the extension type corresponding to the OID.
 
+.. class:: KeyUsage
+
+    .. versionadded:: 0.9
+
+    The key usage extension defines the purpose of the key contained in the
+    certificate.  The usage restriction might be employed when a key that could
+    be used for more than one operation is to be restricted. It corresponds to
+    :data:`OID_KEY_USAGE`.
+
+    .. attribute:: digital_signature
+
+        :type: bool
+
+        This is asserted when the subject public key is used for verifying
+        digital signatures, other than signatures on certificates
+        (``key_cert_sign``) and CRLs (``crl_sign``).
+
+    .. attribute:: content_commitment
+
+        :type: bool
+
+        This is asserted when the subject public key is used for verifying
+        digital signatures, other than signatures on certificates
+        (``key_cert_sign``) and CRLs (``crl_sign``). It is used to provide a
+        non-repudiation service that protects against the signing entity
+        falsely denying some action. In the case of later conflict, a
+        reliable third party may determine the authenticity of the signed
+        data. This was called ``non_repudiation`` in older revisions of the
+        X.509 specification.
+
+    .. attribute:: key_encipherment
+
+        :type: bool
+
+        This is asserted when the subject public key is used for enciphering
+        private or secret keys.
+
+    .. attribute:: data_encipherment
+
+        :type: bool
+
+        This is asserted when the subject public key is used for directly
+        enciphering raw user data without the use of an intermediate symmetric
+        cipher.
+
+    .. attribute:: key_agreement
+
+        :type: bool
+
+        This is asserted when the subject public key is used for key agreement.
+        For example, when a Diffie-Hellman key is to be used for key
+        management, then this bit is set.
+
+    .. attribute:: key_cert_sign
+
+        :type: bool
+
+        This is asserted when the subject public key is used for verifying
+        signatures on public key certificates. If this bit is asserted then
+        ``ca`` must be true in the :class:`BasicConstraints` extension.
+
+    .. attribute:: crl_sign
+
+        :type: bool
+
+        This is asserted when the subject public key is used for verifying
+        signatures on certificate revocation lists.
+
+    .. attribute:: encipher_only
+
+        :type: bool
+
+        The meaning of this bit is undefined in the absence of the
+        ``key_agreement`` bit.  When this bit is asserted and the
+        ``key_agreement`` bit is also set, the subject public key may be
+        used only for enciphering data while performing key agreement.
+
+        :raises ValueError: This is raised if accessed when ``key_agreement``
+            is false.
+
+    .. attribute:: decipher_only
+
+        :type: bool
+
+        The meaning of this bit is undefined in the absence of the
+        ``key_agreement`` bit.  When this bit is asserted and the
+        ``key_agreement`` bit is also set, the subject public key may be
+        used only for deciphering data while performing key agreement.
+
+        :raises ValueError: This is raised if accessed when ``key_agreement``
+            is false.
+
+
 .. class:: BasicConstraints
 
     .. versionadded:: 0.9
@@ -687,6 +780,11 @@
     Corresponds to the dotted string ``"2.5.29.19"``. The identifier for the
     :class:`BasicConstraints` extension type.
 
+.. data:: OID_KEY_USAGE
+
+    Corresponds to the dotted string ``"2.5.29.15"``. The identifier for the
+    :class:`KeyUsage` extension type.
+
 
 Exceptions
 ~~~~~~~~~~
diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py
index 791d1ef..b48a04d 100644
--- a/src/cryptography/x509.py
+++ b/src/cryptography/x509.py
@@ -266,6 +266,54 @@
                 "path_length={0.path_length})>").format(self)
 
 
+class KeyUsage(object):
+    def __init__(self, digital_signature, content_commitment, key_encipherment,
+                 data_encipherment, key_agreement, key_cert_sign, crl_sign,
+                 encipher_only, decipher_only):
+        if not key_agreement and (encipher_only or decipher_only):
+            raise ValueError(
+                "encipher_only and decipher_only can only be true when "
+                "key_agreement is true"
+            )
+
+        self._digital_signature = digital_signature
+        self._content_commitment = content_commitment
+        self._key_encipherment = key_encipherment
+        self._data_encipherment = data_encipherment
+        self._key_agreement = key_agreement
+        self._key_cert_sign = key_cert_sign
+        self._crl_sign = crl_sign
+        self._encipher_only = encipher_only
+        self._decipher_only = decipher_only
+
+    digital_signature = utils.read_only_property("_digital_signature")
+    content_commitment = utils.read_only_property("_content_commitment")
+    key_encipherment = utils.read_only_property("_key_encipherment")
+    data_encipherment = utils.read_only_property("_data_encipherment")
+    key_agreement = utils.read_only_property("_key_agreement")
+    key_cert_sign = utils.read_only_property("_key_cert_sign")
+    crl_sign = utils.read_only_property("_crl_sign")
+
+    @property
+    def encipher_only(self):
+        if not self.key_agreement:
+            raise ValueError(
+                "encipher_only is undefined unless key_agreement is true"
+            )
+        else:
+            return self._encipher_only
+
+    @property
+    def decipher_only(self):
+        if not self.key_agreement:
+            raise ValueError(
+                "decipher_only is undefined unless key_agreement is true"
+            )
+        else:
+            return self._decipher_only
+
+
+
 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
index 87580a0..7447ac4 100644
--- a/tests/test_x509_ext.py
+++ b/tests/test_x509_ext.py
@@ -35,6 +35,103 @@
         )
 
 
+class TestKeyUsage(object):
+    def test_key_agreement_false_encipher_decipher_true(self):
+        with pytest.raises(ValueError):
+            x509.KeyUsage(
+                digital_signature=False,
+                content_commitment=False,
+                key_encipherment=False,
+                data_encipherment=False,
+                key_agreement=False,
+                key_cert_sign=False,
+                crl_sign=False,
+                encipher_only=True,
+                decipher_only=False
+            )
+
+        with pytest.raises(ValueError):
+            x509.KeyUsage(
+                digital_signature=False,
+                content_commitment=False,
+                key_encipherment=False,
+                data_encipherment=False,
+                key_agreement=False,
+                key_cert_sign=False,
+                crl_sign=False,
+                encipher_only=True,
+                decipher_only=True
+            )
+
+        with pytest.raises(ValueError):
+            x509.KeyUsage(
+                digital_signature=False,
+                content_commitment=False,
+                key_encipherment=False,
+                data_encipherment=False,
+                key_agreement=False,
+                key_cert_sign=False,
+                crl_sign=False,
+                encipher_only=False,
+                decipher_only=True
+            )
+
+    def test_properties_key_agreement_true(self):
+        ku = x509.KeyUsage(
+            digital_signature=True,
+            content_commitment=True,
+            key_encipherment=False,
+            data_encipherment=False,
+            key_agreement=False,
+            key_cert_sign=True,
+            crl_sign=False,
+            encipher_only=False,
+            decipher_only=False
+        )
+        assert ku.digital_signature is True
+        assert ku.content_commitment is True
+        assert ku.key_encipherment is False
+        assert ku.data_encipherment is False
+        assert ku.key_agreement is False
+        assert ku.key_cert_sign is True
+        assert ku.crl_sign is False
+
+    def test_key_agreement_true_properties(self):
+        ku = x509.KeyUsage(
+            digital_signature=False,
+            content_commitment=False,
+            key_encipherment=False,
+            data_encipherment=False,
+            key_agreement=True,
+            key_cert_sign=False,
+            crl_sign=False,
+            encipher_only=False,
+            decipher_only=True
+        )
+        assert ku.key_agreement is True
+        assert ku.encipher_only is False
+        assert ku.decipher_only is True
+
+    def test_key_agreement_false_properties(self):
+        ku = x509.KeyUsage(
+            digital_signature=False,
+            content_commitment=False,
+            key_encipherment=False,
+            data_encipherment=False,
+            key_agreement=False,
+            key_cert_sign=False,
+            crl_sign=False,
+            encipher_only=False,
+            decipher_only=False
+        )
+        assert ku.key_agreement is False
+        with pytest.raises(ValueError):
+            ku.encipher_only
+
+        with pytest.raises(ValueError):
+            ku.decipher_only
+
+
 class TestBasicConstraints(object):
     def test_ca_not_boolean(self):
         with pytest.raises(TypeError):