self-signed certificates and SNI

Mads Kiilerich mads at kiilerich.com
Fri Jan 21 16:35:24 CST 2011


Jesus Cea wrote, On 01/21/2011 05:42 PM:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> I have my HG repository (hg.jcea.es) hosted in a HTTP server providing
> SSL with SNI. Since current python code doesn't support SNI, when
> connecting to my repository, mercurial gets the "default" certificate:
> www.jcea.es.
>
> Both certificates are self-signed.
>
> I have added both certificates to my web.cacert. But when doing a "hg
> pull", I get:
>
> jcea at ubuntu:~/Desktop/HG/documentacion$ hg pull -u
> abort: hg.jcea.es certificate error: certificate is for www.jcea.es
>
> So mercurial is both checking that the CA is correct, and the hostname.
>
> The error is actually sensible, but clearly unconvenient. Is there
> anything I can do?. Beside disabling the certificate checking (I do
> agree that this movement is a huge security improvement). Maybe some
> whitelisting/aliaslisting for next version?.
>
> The fact is that all my configuration is correct, but it is not possible
> to do a secure connection because the (correct) strict checking. I guess
> a lot of other people is having the same issue, with their "sane"
> configurations.

Yes, it seems like your configuration would be correct if Mercurial 
supported SNI. Unfortunately Python 2.x and Mercurial don't support SNI.

 From Mercurials point of view the certificate for hg.jcea.es is your 
www.jcea.es certificate. Couldn't you change that certificate so it also 
covered hg.jcea.es?

I agree that we could add a "when I connect to server X then it is ok if 
I get server Y instead" configuration option:

--- a/mercurial/url.py
+++ b/mercurial/url.py
@@ -538,6 +538,7 @@
                  self.sock = _ssl_wrap_socket(sock, self.key_file,
                          self.cert_file, cert_reqs=CERT_REQUIRED,
                          ca_certs=cacerts)
+                self.host = self.ui.config('certalias', self.host, 
self.host)
                  msg = _verifycert(self.sock.getpeercert(), self.host)
                  if msg:
                      raise util.Abort(_('%s certificate error: %s') %

(we shouldn't change self.host, but this shows the idea.)

BUT it would add complexity to something that already is complex and few 
understand. And if the primary use case is supporting configurations 
that uses features that we don't support then it might not be worth it.

/Mads



More information about the Mercurial mailing list