[PATCH 1 of 8] tests: better testing of loaded certificates

Gregory Szorc gregory.szorc at gmail.com
Fri Jul 1 22:57:37 EDT 2016


# HG changeset patch
# User Gregory Szorc <gregory.szorc at gmail.com>
# Date 1467426454 25200
#      Fri Jul 01 19:27:34 2016 -0700
# Node ID 142d3941bd4374998b8f0e92c287b431863ca95c
# Parent  a0ff7329a28e5c73fe1af2abf28e2dc1b99cab24
tests: better testing of loaded certificates

Tests were failing on systems like RHEL 7 where loading the system
certificates results in CA certs being reported to Python. We add
a feature that detects when we're able to load *and detect* the
loading of system certificates. We update the tests to cover the
3 scenarios:

1) system CAs are loadable and detected
2) system CAs are loadable but not detected
3) system CAs aren't loadable

diff --git a/tests/hghave.py b/tests/hghave.py
--- a/tests/hghave.py
+++ b/tests/hghave.py
@@ -413,16 +413,35 @@ def has_sslcontext():
     except (ImportError, AttributeError):
         return False
 
 @check("defaultcacerts", "can verify SSL certs by system's CA certs store")
 def has_defaultcacerts():
     from mercurial import sslutil
     return sslutil._defaultcacerts() or sslutil._canloaddefaultcerts
 
+ at check("defaultcacertsloaded", "detected presence of loaded system CA certs")
+def has_defaultcacertsloaded():
+    import ssl
+    from mercurial import sslutil
+
+    if not has_defaultcacerts():
+        return False
+    if not has_sslcontext():
+        return False
+
+    cafile = sslutil._defaultcacerts()
+    ctx = ssl.create_default_context()
+    if cafile:
+        ctx.load_verify_locations(cafile=cafile)
+    else:
+        ctx.load_default_certs()
+
+    return len(ctx.get_ca_certs()) > 0
+
 @check("windows", "Windows")
 def has_windows():
     return os.name == 'nt'
 
 @check("system-sh", "system() uses sh")
 def has_system_sh():
     return os.name != 'nt'
 
diff --git a/tests/test-https.t b/tests/test-https.t
--- a/tests/test-https.t
+++ b/tests/test-https.t
@@ -42,22 +42,36 @@ Test server address cannot be reused
   abort: cannot start server at ':$HGPORT': Address already in use
   [255]
 #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
+#if sslcontext defaultcacerts no-defaultcacertsloaded
   $ 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
+#endif
+
+#if no-sslcontext defaultcacerts
+  $ hg clone https://localhost:$HGPORT/ copy-pull
+  abort: error: *certificate verify failed* (glob)
+  [255]
+#endif
+
+#if defaultcacertsloaded
+  $ hg clone https://localhost:$HGPORT/ copy-pull
+  abort: error: *certificate verify failed* (glob)
+  [255]
+#endif
+
+#if no-defaultcacerts
   $ 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
 
 Specifying a per-host certificate file that doesn't exist will abort
 
diff --git a/tests/test-patchbomb-tls.t b/tests/test-patchbomb-tls.t
--- a/tests/test-patchbomb-tls.t
+++ b/tests/test-patchbomb-tls.t
@@ -38,26 +38,55 @@ Utility functions:
   $ DISABLECACERTS=
   $ try () {
   >   hg email $DISABLECACERTS -f quux -t foo -c bar -r tip "$@"
   > }
 
 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
+#if sslcontext defaultcacerts no-defaultcacertsloaded
   $ try
   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
 
+#if no-sslcontext defaultcacerts
+  $ try
+  this patch series consists of 1 patches.
+  
+  
+  (?i)abort: .*?certificate.verify.failed.* (re)
+  [255]
+#endif
+
+#if defaultcacertsloaded
+  $ try
+  this patch series consists of 1 patches.
+  
+  
+  (?i)abort: .*?certificate.verify.failed.* (re)
+  [255]
+
+#endif
+
+#if no-defaultcacerts
+  $ try
+  this patch series consists of 1 patches.
+  
+  
+  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
+
   $ DISABLECACERTS="--config devel.disableloaddefaultcerts=true"
 
 Without certificates:
 
   $ try --debug
   this patch series consists of 1 patches.
   
   


More information about the Mercurial-devel mailing list