add invaliditydate class for crl entry extensions
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 4052ff5..39c6f61 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -16,7 +16,7 @@
 
   * :class:`~cryptography.x509.CertificateIssuer`
   * :class:`~cryptography.x509.CRLReason`
-  * ``InvalidityDate``
+  * :class:`~cryptography.x509.InvalidityDate`
 * The :class:`~cryptography.x509.Certificate` class now has
   :attr:`~cryptography.x509.Certificate.signature` and
   :attr:`~cryptography.x509.Certificate.tbs_certificate_bytes` attributes.
diff --git a/docs/x509/reference.rst b/docs/x509/reference.rst
index 51de074..72fd44b 100644
--- a/docs/x509/reference.rst
+++ b/docs/x509/reference.rst
@@ -907,7 +907,7 @@
 
             >>> for ext in revoked_certificate.extensions:
             ...     print(ext)
-            <Extension(oid=<ObjectIdentifier(oid=2.5.29.24, name=invalidityDate)>, critical=False, value=2015-01-01 00:00:00)>
+            <Extension(oid=<ObjectIdentifier(oid=2.5.29.24, name=invalidityDate)>, critical=False, value=<InvalidityDate(invalidity_date=2015-01-01 00:00:00)>)>
             <Extension(oid=<ObjectIdentifier(oid=2.5.29.21, name=cRLReason)>, critical=False, value=<CRLReason(reason=ReasonFlags.key_compromise)>)>
 
 X.509 Revoked Certificate Builder
@@ -2011,6 +2011,31 @@
 
         :type: An element from :class:`~cryptography.x509.ReasonFlags`
 
+.. class:: InvalidityDate(invalidity_date)
+
+    .. versionadded:: 1.2
+
+    Invalidity date is an extension that is only valid inside
+    :class:`~cryptography.x509.RevokedCertificate` objects. It provides
+    the date on which it is known or suspected that the private key was
+    compromised or that the certificate otherwise became invalid.
+    This date may be earlier than the revocation date in the CRL entry,
+    which is the date at which the CA processed the revocation.
+
+    :param invalidity_date: The :class:`datetime.datetime` when it is known
+        or suspected that the private key was compromised.
+
+    .. attribute:: oid
+
+        :type: :class:`ObjectIdentifier`
+
+        Returns
+        :attr:`~cryptography.x509.oid.CRLEntryExtensionOID.INVALIDITY_DATE`.
+
+    .. attribute:: invalidity_date
+
+        :type: :class:`datetime.datetime`
+
 
 Object Identifiers
 ~~~~~~~~~~~~~~~~~~
diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py
index 2650b5d..1376ab7 100644
--- a/src/cryptography/hazmat/backends/openssl/x509.py
+++ b/src/cryptography/hazmat/backends/openssl/x509.py
@@ -717,7 +717,9 @@
             backend._ffi.cast("ASN1_STRING *", generalized_time)
         )
     ).decode("ascii")
-    return datetime.datetime.strptime(time, "%Y%m%d%H%M%SZ")
+    return x509.InvalidityDate(
+        datetime.datetime.strptime(time, "%Y%m%d%H%M%SZ")
+    )
 
 
 def _decode_cert_issuer(backend, ext):
diff --git a/src/cryptography/x509/__init__.py b/src/cryptography/x509/__init__.py
index 89e7f06..dc19161 100644
--- a/src/cryptography/x509/__init__.py
+++ b/src/cryptography/x509/__init__.py
@@ -18,7 +18,7 @@
     CRLNumber, CRLReason, CertificateIssuer, CertificatePolicies,
     DistributionPoint, DuplicateExtension, ExtendedKeyUsage, Extension,
     ExtensionNotFound, ExtensionType, Extensions, GeneralNames,
-    InhibitAnyPolicy, IssuerAlternativeName, KeyUsage,
+    InhibitAnyPolicy, InvalidityDate, IssuerAlternativeName, KeyUsage,
     NameConstraints, NoticeReference, OCSPNoCheck, PolicyInformation,
     ReasonFlags, SubjectAlternativeName, SubjectKeyIdentifier,
     UnsupportedExtension, UserNotice
