diff --git a/mercurial/sslutil.py b/mercurial/sslutil.py index afbe1fe4c44e76572ca5dec8a3921ab6b053c570_bWVyY3VyaWFsL3NzbHV0aWwucHk=..5b71a8d7f7ffc2662ceb58ad8eec806e147ae13d_bWVyY3VyaWFsL3NzbHV0aWwucHk= 100644 --- a/mercurial/sslutil.py +++ b/mercurial/sslutil.py @@ -284,7 +284,22 @@ 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 diff --git a/tests/test-https.t b/tests/test-https.t index afbe1fe4c44e76572ca5dec8a3921ab6b053c570_dGVzdHMvdGVzdC1odHRwcy50..5b71a8d7f7ffc2662ceb58ad8eec806e147ae13d_dGVzdHMvdGVzdC1odHRwcy50 100644 --- a/tests/test-https.t +++ b/tests/test-https.t @@ -49,6 +49,7 @@ #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 @@ -80,6 +81,13 @@ 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] @@ -83,6 +91,7 @@ $ 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 diff --git a/tests/test-patchbomb-tls.t b/tests/test-patchbomb-tls.t index afbe1fe4c44e76572ca5dec8a3921ab6b053c570_dGVzdHMvdGVzdC1wYXRjaGJvbWItdGxzLnQ=..5b71a8d7f7ffc2662ceb58ad8eec806e147ae13d_dGVzdHMvdGVzdC1wYXRjaGJvbWItdGxzLnQ= 100644 --- a/tests/test-patchbomb-tls.t +++ b/tests/test-patchbomb-tls.t @@ -48,6 +48,7 @@ this patch series consists of 1 patches. + (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) (?i)abort: .*?certificate.verify.failed.* (re) [255] #endif