# HG changeset patch # User Nicolas Bareil # Date 2011-06-17 23:03:03 # Node ID 27b080aa880aaf8bd99728928358c9d37e231a3e # Parent d89f8089817897b1cc3d032e4ba228499bb22319 sslutil: fall back to commonName when no dNSName in subjectAltName (issue2798) Any entries in subjectAltName would prevent fallback to using commonName, but RFC 2818 says: If a subjectAltName extension of type dNSName is present, that MUST be used as the identity. Otherwise, the (most specific) Common Name field in the Subject field of the certificate MUST be used. We now only consider dNSNames in subjectAltName. (dNSName is known as 'DNS' in OpenSSL/Python.) diff --git a/mercurial/sslutil.py b/mercurial/sslutil.py --- a/mercurial/sslutil.py +++ b/mercurial/sslutil.py @@ -48,7 +48,8 @@ def _verifycert(cert, hostname): for name in certnames: if matchdnsname(name): return None - return _('certificate is for %s') % ', '.join(certnames) + if certnames: + return _('certificate is for %s') % ', '.join(certnames) # subject is only checked when subjectAltName is empty for s in cert.get('subject', []): diff --git a/tests/test-url.py b/tests/test-url.py --- a/tests/test-url.py +++ b/tests/test-url.py @@ -33,9 +33,13 @@ check(_verifycert(san_cert, 'example.net None) check(_verifycert(san_cert, 'foo.example.net'), None) -# subject is only checked when subjectAltName is empty +# no fallback to subject commonName when subjectAltName has DNS check(_verifycert(san_cert, 'example.com'), 'certificate is for *.example.net, example.net') +# fallback to subject commonName when no DNS in subjectAltName +san_cert = {'subject': ((('commonName', 'example.com'),),), + 'subjectAltName': (('IP Address', '8.8.8.8'),)} +check(_verifycert(san_cert, 'example.com'), None) # Avoid some pitfalls check(_verifycert(cert('*.foo'), 'foo'), @@ -49,6 +53,10 @@ check(_verifycert({'subject': ()}, check(_verifycert(None, 'example.com'), 'no certificate received') +# Unicode (IDN) certname isn't supported +check(_verifycert(cert(u'\u4f8b.jp'), 'example.jp'), + 'IDN in certificate not supported') + import doctest def test_url(): @@ -211,7 +219,3 @@ def test_url(): """ doctest.testmod(optionflags=doctest.NORMALIZE_WHITESPACE) - -# Unicode (IDN) certname isn't supported -check(_verifycert(cert(u'\u4f8b.jp'), 'example.jp'), - 'IDN in certificate not supported')