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.
--- 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