##// END OF EJS Templates
url: check subjectAltName when verifying ssl certificate...
Yuya Nishihara -
r13249:75d0c38a stable
parent child Browse files
Show More
@@ -488,13 +488,26 b' class httphandler(keepalive.HTTPHandler)'
488 488
489 489 def _verifycert(cert, hostname):
490 490 '''Verify that cert (in socket.getpeercert() format) matches hostname.
491 CRLs and subjectAltName are not handled.
491 CRLs is not handled.
492 492
493 493 Returns error message if any problems are found and None on success.
494 494 '''
495 495 if not cert:
496 496 return _('no certificate received')
497 497 dnsname = hostname.lower()
498 def matchdnsname(certname):
499 return (certname == dnsname or
500 '.' in dnsname and certname == '*.' + dnsname.split('.', 1)[1])
501
502 san = cert.get('subjectAltName', [])
503 if san:
504 certnames = [value.lower() for key, value in san if key == 'DNS']
505 for name in certnames:
506 if matchdnsname(name):
507 return None
508 return _('certificate is for %s') % ', '.join(certnames)
509
510 # subject is only checked when subjectAltName is empty
498 511 for s in cert.get('subject', []):
499 512 key, value = s[0]
500 513 if key == 'commonName':
@@ -503,11 +516,10 b' def _verifycert(cert, hostname):'
503 516 certname = value.lower().encode('ascii')
504 517 except UnicodeEncodeError:
505 518 return _('IDN in certificate not supported')
506 if (certname == dnsname or
507 '.' in dnsname and certname == '*.' + dnsname.split('.', 1)[1]):
519 if matchdnsname(certname):
508 520 return None
509 521 return _('certificate is for %s') % certname
510 return _('no commonName found in certificate')
522 return _('no commonName or subjectAltName found in certificate')
511 523
512 524 if has_https:
513 525 class BetterHTTPS(httplib.HTTPSConnection):
@@ -25,6 +25,18 b" check(_verifycert(cert('*.example.com'),"
25 25 check(_verifycert(cert('*.example.com'), 'w.w.example.com'),
26 26 'certificate is for *.example.com')
27 27
28 # Test subjectAltName
29 san_cert = {'subject': ((('commonName', 'example.com'),),),
30 'subjectAltName': (('DNS', '*.example.net'),
31 ('DNS', 'example.net'))}
32 check(_verifycert(san_cert, 'example.net'),
33 None)
34 check(_verifycert(san_cert, 'foo.example.net'),
35 None)
36 # subject is only checked when subjectAltName is empty
37 check(_verifycert(san_cert, 'example.com'),
38 'certificate is for *.example.net, example.net')
39
28 40 # Avoid some pitfalls
29 41 check(_verifycert(cert('*.foo'), 'foo'),
30 42 'certificate is for *.foo')
@@ -33,7 +45,7 b" check(_verifycert(cert('*o'), 'foo'),"
33 45
34 46 check(_verifycert({'subject': ()},
35 47 'example.com'),
36 'no commonName found in certificate')
48 'no commonName or subjectAltName found in certificate')
37 49 check(_verifycert(None, 'example.com'),
38 50 'no certificate received')
39 51
General Comments 0
You need to be logged in to leave comments. Login now