Support Subject Alternative Name in the OpenSSL backend

Adds only DNS support first
diff --git a/setup.py b/setup.py
index 6376a1f..e0b5738 100644
--- a/setup.py
+++ b/setup.py
@@ -32,6 +32,7 @@
 VECTORS_DEPENDENCY = "cryptography_vectors=={0}".format(about['__version__'])
 
 requirements = [
+    "idna",
     "pyasn1",
     "six>=1.4.1",
     "setuptools"
diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py
index 57e6146..363d3df 100644
--- a/src/cryptography/hazmat/backends/openssl/x509.py
+++ b/src/cryptography/hazmat/backends/openssl/x509.py
@@ -15,6 +15,8 @@
 
 import datetime
 
+import idna
+
 from cryptography import utils, x509
 from cryptography.exceptions import UnsupportedAlgorithm
 from cryptography.hazmat.primitives import hashes
@@ -57,6 +59,14 @@
     return x509.Name(attributes)
 
 
+def _build_general_name(backend, gn):
+    if gn.type == backend._lib.GEN_DNS:
+        data = backend._ffi.buffer(
+            gn.d.dNSName.data, gn.d.dNSName.length
+        )[:].decode("ascii")
+        return x509.DNSName(idna.decode(data))
+
+
 @utils.register_interface(x509.Certificate)
 class _Certificate(object):
     def __init__(self, backend, x509):
@@ -173,6 +183,8 @@
                 value = self._build_subject_key_identifier(ext)
             elif oid == x509.OID_KEY_USAGE:
                 value = self._build_key_usage(ext)
+            elif oid == x509.OID_SUBJECT_ALTERNATIVE_NAME:
+                value = self._build_subject_alt_name(ext)
             elif critical:
                 raise x509.UnsupportedExtension(
                     "{0} is not currently supported".format(oid), oid
@@ -254,6 +266,24 @@
             decipher_only
         )
 
+    def _build_subject_alt_name(self, ext):
+        gns = self._backend._ffi.cast(
+            "GENERAL_NAMES *", self._backend._lib.X509V3_EXT_d2i(ext)
+        )
+        assert gns != self._backend._ffi.NULL
+        gns = self._backend._ffi.gc(gns, self._backend._lib.GENERAL_NAMES_free)
+        num = self._backend._lib.sk_GENERAL_NAME_num(gns)
+        general_names = []
+
+        for i in range(0, num):
+            gn = self._backend._lib.sk_GENERAL_NAME_value(gns, i)
+            assert gn != self._backend._ffi.NULL
+            value = _build_general_name(self._backend, gn)
+
+            general_names.append(value)
+
+        return x509.SubjectAlternativeName(general_names)
+
 
 @utils.register_interface(x509.CertificateSigningRequest)
 class _CertificateSigningRequest(object):
diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py
index cdc0e43..9e4b5ee 100644
--- a/src/cryptography/x509.py
+++ b/src/cryptography/x509.py
@@ -70,6 +70,19 @@
 }
 
 
+_GENERAL_NAMES = {
+    0: "otherName",
+    1: "rfc822Name",
+    2: "dNSName",
+    3: "x400Address",
+    4: "directoryName",
+    5: "ediPartyName",
+    6: "uniformResourceIdentifier",
+    7: "iPAddress",
+    8: "registeredID",
+}
+
+
 class Version(Enum):
     v1 = 0
     v3 = 2
@@ -115,6 +128,10 @@
         self.oid = oid
 
 
+class UnsupportedGeneralNameType(Exception):
+    pass
+
+
 class NameAttribute(object):
     def __init__(self, oid, value):
         if not isinstance(oid, ObjectIdentifier):
diff --git a/tests/test_x509_ext.py b/tests/test_x509_ext.py
index 8516a33..2fa659e 100644
--- a/tests/test_x509_ext.py
+++ b/tests/test_x509_ext.py
@@ -730,3 +730,24 @@
         assert repr(san) == (
             "<SubjectAlternativeName([<DNSName(value=cryptography.io)>])>"
         )
+
+
+@pytest.mark.requires_backend_interface(interface=RSABackend)
+@pytest.mark.requires_backend_interface(interface=X509Backend)
+class TestRSASubjectAlternativeNameExtension(object):
+    def test_dns_name(self, backend):
+        cert = _load_cert(
+            os.path.join("x509", "cryptography.io.pem"),
+            x509.load_pem_x509_certificate,
+            backend
+        )
+        ext = cert.extensions.get_extension_for_oid(
+            x509.OID_SUBJECT_ALTERNATIVE_NAME
+        )
+        assert ext is not None
+        assert ext.critical is False
+
+        san = ext.value
+
+        dns = san.get_values_for_type(x509.DNSName)
+        assert dns == [u"www.cryptography.io", u"cryptography.io"]