add UnrecognizedExtension class
diff --git a/docs/x509/reference.rst b/docs/x509/reference.rst
index bbea490..14727e7 100644
--- a/docs/x509/reference.rst
+++ b/docs/x509/reference.rst
@@ -1880,6 +1880,27 @@
 
         :type: int
 
+.. class:: UnrecognizedExtension
+
+    .. versionadded:: 1.2
+
+    A generic extension class used to hold the raw value of **non-critical**
+    extensions that ``cryptography`` does not know how to parse. Extensions
+    marked critical will still raise
+    :class:`~cryptography.x509.UnsupportedExtension`.
+
+    .. attribute:: oid
+
+        :type: :class:`ObjectIdentifier`
+
+        Returns the OID associated with this extension.
+
+    .. attribute:: value
+
+        :type: byte
+
+        Returns the DER encoded bytes payload of the extension.
+
 .. class:: CertificatePolicies(policies)
 
     .. versionadded:: 0.9
diff --git a/src/cryptography/x509/__init__.py b/src/cryptography/x509/__init__.py
index dc19161..a1deb7f 100644
--- a/src/cryptography/x509/__init__.py
+++ b/src/cryptography/x509/__init__.py
@@ -21,7 +21,7 @@
     InhibitAnyPolicy, InvalidityDate, IssuerAlternativeName, KeyUsage,
     NameConstraints, NoticeReference, OCSPNoCheck, PolicyInformation,
     ReasonFlags, SubjectAlternativeName, SubjectKeyIdentifier,
-    UnsupportedExtension, UserNotice
+    UnrecognizedExtension, UnsupportedExtension, UserNotice
 )
 from cryptography.x509.general_name import (
     DNSName, DirectoryName, GeneralName, IPAddress, OtherName, RFC822Name,
@@ -169,4 +169,5 @@
     "CertificateIssuer",
     "CRLReason",
     "InvalidityDate",
+    "UnrecognizedExtension",
 ]
diff --git a/src/cryptography/x509/extensions.py b/src/cryptography/x509/extensions.py
index 4e7a53b..0c5b552 100644
--- a/src/cryptography/x509/extensions.py
+++ b/src/cryptography/x509/extensions.py
@@ -1065,3 +1065,34 @@
         return hash(self.invalidity_date)
 
     invalidity_date = utils.read_only_property("_invalidity_date")
+
+
+@utils.register_interface(ExtensionType)
+class UnrecognizedExtension(object):
+    def __init__(self, oid, value):
+        if not isinstance(oid, ObjectIdentifier):
+            raise TypeError("oid must be an ObjectIdentifier")
+        self._oid = oid
+        self._value = value
+
+    oid = utils.read_only_property("_oid")
+    value = utils.read_only_property("_value")
+
+    def __repr__(self):
+        return (
+            "<UnrecognizedExtension(oid={0.oid}, value={0.value!r})>".format(
+                self
+            )
+        )
+
+    def __eq__(self, other):
+        if not isinstance(other, UnrecognizedExtension):
+            return NotImplemented
+
+        return self.oid == other.oid and self.value == other.value
+
+    def __ne__(self, other):
+        return not self == other
+
+    def __hash__(self):
+        return hash((self.oid, self.value))
diff --git a/tests/test_x509_ext.py b/tests/test_x509_ext.py
index 7cd24a6..258be12 100644
--- a/tests/test_x509_ext.py
+++ b/tests/test_x509_ext.py
@@ -75,6 +75,57 @@
         assert ext1 != object()
 
 
+class TestUnrecognizedExtension(object):
+    def test_invalid_oid(self):
+        with pytest.raises(TypeError):
+            x509.UnrecognizedExtension("notanoid", b"somedata")
+
+    def test_eq(self):
+        ext1 = x509.UnrecognizedExtension(
+            x509.ObjectIdentifier("1.2.3.4"), b"\x03\x02\x01"
+        )
+        ext2 = x509.UnrecognizedExtension(
+            x509.ObjectIdentifier("1.2.3.4"), b"\x03\x02\x01"
+        )
+        assert ext1 == ext2
+
+    def test_ne(self):
+        ext1 = x509.UnrecognizedExtension(
+            x509.ObjectIdentifier("1.2.3.4"), b"\x03\x02\x01"
+        )
+        ext2 = x509.UnrecognizedExtension(
+            x509.ObjectIdentifier("1.2.3.4"), b"\x03\x02\x02"
+        )
+        ext3 = x509.UnrecognizedExtension(
+            x509.ObjectIdentifier("1.2.3.5"), b"\x03\x02\x01"
+        )
+        assert ext1 != ext2
+        assert ext1 != ext3
+        assert ext1 != object()
+
+    def test_repr(self):
+        ext1 = x509.UnrecognizedExtension(
+            x509.ObjectIdentifier("1.2.3.4"), b"\x03\x02\x01"
+        )
+        assert repr(ext1) == (
+            "<UnrecognizedExtension(oid=<ObjectIdentifier(oid=1.2.3.4, name="
+            "Unknown OID)>, value='\\x03\\x02\\x01')>"
+        )
+
+    def test_hash(self):
+        ext1 = x509.UnrecognizedExtension(
+            x509.ObjectIdentifier("1.2.3.4"), b"\x03\x02\x01"
+        )
+        ext2 = x509.UnrecognizedExtension(
+            x509.ObjectIdentifier("1.2.3.4"), b"\x03\x02\x01"
+        )
+        ext3 = x509.UnrecognizedExtension(
+            x509.ObjectIdentifier("1.2.3.5"), b"\x03\x02\x01"
+        )
+        assert hash(ext1) == hash(ext2)
+        assert hash(ext1) != hash(ext3)
+
+
 class TestCertificateIssuer(object):
     def test_iter_names(self):
         ci = x509.CertificateIssuer([