Patchwork [6,of,9,V3] sslutil: print SHA-256 fingerprint by default

login
register
mail settings
Submitter Gregory Szorc
Date June 2, 2016, 3:16 a.m.
Message ID <baae958f1ccd0a5f905b.1464837380@ubuntu-vm-main>
Download mbox | patch
Permalink /patch/15332/
State Superseded
Delegated to: Yuya Nishihara
Headers show

Comments

Gregory Szorc - June 2, 2016, 3:16 a.m.
# HG changeset patch
# User Gregory Szorc <gregory.szorc@gmail.com>
# Date 1464648159 25200
#      Mon May 30 15:42:39 2016 -0700
# Node ID baae958f1ccd0a5f905b4ce9a675c50cdf25c335
# Parent  a2294c4b56839b7afc0a3501890700b3fbc3de3c
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.

Patch

diff --git a/mercurial/sslutil.py b/mercurial/sslutil.py
--- a/mercurial/sslutil.py
+++ b/mercurial/sslutil.py
@@ -368,36 +368,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 devel.disableloaddefaultcerts=true"
 
 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/