Bug 447572 - Configuration - Download (any) -> SSL handshake failed
Summary: Configuration - Download (any) -> SSL handshake failed
Status: RESOLVED FIXED
Alias: None
Product: gcompris
Classification: Applications
Component: general (show other bugs)
Version: unspecified
Platform: Android Android 7.x
: NOR normal
Target Milestone: ---
Assignee: Jazeix Johnny
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-12-27 13:09 UTC by Stefaan
Modified: 2023-01-01 19:19 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments
adb logcat output (151.80 KB, text/plain)
2021-12-28 09:20 UTC, Stefaan
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Stefaan 2021-12-27 13:09:04 UTC
Running GCompris 2.0
on an Android 7.0 (Galaxy Tab S2)

When going to "Configuration" - "Download (e.g. Localized voices, background music, ...)"
each time results in 
   Download error (code: 6): SSL handshake failed

As such, I haven't been able to get voices or background music to play. 

(Similar downloads from my Debian Bookworm's GCompris seem to function correctly)

Contacting https://gcompris.net from my Android system browser works correctly. Could it be that the Qt-libs behind GCompris are using an alternative way to verify the SSL certificates, and then fail?

Did some reading on letsencrypt, which https://gcompris.net seems to be using. Some breakage was feared/announced, but later fixed (https://letsencrypt.org/2020/12/21/extending-android-compatibility.html), using a combination of cross-signing and the fact that Android doesn't enforce expiration on certificates used as trust anchors. Could this be related?
Comment 1 Jazeix Johnny 2021-12-27 15:13:43 UTC
Hi,
thank you for reporting the issue. Unfortunately, we cannot reproduce it on our devices, so I think it is more related to your device than the website ssl.
Would it be possible for you to provide us the logcat traces of GCompris using adb tool so we can see if there are more info on it?

A quick guide:
* install sdk platform tools from https://developer.android.com/studio/releases/platform-tools
* on the tablet, unlock the developer mode and enable USB debugging: https://www.howtogeek.com/129728/how-to-access-the-developer-options-menu-and-enable-usb-debugging-on-android-4.2/
* plug your tablet on the computer via USB and accept the connection.
* Open a terminal/console, go to the sdk platform tools folder and run: "adb logcat"

Can you also try to install the package from https://f-droid.org/en/packages/net.gcompris.full/ (https://f-droid.org/repo/net.gcompris.full_20000.apk) to see if the issue is also present?
Comment 2 animtim 2021-12-27 17:17:19 UTC
Also for info: nowadays the assets in the application are not downloaded from gcompris.net but from https://cdn.kde.org/gcompris
Comment 3 Stefaan 2021-12-28 09:20:28 UTC
Created attachment 144902 [details]
adb logcat output

Hi,

as for "adb logcat", the only related output I see is:

12-28 07:34:00.092 28160 28206 D GCompris: "SSL handshake failed"   QNetworkReply::SslHandshakeFailedError
12-28 07:34:00.093 28160 28206 W GCompris: Error downloading Contents from QUrl("https://cdn.kde.org/gcompris/data2/voices-ogg/Contents") : QNetworkReply::SslHandshakeFailedError : "SSL handshake failed"

I can confirm that opening that same URL in any browser on that tablet just works (tested Chromium / Firefox / Duckduckgo / and the system browser "Samsung Internet") - though at least Firefox is not relevant as I've read uses its own SSL certificate store. 

I also tested removing the app, and installing it from the F-Droid link you provided, however the behavior remains exactly the same. 
I went back to version 1.0, and 0.97 (through https://gcompris.net/download/qt/android/), same result. 

I also found this text on your download site: "WARNING: For Android version 4.4.2, it is recommended to directly download and install manually GCompris version 0.95 from our website, as the version 0.96 from the Play Store will not be able to download external assets with this Android version."
I installed 0.95 as suggested there for Android 4.4.2 (even though I have Android 7.0), and that seems to be able to download assets!
But of course I'd rather run the more recent version. 

So I'm hoping that the observation that 0.95 is able to download stuff, might provide a hint as to what is going on?
Thanks
Comment 4 animtim 2021-12-28 09:28:38 UTC
Thanks for the adb log.

About the 0.95 version, it was the last one using plain http to download assets from gcompris.net, as we switched to cdn.kde.org which requires  https after that.

Also, we are using OpenSSL for the https support, which is different from android's internal https support, but as far as I know it's the only solution supported directly by Qt. So it seems that the certificates included in this android version are no longer working correctly for OpenSSL... I'm not sure which options we have to fix this at our level.
Comment 5 Jazeix Johnny 2021-12-28 09:42:56 UTC
Hi,
thank you.
Maybe we could try to implement a version without checking the certificate: https://stackoverflow.com/questions/21636728/qt-ssl-handshake-failed?rq=1
But it would need an option, with a confirmation box. I can probably take a look during the week.
Comment 6 Stefaan 2021-12-28 10:36:14 UTC
I'm referring back to the LetsEncrypt certificate issue for "Android operating systems prior to 7.1.1", as discussed in https://letsencrypt.org/2020/12/21/extending-android-compatibility.html

If GCompris is using OpenSSL instead of android's internal https support, could it be that the workaround
  "This solution works because Android intentionally does not enforce the expiration dates of certificates used as trust anchors. " (as mentioned on that page)
they're using to enable "ISRG Root X1" on pre-7.1.1 devices, doesn't kick in for GCompris?
The workaround seems to rely on "DST Root CA X3" not being treated as expired by Android, even though in reality, it has expired (https://letsencrypt.org/docs/dst-root-ca-x3-expiration-september-2021/). 

Using Chrome's certificate viewer on cdn.kde.org, I can indeed confirm that "DST Root CA X3" is being used to trust "ISRG Root X1", then "R3" and then the site's "1088045785.rsc.cdn77.org"

So, I've taken the liberty of theorizing further:
- the basic problem is that pre-7.1.1 devices don't know about the "ISRG Root X1" certificate and hence don't trust it. 
- the workaround that works on the Android system, doesn't kick in for GCompris, because it manages its certificate validation independently, but probably still uses the root certificates as shipped with the Android system
- if GCompris would ship the "ISRG Root X1" certificate (as application data), and enable it, that could solve the problem, and would not harm security in any way
- GCompris could do this by (pseudo-code):
  {
    auto sslConfig = QSslConfiguration::defaultConfiguration();
    sslConfig.addCaCertificate(QSslCertificate(QFile("path to ISRG Root X1 certificate file (in pem format)"));
    QSslConfiguration::setDefaultConfiguration(sslConfig);
  }
- and subsequent calls to QNetworkAccessManager::get(...) (as on line 229 in DownloadManager.cpp) would then use the augmented ssl configuration?

Does my theory/analysis make sense?
Comment 7 Jazeix Johnny 2021-12-28 11:08:00 UTC
I'm doing an apk soon, and we'll see if it works :)
Comment 8 Jazeix Johnny 2021-12-28 12:20:18 UTC
Can you please test https://gcompris.net/download/qt/android/debug/GCompris-2.0-addedSslCert.apk ?
The corresponding commit/code is https://invent.kde.org/education/gcompris/-/commit/ec5c0b36950d83d08c5cb3dfb42858cee2702cff

I couldn't use the addCertificate method directly because it has been added in Qt 5.15 and we use Qt5.12 to compile android package (we are not yet compatible with Qt5.14+).
I also added the display of the openSSL version in the GCompris help panel to be sure it uses the one we provide.

There are debug logs to display the list of the certificates (and an error log in case the rootX1 file cannot be loaded).

I downloaded the certificate from https://letsencrypt.org/certificates/ (https://letsencrypt.org/certs/isrgrootx1.pem)
Comment 9 Stefaan 2021-12-28 13:21:03 UTC
Waw, thanks Johnny. I installed the apk you provided, and it works like a charm!!
And the code looks clean too ;)
I appreciate the incredibly quick action on this!
Comment 10 Jazeix Johnny 2021-12-28 17:21:43 UTC
Git commit f0ce2b9b996f02f16ba9d694fbdd6e3097cf9263 by Johnny Jazeix.
Committed on 28/12/2021 at 17:21.
Pushed by jjazeix into branch 'master'.

android, ship certificate for older android and load it at runtime to avoid SSL handshake failed.
For now, only apply it for android as it is the only platform where we had reports.

M  +1    -1    src/core/CMakeLists.txt
M  +18   -0    src/core/DownloadManager.cpp
A  +31   -0    src/core/resource/isrgrootx1.pem

https://invent.kde.org/education/gcompris/commit/f0ce2b9b996f02f16ba9d694fbdd6e3097cf9263
Comment 11 Jazeix Johnny 2021-12-28 17:22:35 UTC
Git commit 09771b9e15aa0791ad02e8cc18b077e1c622cfdd by Johnny Jazeix.
Committed on 28/12/2021 at 17:22.
Pushed by jjazeix into branch 'KDE/2.0'.

android, ship certificate for older android and load it at runtime to avoid SSL handshake failed.
For now, only apply it for android as it is the only platform where we had reports.

M  +1    -1    src/core/CMakeLists.txt
M  +18   -0    src/core/DownloadManager.cpp
A  +31   -0    src/core/resource/isrgrootx1.pem

https://invent.kde.org/education/gcompris/commit/09771b9e15aa0791ad02e8cc18b077e1c622cfdd
Comment 12 Jazeix Johnny 2021-12-28 17:24:59 UTC
(In reply to Stefaan from comment #9)
> Waw, thanks Johnny. I installed the apk you provided, and it works like a
> charm!!
> And the code looks clean too ;)
> I appreciate the incredibly quick action on this!

Well, you did all the search and provided the fix, thank you :)
Comment 13 Alex 2023-01-01 16:44:30 UTC
(In reply to Jazeix Johnny from comment #12)
> (In reply to Stefaan from comment #9)
> > Waw, thanks Johnny. I installed the apk you provided, and it works like a
> > charm!!
> > And the code looks clean too ;)
> > I appreciate the incredibly quick action on this!
> 
> Well, you did all the search and provided the fix, thank you :)

Hi all, seems I have exactly the same problem, but with Linux > Antix and also Antix based MX Linux, both latest versions 32 bit which is e.g. for older laptops which I would like to have for my children. Any chance to fix it the same way?  Thanks a lot in advance :-)
Comment 14 animtim 2023-01-01 17:23:27 UTC
On Linux it is easy to workaround the issue by downloading manually the files and placing them in /home/username/.cache/KDE/gcompris-qt/data2/

