mercurial/url.py
changeset 13250 1a4330e30017
parent 13234 0935ff767285
parent 13249 75d0c38a0bca
child 13315 0d1dca7d2a04
equal deleted inserted replaced
13247:af50a62e9c20 13250:1a4330e30017
   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