From patchwork Mon May 30 23:03:08 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [6,of,9] sslutil: print SHA-256 fingerprint by default From: Gregory Szorc X-Patchwork-Id: 15271 Message-Id: To: mercurial-devel@mercurial-scm.org Date: Mon, 30 May 2016 16:03:08 -0700 # HG changeset patch # User Gregory Szorc # Date 1464648159 25200 # Mon May 30 15:42:39 2016 -0700 # Node ID da5c28f02c7b9561a15d2516c7bf8f67d98a82bd # Parent 2d7ec4ae534f15e844967ba61fe0b84e2518fccb sslutil: print SHA-256 fingerprint by default The world is starting to move on from SHA-1. A few commits ago, we gained the ability to define certificate fingerprints using SHA-256 and SHA-512. Let's start printing the SHA-256 fingerprint instead of the SHA-1 fingerprint to encourage people to pin with a more secure hashing algorithm. There is still a bit of work to be done around the fingerprint messaging. This will be addressed in subsequent commits. diff --git a/mercurial/sslutil.py b/mercurial/sslutil.py --- a/mercurial/sslutil.py +++ b/mercurial/sslutil.py @@ -371,36 +371,40 @@ def validatesocket(sock): # If a certificate fingerprint is pinned, use it and only it to # validate the remote cert. peerfingerprints = { 'sha1': util.sha1(peercert).hexdigest(), 'sha256': util.sha256(peercert).hexdigest(), 'sha512': util.sha512(peercert).hexdigest(), } - nicefingerprint = ':'.join([peerfingerprints['sha1'][x:x + 2] - for x in range(0, len(peerfingerprints['sha1']), 2)]) + + def fmtfingerprint(s): + return ':'.join([s[x:x + 2] for x in range(0, len(s), 2)]) + + legacyfingerprint = fmtfingerprint(peerfingerprints['sha1']) + nicefingerprint = 'sha256:%s' % fmtfingerprint(peerfingerprints['sha256']) if settings['legacyfingerprint']: section = 'hostfingerprint' else: section = 'hostsecurity' if settings['certfingerprints']: fingerprintmatch = False for hash, fingerprint in settings['certfingerprints']: if peerfingerprints[hash].lower() == fingerprint: fingerprintmatch = True break if not fingerprintmatch: raise error.Abort(_('certificate for %s has unexpected ' - 'fingerprint %s') % (host, nicefingerprint), - hint=_('check %s configuration') % section) + 'fingerprint %s') % (host, legacyfingerprint), + hint=_('check %s configuration') % section) ui.debug('%s certificate matched fingerprint %s\n' % - (host, nicefingerprint)) + (host, legacyfingerprint)) return if not sock._hgstate['caloaded']: ui.warn(_('warning: %s certificate with fingerprint %s ' 'not verified (check %s or web.cacerts config ' 'setting)\n') % (host, nicefingerprint, section)) return diff --git a/tests/test-https.t b/tests/test-https.t --- a/tests/test-https.t +++ b/tests/test-https.t @@ -171,17 +171,17 @@ we are able to load CA certs. [255] #endif $ DISABLECACERTS="--config web.cacerts=!" clone via pull $ hg clone https://localhost:$HGPORT/ copy-pull $DISABLECACERTS - warning: localhost certificate with fingerprint 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified (check hostsecurity or web.cacerts config setting) + warning: localhost certificate with fingerprint sha256:62:09:97:2f:97:60:e3:65:8f:12:5d:78:9e:35:a1:36:7a:65:4b:0e:9f:ac:db:c3:bc:6e:b6:a3:c0:16:e0:30 not verified (check hostsecurity or web.cacerts config setting) requesting all changes adding changesets adding manifests adding file changes added 1 changesets with 4 changes to 4 files updating to branch default 4 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg verify -R copy-pull @@ -198,17 +198,17 @@ clone via pull pull without cacert $ cd copy-pull $ echo '[hooks]' >> .hg/hgrc $ echo "changegroup = printenv.py changegroup" >> .hg/hgrc $ hg pull $DISABLECACERTS pulling from https://localhost:$HGPORT/ - warning: localhost certificate with fingerprint 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified (check hostsecurity or web.cacerts config setting) + warning: localhost certificate with fingerprint sha256:62:09:97:2f:97:60:e3:65:8f:12:5d:78:9e:35:a1:36:7a:65:4b:0e:9f:ac:db:c3:bc:6e:b6:a3:c0:16:e0:30 not verified (check hostsecurity or web.cacerts config setting) searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files changegroup hook: HG_NODE=5fed3813f7f5e1824344fdc9cf8f63bb662c292d HG_NODE_LAST=5fed3813f7f5e1824344fdc9cf8f63bb662c292d HG_SOURCE=pull HG_TXNID=TXN:* HG_URL=https://localhost:$HGPORT/ (glob) (run 'hg update' to get a working copy) $ cd .. @@ -239,17 +239,17 @@ variables in the filename searching for changes no changes found cacert mismatch $ hg -R copy-pull pull --config web.cacerts=pub.pem https://127.0.0.1:$HGPORT/ pulling from https://127.0.0.1:$HGPORT/ abort: 127.0.0.1 certificate error: certificate is for localhost - (configure hostsecurity 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca or use --insecure to connect insecurely) + (configure hostsecurity sha256:62:09:97:2f:97:60:e3:65:8f:12:5d:78:9e:35:a1:36:7a:65:4b:0e:9f:ac:db:c3:bc:6e:b6:a3:c0:16:e0:30 or use --insecure to connect insecurely) [255] $ hg -R copy-pull pull --config web.cacerts=pub.pem https://127.0.0.1:$HGPORT/ --insecure pulling from https://127.0.0.1:$HGPORT/ warning: connection security to 127.0.0.1 is disabled per current settings; communication is susceptible to eavesdropping and tampering searching for changes no changes found $ hg -R copy-pull pull --config web.cacerts=pub-other.pem pulling from https://localhost:$HGPORT/