@@ -168,4 +168,5 @@
     "CRLExtensionOID",
     "CertificateIssuer",
     "CRLReason",
+    "InvalidityDate",
 ]
diff --git a/src/cryptography/x509/extensions.py b/src/cryptography/x509/extensions.py
index 6ae0092..22cba68 100644
--- a/src/cryptography/x509/extensions.py
+++ b/src/cryptography/x509/extensions.py
@@ -5,6 +5,7 @@
 from __future__ import absolute_import, division, print_function
 
 import abc
+import datetime
 import hashlib
 import ipaddress
 from enum import Enum
@@ -1001,3 +1002,30 @@
         return not self == other
 
     reason = utils.read_only_property("_reason")
+
+
+@utils.register_interface(ExtensionType)
+class InvalidityDate(object):
+    oid = CRLEntryExtensionOID.INVALIDITY_DATE
+
+    def __init__(self, invalidity_date):
+        if not isinstance(invalidity_date, datetime.datetime):
+            raise TypeError("invalidity_date must be a datetime.datetime")
+
+        self._invalidity_date = invalidity_date
+
+    def __repr__(self):
+        return "<InvalidityDate(invalidity_date={0})>".format(
+            self._invalidity_date
+        )
+
+    def __eq__(self, other):
+        if not isinstance(other, InvalidityDate):
+            return NotImplemented
+
+        return self.invalidity_date == other.invalidity_date
+
+    def __ne__(self, other):
+        return not self == other
+
+    invalidity_date = utils.read_only_property("_invalidity_date")
diff --git a/tests/test_x509.py b/tests/test_x509.py
index 757df44..560324b 100644
--- a/tests/test_x509.py
+++ b/tests/test_x509.py
@@ -387,9 +387,9 @@
             x509.CertificateIssuer).value
         assert issuer == x509.CertificateIssuer(exp_issuer)
 
-        date = rev1.extensions.get_extension_for_oid(
-            x509.OID_INVALIDITY_DATE).value
-        assert date == datetime.datetime(2015, 1, 1, 0, 0)
+        date = rev1.extensions.get_extension_for_class(
+            x509.InvalidityDate).value
+        assert date == x509.InvalidityDate(datetime.datetime(2015, 1, 1, 0, 0))
 
         # Check if all reason flags can be found in the CRL.
         flags = set(x509.ReasonFlags)
diff --git a/tests/test_x509_ext.py b/tests/test_x509_ext.py
index b8105a4..91a0765 100644
--- a/tests/test_x509_ext.py
+++ b/tests/test_x509_ext.py
@@ -5,6 +5,7 @@
 from __future__ import absolute_import, division, print_function
 
 import binascii
+import datetime
 import ipaddress
 import os
 
@@ -135,6 +136,29 @@
         )
 
 
+class TestInvalidityDate(object):
+    def test_invalid_invalidity_date(self):
+        with pytest.raises(TypeError):
+            x509.InvalidityDate("notadate")
+
+    def test_eq(self):
+        invalid1 = x509.InvalidityDate(datetime.datetime(2015, 1, 1, 1, 1))
+        invalid2 = x509.InvalidityDate(datetime.datetime(2015, 1, 1, 1, 1))
+        assert invalid1 == invalid2
+
+    def test_ne(self):
+        invalid1 = x509.InvalidityDate(datetime.datetime(2015, 1, 1, 1, 1))
+        invalid2 = x509.InvalidityDate(datetime.datetime(2015, 1, 1, 1, 2))
+        assert invalid1 != invalid2
+        assert invalid1 != object()
+
+    def test_repr(self):
+        invalid1 = x509.InvalidityDate(datetime.datetime(2015, 1, 1, 1, 1))
+        assert repr(invalid1) == (
+            "<InvalidityDate(invalidity_date=2015-01-01 01:01:00)>"
+        )
+
+
 class TestNoticeReference(object):
     def test_notice_numbers_not_all_int(self):
         with pytest.raises(TypeError):