Merge pull request #2406 from reaperhulk/update-docs-openssl-builder

update docs to point at newer, fancier openssl builder
diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst
index 15c3be9..bfe7633 100644
--- a/docs/development/test-vectors.rst
+++ b/docs/development/test-vectors.rst
@@ -148,6 +148,9 @@
   certificate containing a subject alternative name extension with the
   following general names: ``rfc822Name``, ``dNSName``, ``iPAddress``,
   ``directoryName``, and ``uniformResourceIdentifier``.
+* ``san_empty_hostname.pem`` - An RSA 2048 bit self-signed certificate
+  containing a subject alternative extension with an empty ``dNSName``
+  general name.
 * ``san_other_name.pem`` - An RSA 2048 bit self-signed certificate containing
   a subject alternative name extension with the ``otherName`` general name.
 * ``san_registered_id.pem`` - An RSA 1024 bit certificate containing a
@@ -193,6 +196,9 @@
   containing an authority information access extension with an OCSP entry.
 * ``aia_ca_issuers.pem`` - An RSA 2048 bit self-signed certificate
   containing an authority information access extension with a CA issuers entry.
+* ``cdp_empty_hostname.pem`` - An RSA 2048 bit self-signed certificate
+  containing a CRL distribution point extension with ``fullName`` URI without
+  a hostname.
 * ``cdp_fullname_reasons_crl_issuer.pem`` - An RSA 1024 bit certificate
   containing a CRL distribution points extension with ``fullName``,
   ``cRLIssuer``, and ``reasons`` data.
@@ -248,6 +254,8 @@
   policy constraints extension with an inhibit policy mapping element.
 * ``pc_require.pem`` - An RSA 2048 bit self-signed certificate containing a
   policy constraints extension with a require explicit policy element.
+* ``unsupported_subject_public_key_info.pem`` - A certificate whose public key
+  is an unknown OID (``1.3.6.1.4.1.8432.1.1.2``).
 
 Custom X.509 Request Vectors
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt
index adb9186..dc8bcd0 100644
--- a/docs/spelling_wordlist.txt
+++ b/docs/spelling_wordlist.txt
@@ -30,6 +30,7 @@
 Fernet
 FIPS
 hazmat
+hostname
 indistinguishability
 initialisms
 interoperable
diff --git a/setup.py b/setup.py
index 7afa84c..9c97e1d 100644
--- a/setup.py
+++ b/setup.py
@@ -1,3 +1,5 @@
+#!/usr/bin/env python
+
 # This file is dual licensed under the terms of the Apache License, Version
 # 2.0, and the BSD License. See the LICENSE file in the root of this repository
 # for complete details.
diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py
index 80f32e2..2de5a8c 100644
--- a/src/cryptography/hazmat/backends/openssl/x509.py
+++ b/src/cryptography/hazmat/backends/openssl/x509.py
@@ -64,7 +64,9 @@
 def _decode_general_name(backend, gn):
     if gn.type == backend._lib.GEN_DNS:
         data = backend._asn1_string_to_bytes(gn.d.dNSName)
-        if data.startswith(b"*."):
+        if not data:
+            decoded = u""
+        elif data.startswith(b"*."):
             # This is a wildcard name. We need to remove the leading wildcard,
             # IDNA decode, then re-add the wildcard. Wildcard characters should
             # always be left-most (RFC 2595 section 2.4).
@@ -82,7 +84,10 @@
     elif gn.type == backend._lib.GEN_URI:
         data = backend._asn1_string_to_ascii(gn.d.uniformResourceIdentifier)
         parsed = urllib_parse.urlparse(data)
-        hostname = idna.decode(parsed.hostname)
+        if parsed.hostname:
+            hostname = idna.decode(parsed.hostname)
+        else:
+            hostname = ""
         if parsed.port:
             netloc = hostname + u":" + six.text_type(parsed.port)
         else:
@@ -260,7 +265,11 @@
 
     def public_key(self):
         pkey = self._backend._lib.X509_get_pubkey(self._x509)
-        self._backend.openssl_assert(pkey != self._backend._ffi.NULL)
+        if pkey == self._backend._ffi.NULL:
+            # Remove errors from the stack.
+            self._backend._consume_errors()
+            raise ValueError("Certificate public key is of an unknown type")
+
         pkey = self._backend._ffi.gc(pkey, self._backend._lib.EVP_PKEY_free)
 
         return self._backend._evp_pkey_to_public_key(pkey)
