sslutil: display a better error message when CA file loading fails
authorGregory Szorc <gregory.szorc@gmail.com>
Wed, 29 Jun 2016 19:37:38 -0700
changeset 29446 2f7f1e10f840
parent 29445 072e4a595607
child 29447 13edc11eb7b7
sslutil: display a better error message when CA file loading fails Before, sslcontext.load_verify_locations() would raise a ssl.SSLError which would be caught further up the stack and converted to a urlerror. By that time, we lost track of what actually errored. Trapping the error here gives users a slightly more actionable error message. The behavior between Python <2.7.9 and Python 2.7.9+ differs. This is because our fake SSLContext class installed on <2.7.9 doesn't actually do anything during load_verify_locations: it defers actions until wrap_socket() time. Unfortunately, a number of errors can occur at wrap_socket() time and we're unable to ascertain what the root cause is. But that shouldn't stop us from providing better error messages to people running a modern and secure Python version.
mercurial/sslutil.py
tests/test-https.t
--- a/mercurial/sslutil.py	Wed Jun 29 18:15:28 2016 -0700
+++ b/mercurial/sslutil.py	Wed Jun 29 19:37:38 2016 -0700
@@ -268,7 +268,12 @@
         sslcontext.load_cert_chain(certfile, keyfile, password)
 
     if settings['cafile'] is not None:
-        sslcontext.load_verify_locations(cafile=settings['cafile'])
+        try:
+            sslcontext.load_verify_locations(cafile=settings['cafile'])
+        except ssl.SSLError as e:
+            raise error.Abort(_('error loading CA file %s: %s') % (
+                              settings['cafile'], e.args[1]),
+                              hint=_('file is empty or malformed?'))
         caloaded = True
     elif settings['allowloaddefaultcerts']:
         # This is a no-op on old Python.
--- a/tests/test-https.t	Wed Jun 29 18:15:28 2016 -0700
+++ b/tests/test-https.t	Wed Jun 29 19:37:38 2016 -0700
@@ -62,9 +62,16 @@
 A malformed per-host certificate file will raise an error
 
   $ echo baddata > badca.pem
+#if sslcontext
+  $ hg --config hostsecurity.localhost:verifycertsfile=badca.pem clone https://localhost:$HGPORT/
+  abort: error loading CA file badca.pem: * (glob)
+  (file is empty or malformed?)
+  [255]
+#else
   $ hg --config hostsecurity.localhost:verifycertsfile=badca.pem clone https://localhost:$HGPORT/
   abort: error: * (glob)
   [255]
+#endif
 
 A per-host certificate mismatching the server will fail verification
 
@@ -183,10 +190,19 @@
 empty cacert file
 
   $ touch emptycafile
+
+#if sslcontext
+  $ hg --config web.cacerts=emptycafile -R copy-pull pull
+  pulling from https://localhost:$HGPORT/
+  abort: error loading CA file emptycafile: * (glob)
+  (file is empty or malformed?)
+  [255]
+#else
   $ hg --config web.cacerts=emptycafile -R copy-pull pull
   pulling from https://localhost:$HGPORT/
   abort: error: * (glob)
   [255]
+#endif
 
 cacert mismatch