Comments
Patch
@@ -279,17 +279,32 @@ def wrapsocket(sock, keyfile, certfile,
caloaded = True
elif settings['allowloaddefaultcerts']:
# This is a no-op on old Python.
sslcontext.load_default_certs()
caloaded = True
else:
caloaded = False
- sslsocket = sslcontext.wrap_socket(sock, server_hostname=serverhostname)
+ try:
+ sslsocket = sslcontext.wrap_socket(sock, server_hostname=serverhostname)
+ except ssl.SSLError:
+ # If we're doing certificate verification and no CA certs are loaded,
+ # that is almost certainly the reason why verification failed. Provide
+ # a hint to the user.
+ # Only modern ssl module exposes SSLContext.get_ca_certs() so we can
+ # only show this warning if modern ssl is available.
+ if (caloaded and settings['verifymode'] == ssl.CERT_REQUIRED and
+ modernssl and not sslcontext.get_ca_certs()):
+ ui.warn(_('(an attempt was made to load CA certificates but none '
+ 'were loaded; see '
+ 'https://mercurial-scm.org/wiki/SecureConnections for '
+ 'how to configure Mercurial to avoid this error)\n'))
+ raise
+
# check if wrap_socket failed silently because socket had been
# closed
# - see http://bugs.python.org/issue13721
if not sslsocket.cipher():
raise error.Abort(_('ssl connection failed'))
sslsocket._hgstate = {
'caloaded': caloaded,
@@ -44,16 +44,17 @@ Test server address cannot be reused
#endif
$ cd ..
Our test cert is not signed by a trusted CA. It should fail to verify if
we are able to load CA certs.
#if defaultcacerts
$ hg clone https://localhost:$HGPORT/ copy-pull
+ (an attempt was made to load CA certificates but none were loaded; see https://mercurial-scm.org/wiki/SecureConnections for how to configure Mercurial to avoid this error)
abort: error: *certificate verify failed* (glob)
[255]
#else
$ hg clone https://localhost:$HGPORT/ copy-pull
abort: localhost certificate error: no certificate received
(set hostsecurity.localhost:certfingerprints=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 config setting or use --insecure to connect insecurely)
[255]
#endif
@@ -75,19 +76,27 @@ A malformed per-host certificate file wi
#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
+(modern ssl is able to discern whether the loaded cert is a CA cert)
+#if sslcontext
+ $ hg --config hostsecurity.localhost:verifycertsfile="$CERTSDIR/client-cert.pem" clone https://localhost:$HGPORT/
+ (an attempt was made to load CA certificates but none were loaded; see https://mercurial-scm.org/wiki/SecureConnections for how to configure Mercurial to avoid this error)
+ abort: error: *certificate verify failed* (glob)
+ [255]
+#else
$ hg --config hostsecurity.localhost:verifycertsfile="$CERTSDIR/client-cert.pem" clone https://localhost:$HGPORT/
abort: error: *certificate verify failed* (glob)
[255]
+#endif
A per-host certificate matching the server's cert will be accepted
$ hg --config hostsecurity.localhost:verifycertsfile="$CERTSDIR/pub.pem" clone -U https://localhost:$HGPORT/ perhostgood1
requesting all changes
adding changesets
adding manifests
adding file changes