diff --git a/tests/test_x509.py b/tests/test_x509.py
index 0c022df..8035886 100644
--- a/tests/test_x509.py
+++ b/tests/test_x509.py
@@ -2395,6 +2395,21 @@
         ]
 
 
+@pytest.mark.requires_backend_interface(interface=X509Backend)
+class TestOtherCertificate(object):
+    def test_unsupported_subject_public_key_info(self, backend):
+        cert = _load_cert(
+            os.path.join(
+                "x509", "custom", "unsupported_subject_public_key_info.pem"
+            ),
+            x509.load_pem_x509_certificate,
+            backend,
+        )
+
+        with pytest.raises(ValueError):
+            cert.public_key()
+
+
 class TestNameAttribute(object):
     def test_init_bad_oid(self):
         with pytest.raises(TypeError):
diff --git a/tests/test_x509_ext.py b/tests/test_x509_ext.py
index 8537397..1bc1462 100644
--- a/tests/test_x509_ext.py
+++ b/tests/test_x509_ext.py
@@ -1555,6 +1555,21 @@
             u'saseliminator.com'
         ]
 
+    def test_san_empty_hostname(self, backend):
+        cert = _load_cert(
+            os.path.join(
+                "x509", "custom", "san_empty_hostname.pem"
+            ),
+            x509.load_pem_x509_certificate,
+            backend
+        )
+        san = cert.extensions.get_extension_for_oid(
+            ExtensionOID.SUBJECT_ALTERNATIVE_NAME
+        )
+
+        dns = san.value.get_values_for_type(x509.DNSName)
+        assert dns == [u'']
+
     def test_san_wildcard_idna_dns_name(self, backend):
         cert = _load_cert(
             os.path.join("x509", "custom", "san_wildcard_idna.pem"),
@@ -2903,6 +2918,30 @@
             )
         ])
 
+    def test_crl_empty_hostname(self, backend):
+        cert = _load_cert(
+            os.path.join(
+                "x509", "custom", "cdp_empty_hostname.pem"
+            ),
+            x509.load_pem_x509_certificate,
+            backend
+        )
+
+        cdps = cert.extensions.get_extension_for_oid(
+            ExtensionOID.CRL_DISTRIBUTION_POINTS
+        ).value
+
+        assert cdps == x509.CRLDistributionPoints([
+            x509.DistributionPoint(
+                full_name=[x509.UniformResourceIdentifier(
+                    u"ldap:/CN=A,OU=B,dc=C,DC=D?E?F?G?H=I"
+                )],
+                relative_name=None,
+                reasons=None,
+                crl_issuer=None
+            )
+        ])
+
 
 @pytest.mark.requires_backend_interface(interface=RSABackend)
 @pytest.mark.requires_backend_interface(interface=X509Backend)
