add URI general name support
diff --git a/docs/x509.rst b/docs/x509.rst
index 035fa87..5f36a92 100644
--- a/docs/x509.rst
+++ b/docs/x509.rst
@@ -452,7 +452,12 @@
     .. versionadded:: 0.9
 
     This corresponds to a uniform resource identifier.  For example,
-    ``https://cryptography.io``.
+    ``https://cryptography.io``. The URI is parsed and IDNA decoded (see
+    :rfc:`5895`).
+
+    .. note::
+
+        URIs that do not contain ``://`` in them will not be decoded.
 
     .. attribute:: value
 
diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py
index c21aeeb..3a660d8 100644
--- a/src/cryptography/hazmat/backends/openssl/x509.py
+++ b/src/cryptography/hazmat/backends/openssl/x509.py
@@ -17,6 +17,10 @@
 
 import idna
 
+import six
+
+from six.moves import urllib_parse
+
 from cryptography import utils, x509
 from cryptography.exceptions import UnsupportedAlgorithm
 from cryptography.hazmat.primitives import hashes
@@ -63,6 +67,30 @@
     if gn.type == backend._lib.GEN_DNS:
         data = backend._ffi.buffer(gn.d.dNSName.data, gn.d.dNSName.length)[:]
         return x509.DNSName(idna.decode(data))
+    elif gn.type == backend._lib.GEN_URI:
+        data = backend._ffi.buffer(
+            gn.d.uniformResourceIdentifier.data,
+            gn.d.uniformResourceIdentifier.length
+        )[:].decode("ascii")
+        parsed = urllib_parse.urlparse(data)
+        hostname = idna.decode(parsed.hostname)
+        if parsed.port:
+            netloc = hostname + u":" + six.text_type(parsed.port)
+        else:
+            netloc = hostname
+
+        # Note that building a URL in this fashion means it should be
+        # semantically indistinguishable from the original but is not
+        # guaranteed to be exactly the same.
+        uri = urllib_parse.urlunparse((
+            parsed.scheme,
+            netloc,
+            parsed.path,
+            parsed.params,
+            parsed.query,
+            parsed.fragment
+        ))
+        return x509.UniformResourceIdentifier(uri)
     elif gn.type == backend._lib.GEN_RID:
         oid = _obj2txt(backend, gn.d.registeredID)
         return x509.RegisteredID(x509.ObjectIdentifier(oid))
diff --git a/tests/test_x509_ext.py b/tests/test_x509_ext.py
index bce6781..820e96b 100644
--- a/tests/test_x509_ext.py
+++ b/tests/test_x509_ext.py
@@ -788,3 +788,24 @@
         san = ext.value
         rid = san.get_values_for_type(x509.RegisteredID)
         assert rid == [x509.ObjectIdentifier("1.2.3.4")]
+
+    def test_uri(self, backend):
+        cert = _load_cert(
+            os.path.join(
+                "x509", "custom", "san_uri_with_port.pem"
+            ),
+            x509.load_pem_x509_certificate,
+            backend
+        )
+        ext = cert.extensions.get_extension_for_oid(
+            x509.OID_SUBJECT_ALTERNATIVE_NAME
+        )
+        assert ext is not None
+        uri = ext.value.get_values_for_type(
+            x509.UniformResourceIdentifier
+        )
+        assert uri == [
+            u"gopher://\u043f\u044b\u043a\u0430.cryptography:70/path?q=s#hel"
+            u"lo",
+            u"http://someregulardomain.com",
+        ]