diff -r 9da137faaa9c -r 6315c1e14f75 mercurial/sslutil.py --- a/mercurial/sslutil.py Wed May 25 19:57:31 2016 -0700 +++ b/mercurial/sslutil.py Sat May 28 11:12:02 2016 -0700 @@ -106,6 +106,23 @@ return ssl.wrap_socket(socket, **args) +def _hostsettings(ui, hostname): + """Obtain security settings for a hostname. + + Returns a dict of settings relevant to that hostname. + """ + s = { + # List of 2-tuple of (hash algorithm, hash). + 'certfingerprints': [], + } + + # Fingerprints from [hostfingerprints] are always SHA-1. + for fingerprint in ui.configlist('hostfingerprints', hostname, []): + fingerprint = fingerprint.replace(':', '').lower() + s['certfingerprints'].append(('sha1', fingerprint)) + + return s + def _determinecertoptions(ui, host): """Determine certificate options for a connections. @@ -217,6 +234,7 @@ sslsocket._hgstate = { 'caloaded': caloaded, 'hostname': serverhostname, + 'settings': _hostsettings(ui, serverhostname), 'ui': ui, } @@ -292,6 +310,7 @@ """ host = sock._hgstate['hostname'] ui = sock._hgstate['ui'] + settings = sock._hgstate['settings'] try: peercert = sock.getpeercert(True) @@ -305,15 +324,13 @@ # If a certificate fingerprint is pinned, use it and only it to # validate the remote cert. - hostfingerprints = ui.configlist('hostfingerprints', host) peerfingerprint = util.sha1(peercert).hexdigest() nicefingerprint = ":".join([peerfingerprint[x:x + 2] for x in xrange(0, len(peerfingerprint), 2)]) - if hostfingerprints: + if settings['certfingerprints']: fingerprintmatch = False - for hostfingerprint in hostfingerprints: - if peerfingerprint.lower() == \ - hostfingerprint.replace(':', '').lower(): + for hash, fingerprint in settings['certfingerprints']: + if peerfingerprint.lower() == fingerprint: fingerprintmatch = True break if not fingerprintmatch: