View Ticket
Ticket Hash: 727af73f467a64be0d0bbbcf46c513062a9e4704
Title: ssl: on "pull -R repo", gets ssl certificate again, asks to accept a/y/N
Status: Open Type: Code_Defect
Severity: Important Priority:
Subsystem: Resolution: Open
Last Modified: 2011-06-20 07:12:46
Version Found In: [95ae79d5044a4401368e5633893dfb2044c8565f]
When cloning the fossil repo using https, I am asked if I want to accept the certificate. I said "always".

Now, when doing "fossil pull -R fossil.ssl", it gives me:

me ~/src/fossil$ fossil pull -R fossil2
                Bytes      Cards  Artifacts     Deltas
Send:             130          1          0          0

Unknown SSL certificate:

  countryName               = US
  stateOrProvinceName       = North Carolina
  localityName              = Charlotte     
  organizationName          =    

Issued By:

  countryName               = US
  stateOrProvinceName       = North Carolina
  localityName              = Charlotte     
  organizationName          =    

Accept certificate [a=always/y/N]? a
REPLACE INTO global_config(name,value) VALUES(''
... etc

NOTE: If I do the normal "fossil open" in a directory, then "fossil pull", it works just fine.

anonymous added on 2010-05-21 09:03:45:
Yes, there is some problem with accepting certificates.

For me fossil always complains that the certificate is for a different site although I chose to always accept the certificate.

anonymous claiming to be wfreeman added on 2010-09-02 22:28:45:
I also have the same issue, with it always prompting even though I hit "a". During commits, updates, and syncs.

anonymous claiming to be wfreeman added on 2010-09-03 00:59:01:
I dug a little deeper and put some debug printing into the code.

It's actually returning a: X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY

Perhaps this only happens when the server cert is not self-signed. I'm running https with a GeoTrust issued cert.

I think we may need to use SSL_get_peer_cert_chain and go through the list of certs in order to get an OK return code. I'm not really sure how to do this, but I may come back and look at it later.

As a temporary kludge to remove the annoyance, I think I will just comment out the prompt code, as it's not really necessary unless you are worried about someone spoofing your cert, which, if you're just hitting "a" every time, doesn't really matter anyway.

anonymous added on 2010-11-08 10:20:59:
Fossil first checks if ht e cert is valid and if it is not it does not take saved cert into account.

If you accept a cert which fossil thinks is invalid (which would be the reason to accept it manually in the first place) it does not look at it when validating the cert next time.

jan added on 2011-03-29 12:47:24 UTC:
Since I'm anyways working with the PKI stuff, I thought I'd search for some related tickets, and I found this one.

As wfreeman pointed out, SSL is returning X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY which means exactly what it says.

Slightly simplified: In a PKI trust model environment you have a central authority which you trust to sign certificate sign requests for client and server certificates. The problem here is that even if the server side can verify the authenticity of the relevant certificates, OpenSSL is paranoid enough (read: has the common sense) to want to validate the certificates against the CA certificate on the client side as well. But since fossil currently doesn't actually load the CA certificate into the SSL context, thus not making them accessible for the verification procedure, it won't succeed. The error says exactly that: "I found an issuer in a (server) certificate, but I can not locate the issuer's certificate (CA) on this local system (for verifying the authenticity of the server certificate)".

Though note that it's up to the application to choose whether to care about verification problems or not, SSL doesn't care other than flagging the problem, so fossil isn't technically doing anything wrong by simply marching on like nothing happened.

There are two obvious solutions to this ticket:

  1. Configuring verify mode or verify depth to 0 (it won't care about verifying against the CA). See SSL_CTX_set_verify(3) for more information.
  2. Add support for adding the CA certificate(s) to the SSL context on the client side.

As a direct result of my work on supporting client certificates, I'm working on point 2.

For those who are interested (and only have a single-level CA), there's a one-line patch for point 2 if you don't mind a hard-coded temporary solution. Somewhere early (like after the call to ssl_global_init() in ssl_open()), add:

SSL_CTX_load_verify_locations(sslCtx, "/etc/ssl/public/ca.crt", NULL);

Adjust the cafile path, and make sure it's in the PEM format.

anonymous claiming to be Earl added on 2011-06-19 19:05:55 UTC:
Another quick fix:

As an alternative to hard coding the certificate location, I added the following to ssl_global_init() in http_ssl.c

char *cert_file;
cert_file = mprintf("%s.pem", g.zRepositoryName);
SSL_CTX_load_verify_locations(sslCtx, cert_file, NULL);

This makes OpenSSL look for a certificate file in the same directory as the fossil, named the same as the repository but with .pem added on. For example, when syncing myrepo.fossil, OpenSSL will use myrepo.fossil.pem if it exists. If not, the default locations (e.g. /usr/local/ssl/certs or even C:\usr\local\ssl\certs) are used. This makes it possible to have different certificates for different repositories.

The method works with clone as well as operations on established repositories. Of course, the .pem file should be present before you issue the clone command.

PEM files can contain more than one certificate, up to the trusted root CA. This is not the case for files in directories like /usr/local/ssl/certs, which can only have one certificate per file and need to be named using the openSSL c_rehash utility.

Thank you for developing Fossil. Looking forward to further SSL features.

ben added on 2011-06-20 07:12:46 UTC:
The ben-testing branch (which includes a competing implementation of SSL client and server certificate management) has an extra ssl-ca-location setting. This calls SSL_CTX_load_verify_locations().

I'm not entirely convinced that fossil should be doing any certificate management. At least, not the way it's doing it now. Perhaps storing the fingerprint of the certificate, rather than the certificate itself, might be the way to go.