diff --git a/vectors/cryptography_vectors/x509/custom/cdp_empty_hostname.pem b/vectors/cryptography_vectors/x509/custom/cdp_empty_hostname.pem
new file mode 100644
index 0000000..8a97ea2
--- /dev/null
+++ b/vectors/cryptography_vectors/x509/custom/cdp_empty_hostname.pem
@@ -0,0 +1,33 @@
+-----BEGIN CERTIFICATE-----
+MIIFsDCCA5igAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UECgwEUHlD
+QTAeFw0xNTEwMTAwNDQ3MTVaFw0xNjEwMDkwNDQ3MTVaMA8xDTALBgNVBAoMBFB5
+Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC4CpXJ7KnM/wyy/LyK
++yO/I8G0HmZd3sUcOca8WLwIgld0FMet9vC0OIIln9PvWdYEDux1IzTEPF1KWmar
+2hgE9QcQzJVbELrqzh4SMvePcT9SW22qexDkzOvlVs/XaADf3t/HdSghi/uF/RVj
+boN0UyeSMFPB3myKZ9lIyFaJ9bZAjKI+Yfa6nvAE5b+bIc4zd8BkxzPToDq8XyBl
+j/gqYF9B3ZBJvhuztke93YDiMUlTCOIjlx/+kwjP9T1iob6oT7DanfdYxPrEIIqW
+c3vaaNNh+8p7ZkB+ipKjfYa8BdaJ6mfeUUwDrBnG2PXm/GMdQPJvFoOF5tTOZ7gd
+wQbJhHtlyl2Ah8dZiy4mU2o/4buHilu8FI755Q1gVCSZWvwnECHbF1yL7ZHPJ9Y0
+swhbcewR0xc/uYx/Mu//o0v/IRVQ4yQZDUe0B68+pqQtlUnZR/0pIuqfyvZt6tvb
+0rQt8YPahgbRxsZ81NH++0M9mD+NYuFJda+7uhS2HwAxLN2qal1repB2914z/WiW
+FHdG6sjR+Dfp3wG2Q1gIkXH6KNyOATa1kbUf4IoDKZ6T1CfEixJ3DxT0PlzDGPA1
+8QdF+jWxxyIJf2K2x95WotB9RGDLhKFfB/yw+PiaO3Yj8bKurUQEk/OhHhOxFESQ
+I5NNdN4vY0MfykL5BbKIjyabqwIDAQABo4IBFDCCARAwCQYDVR0TBAIwADARBglg
+hkgBhvhCAQEEBAMCBkAwMwYJYIZIAYb4QgENBCYWJE9wZW5TU0wgR2VuZXJhdGVk
+IFNlcnZlciBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUGjhISt50wkqiNQcSJ3YYhQ29
+CBYwPwYDVR0jBDgwNoAUGjhISt50wkqiNQcSJ3YYhQ29CBahE6QRMA8xDTALBgNV
+BAoMBFB5Q0GCCQDJtDPL+4grIjAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYI
+KwYBBQUHAwEwNgYDVR0fBC8wLTAroCmgJ4YlbGRhcDovLy9DTj1BLE9VPUIsZGM9
+QyxEQz1EP0U/Rj9HP0g9STANBgkqhkiG9w0BAQsFAAOCAgEAg5r2b6APXiXaUQeT
+daEeuWDGFtPxg/eOBoFh/GrqxxX6TfvqfcTQfwPeJqT1b5TBs5OAq3vcaJhSy4/X
+FWbMSzZjpEbr2mGrvt1EU8lAu9LZFDZD+UMvAOSAeQN5ePogUkXOip2GfRn+mK5w
+Yko9vroyprU1NhJFPagJ7jLEHKULQB5VC61Of57+72P5u+dU563pWcM0t9A1Jw5N
+ERpO1m3oXJMFKhgxeTsmitH/Q2b/39V+o5LplQtyyjvHjSthE2PM0+0A7IafQmAV
+z4C7wEaSqwOsrzEz2mw5MAqeqpc6/TcmxZOLgajVLvyEyfb5OaLiWkjj+Mi1RtWp
+Ylx4Z9B1wCgPcZYkfMmUwn/YuBSxTMWk5ktHiM6mc1K/0FFxnAR4+WXIzQW9n5Rg
+uuurBKYHWFOtfjThSEOqTSBMDEzRtk/d3n7aXGD1xOEYti6U5o3gASv7wQDIVKkv
+xpil5fmrmwEjU0dcjU5AtSZt0rLXJGywT2hTrCL7Ua8BtKwzp0KKVXLAo7O+1Vau
+u3m1D26xvgkwgB8fbgaXpFViJADHHVxBSeIuEEtkrgq2Znubc/BF7QGoXLbrsYo/
+mgbT71C8VbY+g5Gmk0xr5+xWiEBCq+Px2Bkz09J83/eJ5UU9zcMn+5oK9YQ5QAJk
+Mb7IyeivYBRJP4cqh4LdUaBIEHI=
+-----END CERTIFICATE-----
diff --git a/vectors/cryptography_vectors/x509/custom/san_empty_hostname.pem b/vectors/cryptography_vectors/x509/custom/san_empty_hostname.pem
new file mode 100644
index 0000000..90b678b
--- /dev/null
+++ b/vectors/cryptography_vectors/x509/custom/san_empty_hostname.pem
@@ -0,0 +1,32 @@
+-----BEGIN CERTIFICATE-----
+MIIFgzCCA2ugAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UECgwEUHlD
+QTAeFw0xNTEwMTAwNDQ2MTRaFw0xNjEwMDkwNDQ2MTRaMA8xDTALBgNVBAoMBFB5
+Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC4CpXJ7KnM/wyy/LyK
++yO/I8G0HmZd3sUcOca8WLwIgld0FMet9vC0OIIln9PvWdYEDux1IzTEPF1KWmar
+2hgE9QcQzJVbELrqzh4SMvePcT9SW22qexDkzOvlVs/XaADf3t/HdSghi/uF/RVj
+boN0UyeSMFPB3myKZ9lIyFaJ9bZAjKI+Yfa6nvAE5b+bIc4zd8BkxzPToDq8XyBl
+j/gqYF9B3ZBJvhuztke93YDiMUlTCOIjlx/+kwjP9T1iob6oT7DanfdYxPrEIIqW
+c3vaaNNh+8p7ZkB+ipKjfYa8BdaJ6mfeUUwDrBnG2PXm/GMdQPJvFoOF5tTOZ7gd
+wQbJhHtlyl2Ah8dZiy4mU2o/4buHilu8FI755Q1gVCSZWvwnECHbF1yL7ZHPJ9Y0
+swhbcewR0xc/uYx/Mu//o0v/IRVQ4yQZDUe0B68+pqQtlUnZR/0pIuqfyvZt6tvb
+0rQt8YPahgbRxsZ81NH++0M9mD+NYuFJda+7uhS2HwAxLN2qal1repB2914z/WiW
+FHdG6sjR+Dfp3wG2Q1gIkXH6KNyOATa1kbUf4IoDKZ6T1CfEixJ3DxT0PlzDGPA1
+8QdF+jWxxyIJf2K2x95WotB9RGDLhKFfB/yw+PiaO3Yj8bKurUQEk/OhHhOxFESQ
+I5NNdN4vY0MfykL5BbKIjyabqwIDAQABo4HoMIHlMAkGA1UdEwQCMAAwEQYJYIZI
+AYb4QgEBBAQDAgZAMDMGCWCGSAGG+EIBDQQmFiRPcGVuU1NMIEdlbmVyYXRlZCBT
+ZXJ2ZXIgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFBo4SEredMJKojUHEid2GIUNvQgW
+MD8GA1UdIwQ4MDaAFBo4SEredMJKojUHEid2GIUNvQgWoROkETAPMQ0wCwYDVQQK
+DARQeUNBggkAybQzy/uIKyIwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsG
+AQUFBwMBMAsGA1UdEQQEMAKCADANBgkqhkiG9w0BAQsFAAOCAgEAjDlZFmLz7JPA
+8sQCjTbHkTJsn4vD/VqZPszqXuaR/De2R8EhnJEd2uTMYOG+X9iFkyxUYl3OWzQ3
+GLznmjLaobuOQ9ck3RhNDaSjcqTVFGB8EXIVrM3ioh/1YB9GPlOuaUFWJKwWQkS0
+GqUp5JlmWV9ScyW7R7IgZOMTb2opaww0vlSNudqaFGjpTmSd/VNPaAIAEK3NQwZa
+XtQ70CqiwBAHoDWvHfFfIiXVvkze0QPzWbKPRmK0iaGzxZ9E+0+w36r2YL0vkQzQ
+9fwrfPM10Am7VdHnyExbm/gr9LkJQDb6Igz3M6Hd8Ui7w8dlaw0+jzTZ1cwXyOL8
+4BjbBvuFvsx8OyCaPl+EO0Z4XPquPWV80igbGbkxGQiIFMP5TyK+7yGB+1txWnMR
+8ADmuMhCRUJ5Gim5p8yrq6cZTsxfgbmNsPCWeTroyscBXZEDYEzLpUvs/SI826+Y
+a607iwg4YcHl9JUN2bcTay5G0tXFyrI5iLfEeMaSiRSM1EOqyYsBI9buf3WhH+rm
+mlXyXt1mXhHvZDY/kWdbiHNc7GNAhhCQIuuLHhXd3/6eyMn8iGE5a/cbjPVwcYLw
+bxjb9YB6yWbrAQSG/ts89v/efqqhxnpjXtZ+gJLLmBrVq70UZj0ptNKDCvsCNlHr
+cHZkH9okuLpO5zNsYPEWjg1NoF4wwxw=
+-----END CERTIFICATE-----
diff --git a/vectors/cryptography_vectors/x509/custom/unsupported_subject_public_key_info.pem b/vectors/cryptography_vectors/x509/custom/unsupported_subject_public_key_info.pem
new file mode 100644
index 0000000..aa06dfb
--- /dev/null
+++ b/vectors/cryptography_vectors/x509/custom/unsupported_subject_public_key_info.pem
@@ -0,0 +1,28 @@
+-----BEGIN CERTIFICATE-----
+MIIEyTCCA7GgAwIBAgIIASZ+ezr7rN0wDQYJKoZIhvcNAQEFBQAwgZAxCzAJBgNV
+BAYTAlVTMRAwDgYDVQQIEwdNb250YW5hMRAwDgYDVQQHEwdCb3plbWFuMREwDwYD
+VQQKEwhTYXd0b290aDETMBEGA1UECxMKQ29uc3VsdGluZzEWMBQGA1UEAxMNd3d3
+Lnlhc3NsLmNvbTEdMBsGCSqGSIb3DQEJARYOaW5mb0B5YXNzbC5jb20wIhgPMjAx
+MTEyMDUwMDE2MzdaGA8yMDEzMDQxOTAxMTYzN1owgYoxCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIEwJPUjERMA8GA1UEBxMIUG9ydGxhbmQxDjAMBgNVBAoTBXlhU1NMMRQw
+EgYDVQQLEwtEZXZlbG9wbWVudDEWMBQGA1UEAxMNd3d3Lnlhc3NsLmNvbTEdMBsG
+CSqGSIb3DQEJARYOaW5mb0B5YXNzbC5jb20wggJLMBgGCisGAQQBwXABAQIGCisG
+AQQBwXABAi4DggItAASCAihFDRAy0fOBZth/IRQFJeuEUgrViJfGvKOUuNW6yYmn
+9/YXT2I3/aiBZ/udSehoEFVPNgLs/ZWwNrsIuETH5TPkS1e9Ig4I5G839deKT89M
+Qpq7GiKLwlLY3He/a6O+/UMEFH4ShdhDopsH2+IsWCX0H7Lvp8L8RqURrQNFXvlr
+xRAFiBixEQNry2HyEcVz/9TQSdifE4KGUtneErqsk1/Sms1m1/NqW30H77YerJfs
+QWsOEgasoJnYWS6knJC4XsUbJKqKcHRc6XeODOyf72J3ESvES2C+cqEsShxVP7zG
+hDiHurwfyvIAUL4bZSBtlAqt60iOEsXScXwdbNrj+4iuFAyjX8+JrxGMbDNi3X5l
+L2RLUiEIKUSGUozbDlR3jU2WoHUm76mZwjGe1+vOKpvqh5yrRoyqiDERj8wsGrDO
+MdoheW1xSjQ3p5fQ/UOtagWA5Lh/MqbCIHdMzMLpbOmfhFJA5BXaNg/qThhjpmvf
+csYfwWCWukKKbjfY7cxOVMuUN0VvoYBjOxt5UQhXuPjH/+5s4J7E/IxQrWz6fhcG
+wfvJjWJjedfhP23Jm4zodbwtU6MgPF641DcAwcnBqSi/Ugi7d0YeHMqTJkSnIJZV
+r3v1YLuqiFDzB6bx69DGpCxFMxIpdOPq4a9WpeQQ9H7cBK0HFl4tRPNnQ2XCrKMc
+86gQ35aaM2vPvgj0d/zgC0AG8WFQEG1wYBvLEgfiQsi7auXoScYZA8AwDQYJKoZI
+hvcNAQEFBQADggEBAJ7eyiJIGiyyrhAdaYOit3U3CUkGSatNXTkn8PRO8SwzPWCi
+FQ+4AePYV+/ovtNZiqLwm7mVa3s2CS8LCk2s9/ld22cDJNV+gDkzrelUyTLUi0jr
+zZJwEiaNXIEkYrLGifSzoNUgQBTzDmOSkm2UpIX70GTsXF73FKdqonf1VTnopVKa
+XZDpIG3/TKyh8jCwowMrkxnHS886FhXiHGCBzM1rnp3S+r3b+rTqoKoeuZQnDgJP
+IZwnZL6agtwbUfmZj6/868irlsLtC9M5nKBtj/U/tQIrW52XEhBqChmTXIq0JNL1
+++kWLLeu9t0T53Pth3VxMT/ePV0aURQvjINm60o=
+-----END CERTIFICATE-----
diff --git a/vectors/setup.py b/vectors/setup.py
index 53ec82e..bf02e38 100644
--- a/vectors/setup.py
+++ b/vectors/setup.py
@@ -1,3 +1,5 @@
+#!/usr/bin/env python
+
 # This file is dual licensed under the terms of the Apache License, Version
 # 2.0, and the BSD License. See the LICENSE file in the root of this repository
 # for complete details.