After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 780160 - Fails to connect to Google, with legacy CAs disabled, or with ca-certificates version 2.10
Fails to connect to Google, with legacy CAs disabled, or with ca-certificates...
Status: RESOLVED FIXED
Product: empathy
Classification: Core
Component: Auth client
3.12.x
Other All
: Normal normal
: ---
Assigned To: empathy-maint
empathy-maint
Depends on: 753260
Blocks:
 
 
Reported: 2017-03-16 18:33 UTC by Debarshi Ray
Modified: 2017-03-21 15:38 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
tls-verifier: Handle GNUTLS_CERT_REVOKED (1.03 KB, patch)
2017-03-16 19:53 UTC, Debarshi Ray
committed Details | Review
tls-verifier: Use GIO to verify the chain of TLS certificates (20.00 KB, patch)
2017-03-16 19:53 UTC, Debarshi Ray
none Details | Review
Remove the GnuTLS dependency (4.49 KB, patch)
2017-03-16 19:54 UTC, Debarshi Ray
none Details | Review
tls-verifier: Use GIO to verify the chain of TLS certificates (22.83 KB, patch)
2017-03-20 14:45 UTC, Debarshi Ray
none Details | Review
Remove the GnuTLS dependency (4.49 KB, patch)
2017-03-20 14:45 UTC, Debarshi Ray
none Details | Review
tests: Fix comment (1.20 KB, patch)
2017-03-20 19:50 UTC, Debarshi Ray
committed Details | Review
tests: Actually test that hostnames of pinned certificates are verified (1.34 KB, patch)
2017-03-20 19:50 UTC, Debarshi Ray
committed Details | Review
tests: Retain the PEM formatted root certificate (4.65 KB, patch)
2017-03-20 19:50 UTC, Debarshi Ray
committed Details | Review
tls-verifier: Use GIO to verify the chain of TLS certificates (25.67 KB, patch)
2017-03-20 19:50 UTC, Debarshi Ray
none Details | Review
Remove the GnuTLS dependency (4.49 KB, patch)
2017-03-20 19:51 UTC, Debarshi Ray
committed Details | Review
tls-verifier: Use GIO to verify the chain of TLS certificates (25.66 KB, patch)
2017-03-21 14:50 UTC, Debarshi Ray
committed Details | Review

Description Debarshi Ray 2017-03-16 18:33:08 UTC
empathy-auth-client uses and gcr_certificate_chain_build_async [1], and its own home grown logic (that eventually calls GnuTLS) to validate TLS certificate chains. Both the Gcr API and Empathy haven't kept up with the times and gets it wrong when certain legacy CAs are disabled. See this Fedora bug for further details:
https://bugzilla.redhat.com/show_bug.cgi?id=1381671

Even if they did keep up, it is always better not to have multiple copies of security sensitive code.

These days glib-networking (bug 753260, since 2.48) defers all this to GnuTLS which does the right thing. Hence, we should stop using gcr_certificate_chain_build, and migrate to g_tls_database_verify_chain.

Note that empathy has some copy/pasted GnuTLS code to get the hostname out of the certificate (empathy_get_x509_certificate_hostname) for which there isn't any counterpart in GTlsCertificate. I suggest we drop this and wait for the corresponding accessor to be added to GTlsCertificate. The benefit of not relying on a specific encryption library outweighs the slight loss of verbosity in the error dialog.

[1] https://developer.gnome.org/gcr/unstable/GcrCertificateChain.html#gcr-certificate-chain-build-async
[2] https://developer.gnome.org/gio/stable/GTlsDatabase.html#g-tls-database-verify-chain
Comment 1 Debarshi Ray 2017-03-16 19:53:42 UTC
Created attachment 348117 [details] [review]
tls-verifier: Handle GNUTLS_CERT_REVOKED
Comment 2 Debarshi Ray 2017-03-16 19:53:57 UTC
Created attachment 348118 [details] [review]
tls-verifier: Use GIO to verify the chain of TLS certificates
Comment 3 Debarshi Ray 2017-03-16 19:54:10 UTC
Created attachment 348119 [details] [review]
Remove the GnuTLS dependency
Comment 4 Simon McVittie 2017-03-16 20:29:21 UTC
Review of attachment 348117 [details] [review]:

Seems right
Comment 5 Simon McVittie 2017-03-16 20:43:27 UTC
Review of attachment 348118 [details] [review]:

::: libempathy/empathy-tls-verifier.c
@@ +205,3 @@
+
+  /* error is set only when there is an actual failure. It won't be
+   * set, if it successfully determined that the ceritificate was not

nitpick: "certificate"

@@ +223,3 @@
+    {
+      data = g_ptr_array_index (cert_data, idx);
+      cert = g_initable_new (tls_certificate_type,

Is there really no convenience API for constructing the certificates?

@@ +252,3 @@
+
+  tls_database = g_tls_backend_get_default_database (tls_backend);
+  identity = g_network_address_new (priv->hostname, 0);

Only having one identity here could be bad. The old code supported multiple reference identities, and I dimly remember that actually mattering for some XMPP servers (I think some of the big corporate/semi-proprietary ones would put hostname A in your JID but expected you to know that they were going to present a certificate for hostname B, and certainly if we had JID example@gmail.com but were explicitly connecting to talk.google.com we had to accept either).

It wouldn't surprise me if that had test coverage. Maybe that's what's failing?
Comment 6 Dan Winship 2017-03-16 21:16:28 UTC
(In reply to Debarshi Ray from comment #0)
> Note that empathy has some copy/pasted GnuTLS code to get the hostname out
> of the certificate (empathy_get_x509_certificate_hostname) for which there
> isn't any counterpart in GTlsCertificate. I suggest we drop this and wait
> for the corresponding accessor to be added to GTlsCertificate.

"Wait for it to be added" isn't a good plan. Either "drop this feature with the expectation that it isn't coming back" or else "file a glib bug with a patch adding the API we need". (Or at the very least, "file a glib bug *requesting* the API we need".)
Comment 7 Dan Winship 2017-03-16 21:29:49 UTC
(In reply to Simon McVittie from comment #5)
> +      cert = g_initable_new (tls_certificate_type,
> 
> Is there really no convenience API for constructing the certificates?

Not from an array of DER blobs. It's not an API you'd be likely to need, except when interfacing with a TLS-library-agnostic TLS-handshake-validation API.

> Only having one identity here could be bad. The old code supported multiple
> reference identities, and I dimly remember that actually mattering for some
> XMPP servers

You could deal with that by passing a NULL identity to g_tls_database_verify_chain_async() to verify everything except the identity, and then (assuming that passes), call g_tls_certificate_verify() (with a NULL trusted_ca) on each possible identity until you get one that works.
Comment 8 Debarshi Ray 2017-03-16 22:23:09 UTC
(In reply to Dan Winship from comment #6)
> (In reply to Debarshi Ray from comment #0)
> > Note that empathy has some copy/pasted GnuTLS code to get the hostname out
> > of the certificate (empathy_get_x509_certificate_hostname) for which there
> > isn't any counterpart in GTlsCertificate. I suggest we drop this and wait
> > for the corresponding accessor to be added to GTlsCertificate.
> 
> "Wait for it to be added" isn't a good plan. Either "drop this feature with
> the expectation that it isn't coming back" or else "file a glib bug with a
> patch adding the API we need". (Or at the very least, "file a glib bug
> *requesting* the API we need".)

We'll have to "wait" in the sense that this patch set can't require anything higher than glib-2.50 or GNOME 3.22 because I need it at least in Fedora 25. The glib API addition would be glib-2.54 or GNOME 3.26 material.

But, yes, I'll file a request for the API. Although, I was hoping to take a look at any other remaining gcr_certificate_chain_build users to see what else they might be needing to have a fuller picture before asking for anything.
Comment 9 Debarshi Ray 2017-03-16 22:26:59 UTC
(In reply to Dan Winship from comment #7)
> (In reply to Simon McVittie from comment #5)
> > +      cert = g_initable_new (tls_certificate_type,
> > 
> > Is there really no convenience API for constructing the certificates?
> 
> Not from an array of DER blobs. It's not an API you'd be likely to need,
> except when interfacing with a TLS-library-agnostic TLS-handshake-validation
> API.

Umm... wouldn't it be useful for other instances of code that was using GcrSimpleCertificate and gcr_certificate_chain_build and now wants to port to GIO? I guess we will have to actually dig up those instances and see.

> > Only having one identity here could be bad. The old code supported multiple
> > reference identities, and I dimly remember that actually mattering for some
> > XMPP servers
> 
> You could deal with that by passing a NULL identity to
> g_tls_database_verify_chain_async() to verify everything except the
> identity, and then (assuming that passes), call g_tls_certificate_verify()
> (with a NULL trusted_ca) on each possible identity until you get one that
> works.

Ok. I was thinking that I'd have to chain together multiple g_tls_database_verify_chain_async calls, one for each identity, but this is simpler. g_tls_certificate_verify appears to be sync-safe and hence more loop-friendly.
Comment 10 Dan Winship 2017-03-17 17:07:31 UTC
(In reply to Debarshi Ray from comment #9)
> > > Is there really no convenience API for constructing the certificates?
> > 
> > Not from an array of DER blobs. It's not an API you'd be likely to need,
> > except when interfacing with a TLS-library-agnostic TLS-handshake-validation
> > API.
> 
> Umm... wouldn't it be useful for other instances of code that was using
> GcrSimpleCertificate and gcr_certificate_chain_build and now wants to port
> to GIO? I guess we will have to actually dig up those instances and see.

Are there any? And it's people who want to port *only* their certificate validation code to gio, but *not* their network I/O code. GLib assumes you're only going to be using its TLS certificate validation API if you're also using its TLS connection API, which seems reasonably reasonable. If it turns out there are lots of people who have good reason to want to use one but not the other then more APIs can be added, but I'm guessing that won't be the case.

> Ok. I was thinking that I'd have to chain together multiple
> g_tls_database_verify_chain_async calls, one for each identity, but this is
> simpler. g_tls_certificate_verify appears to be sync-safe and hence more
> loop-friendly.

Yes, g_tls_database_verify_chain() is blocking-or-async because it might have to do I/O to a smart card. g_tls_certificate_verify() only looks at the certs you explicitly give it, so there are no worries.
Comment 11 Debarshi Ray 2017-03-20 14:44:24 UTC
Comment on attachment 348117 [details] [review]
tls-verifier: Handle GNUTLS_CERT_REVOKED

Pushed to master and gnome-3-12.
Comment 12 Debarshi Ray 2017-03-20 14:45:15 UTC
Created attachment 348321 [details] [review]
tls-verifier: Use GIO to verify the chain of TLS certificates
Comment 13 Debarshi Ray 2017-03-20 14:45:30 UTC
Created attachment 348322 [details] [review]
Remove the GnuTLS dependency
Comment 14 Kai Engert 2017-03-20 19:35:07 UTC
I have tested the combination of the three attached patches, on top of empathy 3.12.13

It appears to work correctly.

Connecting to google talk works, when the legacy CAs are removed.

I've performed a couple of additional tests, using a local XMPP server:

- valid certificate, but hostname mismatch:
      fails as expected

- valid certificate with missing intermediate CA:
      fails as expected

- self-signed server certificate:
      fails as expected

- both self-signed server certificate and hostname mismatch:
      fails as expected

Given that I was unable to connect to google talk without these patch, I conclude that these patches improve the certificate verification as requested, but common certificate errors are still correctly identified.
Comment 15 Debarshi Ray 2017-03-20 19:45:29 UTC
(In reply to Kai Engert from comment #14)
> I have tested the combination of the three attached patches, on top of
> empathy 3.12.13
> 
> It appears to work correctly.

Thanks for the extensive tests, Kai!
Comment 16 Debarshi Ray 2017-03-20 19:48:12 UTC
I just realized that unlike Gcr [1], GnuTLS doesn't seem to provide a way to load a PKCS#11 module that's built into the code, as opposed to being a shared object. This makes it hard for us to load our mock PKCS#11 module. I guess it won't hurt that much to disable the test case that relies on using PKCS#11 storage to complete the certificate chain. All that work should be happening inside GnuTLS anyway.

[1] https://developer.gnome.org/gck/unstable/GckModule.html
Comment 17 Debarshi Ray 2017-03-20 19:50:09 UTC
Created attachment 348350 [details] [review]
tests: Fix comment
Comment 18 Debarshi Ray 2017-03-20 19:50:25 UTC
Created attachment 348351 [details] [review]
tests: Actually test that hostnames of pinned certificates are verified
Comment 19 Debarshi Ray 2017-03-20 19:50:37 UTC
Created attachment 348352 [details] [review]
tests: Retain the PEM formatted root certificate
Comment 20 Debarshi Ray 2017-03-20 19:50:51 UTC
Created attachment 348353 [details] [review]
tls-verifier: Use GIO to verify the chain of TLS certificates
Comment 21 Debarshi Ray 2017-03-20 19:51:04 UTC
Created attachment 348354 [details] [review]
Remove the GnuTLS dependency
Comment 22 Debarshi Ray 2017-03-21 14:38:01 UTC
I pushed the test suite fixes to master and gnome-3-12.
Comment 23 Debarshi Ray 2017-03-21 14:50:33 UTC
Created attachment 348417 [details] [review]
tls-verifier: Use GIO to verify the chain of TLS certificates

Rebased against master.
Comment 24 Debarshi Ray 2017-03-21 15:35:16 UTC
I pushed the actual port GIO port only to master because it bumps the GLib requirement quite significantly. Downstreams wishing to backport should be able to do so pretty easily.
Comment 25 Debarshi Ray 2017-03-21 15:38:43 UTC
Dan, Simon and Kai: thanks for all the help on this so far! Let me know if something is wrong.