504 _generic_start_transaction(self, h, req) |
504 _generic_start_transaction(self, h, req) |
505 return keepalive.HTTPHandler._start_transaction(self, h, req) |
505 return keepalive.HTTPHandler._start_transaction(self, h, req) |
506 |
506 |
507 def _verifycert(cert, hostname): |
507 def _verifycert(cert, hostname): |
508 '''Verify that cert (in socket.getpeercert() format) matches hostname. |
508 '''Verify that cert (in socket.getpeercert() format) matches hostname. |
509 CRLs and subjectAltName are not handled. |
509 CRLs is not handled. |
510 |
510 |
511 Returns error message if any problems are found and None on success. |
511 Returns error message if any problems are found and None on success. |
512 ''' |
512 ''' |
513 if not cert: |
513 if not cert: |
514 return _('no certificate received') |
514 return _('no certificate received') |
515 dnsname = hostname.lower() |
515 dnsname = hostname.lower() |
|
516 def matchdnsname(certname): |
|
517 return (certname == dnsname or |
|
518 '.' in dnsname and certname == '*.' + dnsname.split('.', 1)[1]) |
|
519 |
|
520 san = cert.get('subjectAltName', []) |
|
521 if san: |
|
522 certnames = [value.lower() for key, value in san if key == 'DNS'] |
|
523 for name in certnames: |
|
524 if matchdnsname(name): |
|
525 return None |
|
526 return _('certificate is for %s') % ', '.join(certnames) |
|
527 |
|
528 # subject is only checked when subjectAltName is empty |
516 for s in cert.get('subject', []): |
529 for s in cert.get('subject', []): |
517 key, value = s[0] |
530 key, value = s[0] |
518 if key == 'commonName': |
531 if key == 'commonName': |
519 certname = value.lower() |
532 try: |
520 if (certname == dnsname or |
533 # 'subject' entries are unicode |
521 '.' in dnsname and certname == '*.' + dnsname.split('.', 1)[1]): |
534 certname = value.lower().encode('ascii') |
|
535 except UnicodeEncodeError: |
|
536 return _('IDN in certificate not supported') |
|
537 if matchdnsname(certname): |
522 return None |
538 return None |
523 return _('certificate is for %s') % certname |
539 return _('certificate is for %s') % certname |
524 return _('no commonName found in certificate') |
540 return _('no commonName or subjectAltName found in certificate') |
525 |
541 |
526 if has_https: |
542 if has_https: |
527 class BetterHTTPS(httplib.HTTPSConnection): |
543 class BetterHTTPS(httplib.HTTPSConnection): |
528 send = keepalive.safesend |
544 send = keepalive.safesend |
529 |
545 |