diff --git a/0001-SSL-Handle-wildcards-in-Subject-Alternative-Names.patch b/0001-SSL-Handle-wildcards-in-Subject-Alternative-Names.patch new file mode 100644 index 0000000..64d5990 --- /dev/null +++ b/0001-SSL-Handle-wildcards-in-Subject-Alternative-Names.patch @@ -0,0 +1,158 @@ +From 097ca3d53f3d332c74ea10bf8e6bb088013640df Mon Sep 17 00:00:00 2001 +From: Dominik Heidler +Date: Tue, 10 Dec 2013 13:34:04 +0100 +Subject: [PATCH] SSL: Handle wildcards in Subject Alternative Names + +Closes-Bug: #1259528 + +Change-Id: Iedc2b98d47f1f9433a4cfd77e07f7f86bae806c1 +--- + glanceclient/common/http.py | 22 +++++++++----- + tests/test_ssl.py | 28 ++++++++++++++++++ + tests/var/wildcard-san-certificate.crt | 54 ++++++++++++++++++++++++++++++++++ + 3 files changed, 96 insertions(+), 8 deletions(-) + create mode 100644 tests/var/wildcard-san-certificate.crt + +Index: python-glanceclient-0.11.0/glanceclient/common/http.py +=================================================================== +--- python-glanceclient-0.11.0.orig/glanceclient/common/http.py ++++ python-glanceclient-0.11.0/glanceclient/common/http.py +@@ -326,17 +326,22 @@ class VerifiedHTTPSConnection(HTTPSConne + connecting to, ie that the certificate's Common Name + or a Subject Alternative Name matches 'host'. + """ ++ def check_match(name): ++ # Directly match the name ++ if name == host: ++ return True ++ ++ # Support single wildcard matching ++ if name.startswith('*.') and host.find('.') > 0: ++ if name[2:] == host.split('.', 1)[1]: ++ return True ++ + common_name = x509.get_subject().commonName + + # First see if we can match the CN +- if common_name == host: ++ if check_match(common_name): + return True + +- # Support single wildcard matching +- if common_name.startswith('*.') and host.find('.') > 0: +- if common_name[2:] == host.split('.', 1)[1]: +- return True +- + # Also try Subject Alternative Names for a match + san_list = None + for i in xrange(x509.get_extension_count()): +@@ -344,8 +349,9 @@ class VerifiedHTTPSConnection(HTTPSConne + if ext.get_short_name() == 'subjectAltName': + san_list = str(ext) + for san in ''.join(san_list.split()).split(','): +- if san == "DNS:%s" % host: +- return True ++ if san.startswith('DNS:'): ++ if check_match(san.split(':', 1)[1]): ++ return True + + # Server certificate does not match host + msg = ('Host "%s" does not match x509 certificate contents: ' +Index: python-glanceclient-0.11.0/tests/test_ssl.py +=================================================================== +--- python-glanceclient-0.11.0.orig/tests/test_ssl.py ++++ python-glanceclient-0.11.0/tests/test_ssl.py +@@ -165,6 +165,34 @@ class TestVerifiedHTTPSConnection(testto + except Exception: + self.fail('Unexpected exception.') + ++ def test_ssl_cert_subject_alt_name_wildcard(self): ++ """ ++ Test certificate: wildcard SAN match ++ """ ++ cert_file = os.path.join(TEST_VAR_DIR, 'wildcard-san-certificate.crt') ++ cert = crypto.load_certificate(crypto.FILETYPE_PEM, ++ file(cert_file).read()) ++ # The expected cert should have CN=0.0.0.0 ++ self.assertEqual(cert.get_subject().commonName, '0.0.0.0') ++ try: ++ conn = http.VerifiedHTTPSConnection('alt1.example.com', 0) ++ conn.verify_callback(None, cert, 0, 0, 1) ++ except Exception: ++ self.fail('Unexpected exception.') ++ ++ try: ++ conn = http.VerifiedHTTPSConnection('alt2.example.com', 0) ++ conn.verify_callback(None, cert, 0, 0, 1) ++ except Exception: ++ self.fail('Unexpected exception.') ++ ++ try: ++ conn = http.VerifiedHTTPSConnection('alt3.example.net', 0) ++ conn.verify_callback(None, cert, 0, 0, 1) ++ self.fail('Failed to raise assertion.') ++ except exc.SSLCertificateError: ++ pass ++ + def test_ssl_cert_mismatch(self): + """ + Test certificate: bogus host +Index: python-glanceclient-0.11.0/tests/var/wildcard-san-certificate.crt +=================================================================== +--- /dev/null ++++ python-glanceclient-0.11.0/tests/var/wildcard-san-certificate.crt +@@ -0,0 +1,54 @@ ++#Certificate: ++# Data: ++# Version: 3 (0x2) ++# Serial Number: 11990626514780340979 (0xa66743493fdcc2f3) ++# Signature Algorithm: sha1WithRSAEncryption ++# Issuer: C=US, ST=CA, L=State1, O=Openstack Test Org, OU=Openstack Test Unit, CN=0.0.0.0 ++# Validity ++# Not Before: Dec 10 15:31:22 2013 GMT ++# Not After : Nov 16 15:31:22 2113 GMT ++# Subject: C=US, ST=CA, L=State1, O=Openstack Test Org, OU=Openstack Test Unit, CN=0.0.0.0 ++# Subject Public Key Info: ++# Public Key Algorithm: rsaEncryption ++# Public-Key: (2048 bit) ++# Modulus: ++# 00:ca:6b:07:73:53:24:45:74:05:a5:2a:27:bd:3e: ++# . ++# . ++# . ++# Exponent: 65537 (0x10001) ++# X509v3 extensions: ++# X509v3 Key Usage: ++# Key Encipherment, Data Encipherment ++# X509v3 Extended Key Usage: ++# TLS Web Server Authentication ++# X509v3 Subject Alternative Name: ++# DNS:foo.example.net, DNS:*.example.com ++# Signature Algorithm: sha1WithRSAEncryption ++# 7e:41:69:da:f4:3c:06:d6:83:c6:f2:db:df:37:f1:ac:fa:f5: ++# . ++# . ++# . ++-----BEGIN CERTIFICATE----- ++MIIDxDCCAqygAwIBAgIJAKZnQ0k/3MLzMA0GCSqGSIb3DQEBBQUAMHgxCzAJBgNV ++BAYTAlVTMQswCQYDVQQIEwJDQTEPMA0GA1UEBxMGU3RhdGUxMRswGQYDVQQKExJP ++cGVuc3RhY2sgVGVzdCBPcmcxHDAaBgNVBAsTE09wZW5zdGFjayBUZXN0IFVuaXQx ++EDAOBgNVBAMTBzAuMC4wLjAwIBcNMTMxMjEwMTUzMTIyWhgPMjExMzExMTYxNTMx ++MjJaMHgxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEPMA0GA1UEBxMGU3RhdGUx ++MRswGQYDVQQKExJPcGVuc3RhY2sgVGVzdCBPcmcxHDAaBgNVBAsTE09wZW5zdGFj ++ayBUZXN0IFVuaXQxEDAOBgNVBAMTBzAuMC4wLjAwggEiMA0GCSqGSIb3DQEBAQUA ++A4IBDwAwggEKAoIBAQDKawdzUyRFdAWlKie9Pn10j7frffN+z1gEMluK2CtDEwv9 ++kbD4uS/Kz4dujfTx03mdyNfiMVlOM+YJm/qeLLSdJyFyvZ9Y3WmJ+vT2RGlMMhLd ++/wEnMRrTYLL39pwI6z+gyw+4D78Pyv/OXy02IA6WtVEefYSx1vmVngb3pL+iBzhO ++8CZXNI6lqrFhh+Hr4iMkYMtY1vTnwezAL6p64E/ZAFNPYCEJlacESTLQ4VZYniHc ++QTgnE1czlI1vxlIk1KDXAzUGeeopZecRih9qlTxtOpklqEciQEE+sHtPcvyvdRE9 ++Bdyx5rNSALLIcXs0ViJE1RPlw3fjdBoDIOygqvX1AgMBAAGjTzBNMAsGA1UdDwQE ++AwIEMDATBgNVHSUEDDAKBggrBgEFBQcDATApBgNVHREEIjAggg9mb28uZXhhbXBs ++ZS5uZXSCDSouZXhhbXBsZS5jb20wDQYJKoZIhvcNAQEFBQADggEBAH5Badr0PAbW ++g8by29838az69Raul5IkpZQ5V3O1NaNNWxvmF1q8zFFqqGK5ktXJAwGiwnYEBb30 ++Zfrr+eFIEERzBthSJkWlP8NG+2ooMyg50femp+asAvW+KYYefJW8KaXTsznMsAFy ++z1agcWVYVZ4H9PwunEYn/rM1krLEe4Cagsw5nmf8VqZg+hHtw930q8cRzgDsZdfA ++jVK6dWdmzmLCUTL1GKCeNriDw1jIeFvNufC+Q3orH7xBx4VL+NV5ORWdNY/B8q1b ++mFHdzbuZX6v39+2ww6aZqG2orfxUocc/5Ox6fXqenKPI3moeHS6Ktesq7sEQSJ6H ++QZFsTuT/124= ++-----END CERTIFICATE----- diff --git a/python-glanceclient.changes b/python-glanceclient.changes index 2f4bf34..7e19102 100644 --- a/python-glanceclient.changes +++ b/python-glanceclient.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Fri Dec 13 09:42:23 UTC 2013 - dmueller@suse.com + +- add 0001-SSL-Handle-wildcards-in-Subject-Alternative-Names.patch + ------------------------------------------------------------------- Mon Oct 7 10:21:35 UTC 2013 - opensuse-cloud@opensuse.org diff --git a/python-glanceclient.spec b/python-glanceclient.spec index 6978362..4ae5927 100644 --- a/python-glanceclient.spec +++ b/python-glanceclient.spec @@ -1,7 +1,7 @@ # # spec file for package python-glanceclient # -# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -27,6 +27,7 @@ Group: Development/Languages/Python Url: http://launchpad.net/python-glanceclient Source: python-glanceclient-0.11.0.tar.gz Source2: openstack-glance.sh +Patch0: 0001-SSL-Handle-wildcards-in-Subject-Alternative-Names.patch BuildRequires: openstack-suse-macros BuildRequires: python-base # Documentation build requirements: @@ -81,6 +82,7 @@ This package contains testsuite files for %{name}. %prep %setup -q -n python-glanceclient-0.11.0 +%patch0 -p1 %openstack_cleanup_prep # Our package versioning scheme is different (but we provide the correct thing) thus: sed -i "s|python-keystoneclient>=0.1.2,<1|python-keystoneclient|" requirements.txt