You can download the files from https://cdn.kde.org/gcompris/data2/

To get the complete extra downloadable files, download the following :
- in the folder backgroundMusic, the files Contents and backgroundMusic-ogg.rcc, and place them in the folder /home/username/.cache/KDE/gcompris-qt/data2/backgroundMusic
- in the folder voices-ogg, the files Contents and the voices-xx.rcc for your language, and place them in the folder /home/username/.cache/KDE/gcompris-qt/data2/voices-ogg
- in the folder words, the files Contents and words-webp.rcc (or if you use an older version of GCompris, before 2.4, the file words.rcc), and place them in the folder /home/username/.cache/KDE/gcompris-qt/data2/words
Comment 15 Alex 2023-01-01 19:19:37 UTC
(In reply to animtim from comment #14)
> On Linux it is easy to workaround the issue by downloading manually the
> files and placing them in /home/username/.cache/KDE/gcompris-qt/data2/
> 
> You can download the files from https://cdn.kde.org/gcompris/data2/
> 
> To get the complete extra downloadable files, download the following :
> - in the folder backgroundMusic, the files Contents and
> backgroundMusic-ogg.rcc, and place them in the folder
> /home/username/.cache/KDE/gcompris-qt/data2/backgroundMusic
> - in the folder voices-ogg, the files Contents and the voices-xx.rcc for
> your language, and place them in the folder
> /home/username/.cache/KDE/gcompris-qt/data2/voices-ogg
> - in the folder words, the files Contents and words-webp.rcc (or if you use
> an older version of GCompris, before 2.4, the file words.rcc), and place
> them in the folder /home/username/.cache/KDE/gcompris-qt/data2/words

This workaround works, thanks a lot for guiding through the files and folders. I am very impressed by both, your very fast help and Gcompris itself 
:-)