# HG changeset patch # User Gregory Szorc # Date 1460311378 25200 # Node ID 3819c349b1947964573e014a36c00801356d4123 # Parent 1fde84d42f9c923b7e17b38894136af5f5a0b179 sslutil: document and slightly refactor validation logic This main purpose of this patch is to make it clearer that fingerprint pinning takes precedence over CA verification. This will make subsequent refactoring to the validation code easier to read. diff -r 1fde84d42f9c -r 3819c349b194 mercurial/sslutil.py --- a/mercurial/sslutil.py Sun Apr 10 11:00:41 2016 -0700 +++ b/mercurial/sslutil.py Sun Apr 10 11:02:58 2016 -0700 @@ -264,8 +264,6 @@ def __call__(self, sock, strict=False): host = self.host - cacerts = self.ui.config('web', 'cacerts') - hostfingerprints = self.ui.configlist('hostfingerprints', host) if not sock.cipher(): # work around http://bugs.python.org/issue13721 raise error.Abort(_('%s ssl connection error') % host) @@ -278,6 +276,10 @@ if not peercert: raise error.Abort(_('%s certificate error: ' 'no certificate received') % host) + + # If a certificate fingerprint is pinned, use it and only it to + # validate the remote cert. + hostfingerprints = self.ui.configlist('hostfingerprints', host) peerfingerprint = util.sha1(peercert).hexdigest() nicefingerprint = ":".join([peerfingerprint[x:x + 2] for x in xrange(0, len(peerfingerprint), 2)]) @@ -294,7 +296,11 @@ hint=_('check hostfingerprint configuration')) self.ui.debug('%s certificate matched fingerprint %s\n' % (host, nicefingerprint)) - elif cacerts != '!': + return + + # No pinned fingerprint. Establish trust by looking at the CAs. + cacerts = self.ui.config('web', 'cacerts') + if cacerts != '!': msg = _verifycert(peercert2, host) if msg: raise error.Abort(_('%s certificate error: %s') % (host, msg),