add bindings and interfaces for CRL objects
diff --git a/docs/x509.rst b/docs/x509.rst
index 5e4d9bf..fa01f04 100644
--- a/docs/x509.rst
+++ b/docs/x509.rst
@@ -208,7 +208,7 @@
             :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm`
             that will be used to generate the fingerprint.
 
-        :return bytes: The fingerprint using the supplied hash algorithm as
+        :return bytes: The fingerprint using the supplied hash algorithm, as
             bytes.
 
         .. doctest::
@@ -335,6 +335,71 @@
         :return bytes: The data that can be written to a file or sent
             over the network to be verified by clients.
 
+X.509 CRL (Certificate Revocation List) Object
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. class:: CertificateRevocationList
+
+    .. versionadded:: 1.0
+
+    .. method:: fingerprint(algorithm)
+
+        :param algorithm: The
+            :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm`
+            that will be used to generate the fingerprint.
+
+        :return bytes: The fingerprint using the supplied hash algorithm, as
+            bytes.
+
+    .. attribute:: signature_hash_algorithm
+
+        :type: :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm`
+
+        Returns the
+        :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm` which
+        was used in signing this CRL.
+
+    .. attribute:: issuer
+
+        :type: :class:`Name`
+
+        The :class:`Name` of the issuer.
+
+    .. attribute:: next_update
+
+        :type: :class:`datetime.datetime`
+
+        A naïve datetime representing when the next update to this CRL is
+        expected.
+
+    .. attribute:: last_update
+
+        :type: :class:`datetime.datetime`
+
+        A naïve datetime representing when the this CRL was last updated.
+
+    .. attribute:: revoked
+
+        :type: list of :class:`RevokedCertificate`
+
+        The revoked certificates listed in this CRL.
+
+    .. attribute:: extensions
+
+        :type: :class:`Extensions`
+
+        The extensions encoded in the CRL.
+
+    .. method:: verify(pubkey)
+
+        :param algorithm: The
+            :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey` or
+            :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey` or
+            :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey`
+            that will be used to verify the CRL.
+
+        :return boolean: The result of the verification as boolean value.
+
 X.509 CSR (Certificate Signing Request) Object
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -388,6 +453,30 @@
             over the network to be signed by the certificate
             authority.
 
+X.509 Revoked Certificate Object
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. class:: RevokedCertificate
+
+    .. versionadded:: 1.0
+
+    .. attribute:: serial_number
+
+        :type: :class:`int`
+
+        An integer representing the serial number of the revoked certificate.
+
+    .. attribute:: revocation_date
+
+        :type: :class:`datetime.datetime`
+
+        A naïve datetime representing the date this certificates was revoked.
+
+    .. attribute:: extensions
+
+        :type: :class:`Extensions`
+
+        The extensions encoded in the revoked certificate.
 
 .. class:: Name
 
diff --git a/src/cryptography/hazmat/bindings/openssl/asn1.py b/src/cryptography/hazmat/bindings/openssl/asn1.py
index 711c30b..c18708c 100644
--- a/src/cryptography/hazmat/bindings/openssl/asn1.py
+++ b/src/cryptography/hazmat/bindings/openssl/asn1.py
@@ -114,6 +114,7 @@
 ASN1_ENUMERATED *ASN1_ENUMERATED_new(void);
 void ASN1_ENUMERATED_free(ASN1_ENUMERATED *);
 int ASN1_ENUMERATED_set(ASN1_ENUMERATED *, long);
+long ASN1_ENUMERATED_get(ASN1_ENUMERATED *);
 
 ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **, const unsigned char **, long,
                           const ASN1_ITEM *);
diff --git a/src/cryptography/hazmat/bindings/openssl/x509.py b/src/cryptography/hazmat/bindings/openssl/x509.py
index caa3396..3eb7017 100644
--- a/src/cryptography/hazmat/bindings/openssl/x509.py
+++ b/src/cryptography/hazmat/bindings/openssl/x509.py
@@ -194,6 +194,7 @@
 int X509_CRL_get_ext_count(X509_CRL *);
 X509_EXTENSION *X509_CRL_get_ext(X509_CRL *, int);
 int X509_CRL_add_ext(X509_CRL *, X509_EXTENSION *, int);
+int X509_CRL_cmp(const X509_CRL *, const X509_CRL *);
 
 int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *, EVP_PKEY *);
 int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *, EVP_PKEY *, const EVP_MD *);
diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py
index e6d19ae..421ebfc 100644
--- a/src/cryptography/x509.py
+++ b/src/cryptography/x509.py
@@ -55,6 +55,9 @@
     "2.5.29.17": "subjectAltName",
     "2.5.29.18": "issuerAltName",
     "2.5.29.19": "basicConstraints",
+    "2.5.29.21": "CRLReason",
+    "2.5.29.24": "InvalidityDate",
+    "2.5.29.29": "CertificateIssuer",
     "2.5.29.30": "nameConstraints",
     "2.5.29.31": "cRLDistributionPoints",
     "2.5.29.32": "certificatePolicies",
@@ -224,6 +227,9 @@
 OID_SUBJECT_ALTERNATIVE_NAME = ObjectIdentifier("2.5.29.17")
 OID_ISSUER_ALTERNATIVE_NAME = ObjectIdentifier("2.5.29.18")
 OID_BASIC_CONSTRAINTS = ObjectIdentifier("2.5.29.19")
+OID_CRL_REASON = ObjectIdentifier("2.5.29.21")
+OID_INVALIDITY_DATE = ObjectIdentifier("2.5.29.24")
+OID_CERTIFICATE_ISSUER = ObjectIdentifier("2.5.29.29")
 OID_NAME_CONSTRAINTS = ObjectIdentifier("2.5.29.30")
 OID_CRL_DISTRIBUTION_POINTS = ObjectIdentifier("2.5.29.31")
 OID_CERTIFICATE_POLICIES = ObjectIdentifier("2.5.29.32")
@@ -944,7 +950,7 @@
         return not self == other
 
 
-class SubjectAlternativeName(object):
+class GeneralNames(object):
     def __init__(self, general_names):
         if not all(isinstance(x, GeneralName) for x in general_names):
             raise TypeError(
@@ -964,6 +970,32 @@
         return [i.value for i in self if isinstance(i, type)]
 
     def __repr__(self):
+        return "<GeneralNames({0})>".format(self._general_names)
+
+    def __eq__(self, other):
+        if not isinstance(other, GeneralNames):
+            return NotImplemented
+
+        return self._general_names == other._general_names
+
+    def __ne__(self, other):
+        return not self == other
+
+
+class SubjectAlternativeName(object):
+    def __init__(self, general_names):
+        self._general_names = GeneralNames(general_names)
+
+    def __iter__(self):
+        return iter(self._general_names)
+
+    def __len__(self):
+        return len(self._general_names)
+
+    def get_values_for_type(self, type):
+        return self._general_names.get_values_for_type(type)
+
+    def __repr__(self):
         return "<SubjectAlternativeName({0})>".format(self._general_names)
 
     def __eq__(self, other):
@@ -1175,6 +1207,71 @@
 
 
 @six.add_metaclass(abc.ABCMeta)
+class CertificateRevocationList(object):
+
+    @abc.abstractmethod
+    def fingerprint(self, algorithm):
+        """
+        Returns bytes using digest passed.
+        """
+
+    @abc.abstractproperty
+    def signature_hash_algorithm(self):
+        """
+        Returns a HashAlgorithm corresponding to the type of the digest signed
+        in the certificate.
+        """
+
+    @abc.abstractproperty
+    def issuer(self):
+        """
+        Returns the X509Name with the issuer of this CRL.
+        """
+
+    @abc.abstractproperty
+    def next_update(self):
+        """
+        Returns the date of next update for this CRL.
+        """
+
+    @abc.abstractproperty
+    def last_update(self):
+        """
+        Returns the date of last update for this CRL.
+        """
+
+    @abc.abstractproperty
+    def revoked(self):
+        """
+        Returns a list of RevokedCertificate objects for this CRL.
+        """
+
+    @abc.abstractproperty
+    def extensions(self):
+        """
+        Returns an Extensions object containing a list of CRL extensions.
+        """
+
+    @abc.abstractmethod
+    def verify(self, pubkey):
+        """
+        Verify this CRL against a given 'pubkey'.
+        """
+
+    @abc.abstractmethod
+    def __eq__(self, other):
+        """
+        Checks equality.
+        """
+
+    @abc.abstractmethod
+    def __ne__(self, other):
+        """
+        Checks not equal.
+        """
+
+
+@six.add_metaclass(abc.ABCMeta)
 class CertificateSigningRequest(object):
     @abc.abstractmethod
     def public_key(self):
@@ -1206,3 +1303,24 @@
         """
         Encodes the request to PEM or DER format.
         """
+
+
+@six.add_metaclass(abc.ABCMeta)
+class RevokedCertificate(object):
+    @abc.abstractproperty
+    def serial_number(self):
+        """
+        Returns the serial number of the revoked certificate.
+        """
+
+    @abc.abstractproperty
+    def revocation_date(self):
+        """
+        Returns the date of when this certificate was revoked.
+        """
+
+    @abc.abstractproperty
+    def extensions(self):
+        """
+        Returns an Extensions object containing a list of Revoked extensions.
+        """
diff --git a/tests/test_x509_ext.py b/tests/test_x509_ext.py
index 20a016b..ace3811 100644
--- a/tests/test_x509_ext.py
+++ b/tests/test_x509_ext.py
@@ -1139,6 +1139,61 @@
         assert gn != object()
 
 
+class TestGeneralNames(object):
+    def test_get_values_for_type(self):
+        gns = x509.GeneralNames(
+            [x509.DNSName(u"cryptography.io")]
+        )
+        names = gns.get_values_for_type(x509.DNSName)
+        assert names == [u"cryptography.io"]
+
+    def test_iter_names(self):
+        gns = x509.GeneralNames([
+            x509.DNSName(u"cryptography.io"),
+            x509.DNSName(u"crypto.local"),
+        ])
+        assert len(gns) == 2
+        assert list(gns) == [
+            x509.DNSName(u"cryptography.io"),
+            x509.DNSName(u"crypto.local"),
+        ]
+
+    def test_invalid_general_names(self):
+        with pytest.raises(TypeError):
+            x509.GeneralNames(
+                [x509.DNSName(u"cryptography.io"), "invalid"]
+            )
+
+    def test_repr(self):
+        gns = x509.GeneralNames(
+            [
+                x509.DNSName(u"cryptography.io")
+            ]
+        )
+        assert repr(gns) == (
+            "<GeneralNames([<DNSName(value=cryptography.io)>])>"
+        )
+
+    def test_eq(self):
+        gns = x509.GeneralNames(
+            [x509.DNSName(u"cryptography.io")]
+        )
+        gns2 = x509.GeneralNames(
+            [x509.DNSName(u"cryptography.io")]
+        )
+        assert gns == gns2
+
+    def test_ne(self):
+        gns = x509.GeneralNames(
+            [x509.DNSName(u"cryptography.io")]
+        )
+        gns2 = x509.GeneralNames(
+            [x509.RFC822Name(u"admin@cryptography.io")]
+        )
+        assert gns != gns2
+        assert gns != object()
+
+
 class TestSubjectAlternativeName(object):
     def test_get_values_for_type(self):
         san = x509.SubjectAlternativeName(
@@ -1171,7 +1226,8 @@
             ]
         )
         assert repr(san) == (
-            "<SubjectAlternativeName([<DNSName(value=cryptography.io)>])>"
+            "<SubjectAlternativeName("
+            "<GeneralNames([<DNSName(value=cryptography.io)>])>)>"
         )
 
     def test_eq(self):