Author Topic: Missing information on "SSL certificate has been changed dialog"  (Read 5914 times)

aquaj

  • Newbie
  • *
  • Posts: 5
Hi,

this morning AquaMail welcomed me with a "SSL certificate has been changed" dialog. As I am familiar with the SSL certificate and PKI system I wasn't too surprised as certificates has to be changed from time to time.

However what surprised me was the content of the dialog: It only contains the data from the old and the new certificate and asks me if the certificate is trustworthy.

What was missing is the IMHO most important information: Is the new certificate valid/the certificate chain trusted?

No user can say if a certificate is trustworthy by just seeing the certificate data (subject, issuer, validity and hashes).
Therefore I would have expected that such a dialog contains the information if the certificate (and it's chain) has been correctly validated by AquaMail - please add this most important information to the dialog.

Kostya Vasilyev

  • Hero Member
  • *****
  • Posts: 12740
Re: Missing information on "SSL certificate has been changed dialog"
« Reply #1 on: October 27, 2016, 01:04:08 am »
But the app can't know this, this is the reason why it asks.

And I guess what people do is -- Google the hash value (I've provided both md5 and sha1 hash values) to see if there are other users, at different locations, are seeing same cert, or not. So this is a kind of -- informal -- trust network.
Creating debug logs for diagnostics: https://www.aqua-mail.com/troubleshooting/

The official FAQ: https://www.aqua-mail.com/faq/

Лог-файлы для диагностики: https://www.aqua-mail.com/ru/troubleshooting/

Вопросы и ответы: https://www.aqua-mail.com/ru/faq/

Kostya Vasilyev

  • Hero Member
  • *****
  • Posts: 12740
Re: Missing information on "SSL certificate has been changed dialog"
« Reply #2 on: October 27, 2016, 01:46:01 am »
But I see your point about showing whether a cert validates to trusted CA's.

I don't know of a way to do this though, and quick Googling only turned up this piece of code which apparently gets copied from blog post to blog post everywhere:

https://svn.apache.org/repos/asf/cxf/tags/cxf-2.4.1/distribution/src/main/release/samples/sts_issue_operation/src/main/java/demo/sts/provider/cert/CertificateVerifier.java

Since you'd mentioned that you have knowledge of SSL and PKI, do you also happen to know if that code is any good? Any other pointers perhaps?
Creating debug logs for diagnostics: https://www.aqua-mail.com/troubleshooting/

The official FAQ: https://www.aqua-mail.com/faq/

Лог-файлы для диагностики: https://www.aqua-mail.com/ru/troubleshooting/

Вопросы и ответы: https://www.aqua-mail.com/ru/faq/

aquaj

  • Newbie
  • *
  • Posts: 5
Re: Missing information on "SSL certificate has been changed dialog"
« Reply #3 on: October 27, 2016, 09:24:06 pm »
In general the code looks quite good, however it may get tricky to get the complete certificate chain. And I am not sure if you really have to add every trusted root certificate manually. However I have to admit that I don't have much experience on the CertPathBuilder class.

As SSL/TLS security can be very tricky and I wanted to be sure that AquaMail handles it the correct way I took the freedom to "dig a little bit deeper" into the code using Jadx - I hope you don't mind.

From my understanding the way how you receive the certificate already tells us a lot about the fact if it is valid or not. I have seen that there are two TrustManager implementations, the strict one and the "relaxed" (or dummy as I would call it) one.
I assume that for receiving a certificate you establish the SSL connection using the TrustManager configured for the active mail account (did not find the exact part where it is downloaded).
Therefore if you receive the certificate on an mail account that uses the strict TrustManager the Android OS verifies the certificate for you as part of the connection process.
Is this the way AquaMail works?

BTW: I stumbled over your SSL hardening code. Does this really work in real-life or do often users have problems with the cipher blacklisting. I am just asking because this is the first implementation I see that first establishes the connection and then checks if it is matching the hardening requirements. May be the server supports one of the allowed cipher suites but does not use it because the Android device (client) has sent the info in the SSL connection handshake phase that it is allowed...
If you are interested in that topic I could share my knowledge how to change the SSL handshake so that that the server nevers gets the infor that the Android device supports one of the disallowed ciphers.

Kostya Vasilyev

  • Hero Member
  • *****
  • Posts: 12740
Re: Missing information on "SSL certificate has been changed dialog"
« Reply #4 on: October 28, 2016, 08:18:30 pm »
aquaj:

The TrustManagers are not used for "SSL change detection" -- this is only for "CA validated vs. accept any". SSL "change detection" is done somewhere else, which is why you're not seeing it there.

As for SSL hardening, well, I use it myself :) and think I'm not alone. Yes it works really well IMO.

On Android 5.+, when SSL hardening is off, it re-enable certain ciphers that are not enabled by default in the platform's SSL implementation -- for compatibility (used to get a lot of "your app worked on my old phone and now doesn't connect to my mail server on the new phone").

Re: And I am not sure if you really have to add every trusted root certificate manually

That's the tricky part. Android's SSL stuff is often routed to OpenSSL down below, and so it "just magically works" (e.g. the default SSL socket factory will validate against CA's). But I don't know if it's possible to get the system CA's at all.

I'm a actually surprised that there is no standard Java class / method to validate a certificate against CA's -- like it already does for you when you use an SSL socket.
Creating debug logs for diagnostics: https://www.aqua-mail.com/troubleshooting/

The official FAQ: https://www.aqua-mail.com/faq/

Лог-файлы для диагностики: https://www.aqua-mail.com/ru/troubleshooting/

Вопросы и ответы: https://www.aqua-mail.com/ru/faq/

aquaj

  • Newbie
  • *
  • Posts: 5
Re: Missing information on "SSL certificate has been changed dialog"
« Reply #5 on: October 28, 2016, 08:37:44 pm »
I'm a actually surprised that there is no standard Java class / method to validate a certificate against CA's -- like it already does for you when you use an SSL socket.

I assume that for most users the implicit validation when opening a connection is sufficient. Anyway you can use the system default TrustManager (as log as you don't overwrite it) and use it via checkServerTrusted() method.


The TrustManagers are not used for "SSL change detection" -- this is only for "CA validated vs. accept any". SSL "change detection" is done somewhere else, which is why you're not seeing it there.

That does not sound secure. If the TrustManager is different this also means that the connection is different. This opens a TOCTOU (time-of-check time-of-use) vulnerability: An attacker could pass the first connection (SSL check) without modification/man-in-the-middle TLS decryption. Then when AquaMail performs the real connection it enables the man-in-the-middle TLS decryption.

Kostya Vasilyev

  • Hero Member
  • *****
  • Posts: 12740
Re: Missing information on "SSL certificate has been changed dialog"
« Reply #6 on: October 28, 2016, 09:13:16 pm »
Re: checkServerTrusted() method

Seen that.

Requires the key exchange algorithm, which I don't think I have access to... Unless it's this:

https://developer.android.com/reference/javax/net/ssl/SSLSession.html#getProtocol()

... but this could also be some generic name like "SSL" (meaning encrypted, not SSLv3 or whatever).

Re: That does not sound secure. If the TrustManager is different this also means that the connection is different [snip]

No it's not like that.

The app validates "the" actual connection (vs. connects, validates, disconnects, connects again thinking it's secure and maybe gets MITM'd -- not like this).

And if the cert changed, it aborts and displays the "SSL changed" error without logging in, so your password or auth tokens are safe.
Creating debug logs for diagnostics: https://www.aqua-mail.com/troubleshooting/

The official FAQ: https://www.aqua-mail.com/faq/

Лог-файлы для диагностики: https://www.aqua-mail.com/ru/troubleshooting/

Вопросы и ответы: https://www.aqua-mail.com/ru/faq/

Kostya Vasilyev

  • Hero Member
  • *****
  • Posts: 12740
Re: Missing information on "SSL certificate has been changed dialog"
« Reply #7 on: October 28, 2016, 09:25:14 pm »
Quote
Re: checkServerTrusted() method

Seen that.

Requires the key exchange algorithm, which I don't think I have access to... Unless it's this:

https://developer.android.com/reference/javax/net/ssl/SSLSession.html#getProtocol()

... but this could also be some generic name like "SSL" (meaning encrypted, not SSLv3 or whatever).

I'm an idiot. Of course it's things like "SSLv3" or "TLSv1.2".

But still, not the key exchange algorithm.
Creating debug logs for diagnostics: https://www.aqua-mail.com/troubleshooting/

The official FAQ: https://www.aqua-mail.com/faq/

Лог-файлы для диагностики: https://www.aqua-mail.com/ru/troubleshooting/

Вопросы и ответы: https://www.aqua-mail.com/ru/faq/

aquaj

  • Newbie
  • *
  • Posts: 5
Re: Missing information on "SSL certificate has been changed dialog"
« Reply #8 on: October 28, 2016, 09:33:51 pm »
But still, not the key exchange algorithm.
You mean the "authType" parameter?  I am not sure if it really has an effect. May it is there for being able to disallow certain combinations of certificates and authentication types.
I assume passing "UNKNOWN" should be fine.

See also the AOSP code of StandardNames.java: https://github.com/justinsb/android-libcore/blob/master/support/src/test/java/libcore/java/security/StandardNames.java [nofollow]

Code: [Select] [nofollow]
       /**
     * Valid values for X509TrustManager.checkServerTrusted authType,
     * either key exchange algorithm part of the cipher suite
     * or UNKNOWN.
     */
    public static final Set<String> SERVER_AUTH_TYPES = new HashSet<String>(Arrays.asList(
        "DHE_DSS",
        "DHE_DSS_EXPORT",
        "DHE_RSA",
        "DHE_RSA_EXPORT",
        "DH_DSS_EXPORT",
        "DH_RSA_EXPORT",
        "DH_anon",
        "DH_anon_EXPORT",
        "KRB5",
        "KRB5_EXPORT",
        "RSA",
        "RSA_EXPORT",
        "RSA_EXPORT1024",
        "ECDH_ECDSA",
        "ECDH_RSA",
        "ECDHE_ECDSA",
        "ECDHE_RSA",
        "UNKNOWN"));

Kostya Vasilyev

  • Hero Member
  • *****
  • Posts: 12740
Re: Missing information on "SSL certificate has been changed dialog"
« Reply #9 on: October 28, 2016, 11:07:23 pm »
Quote
You mean the "authType" parameter?  I am not sure if it really has an effect. May it is there for being able to disallow certain combinations of certificates and authentication types.
I assume passing "UNKNOWN" should be fine.

Yes, that. The docs say it cannot be null or empty. We'll see.
Creating debug logs for diagnostics: https://www.aqua-mail.com/troubleshooting/

The official FAQ: https://www.aqua-mail.com/faq/

Лог-файлы для диагностики: https://www.aqua-mail.com/ru/troubleshooting/

Вопросы и ответы: https://www.aqua-mail.com/ru/faq/

cpw

  • Newbie
  • *
  • Posts: 1
SSL certificate has been changed dialog
« Reply #10 on: November 01, 2016, 09:41:33 pm »
Hi, I really like Aquamail, it's by far the best of the email clients out there for Android. However, I'd just like to say that this prompt really has quite an annoying impact for me, and I suspect others as this CA becomes more popular.

I switched to using let's encrypt (google it) for my SSL certificates, and they expire every 3 months (and renew more frequently than that - about every 1-2 months). This means I have to renew the certificates by accepting this dialog for all my devices and the rest of my family's devices every month or two, which is quite irritating. Sadly, let's encrypt won't change this policy (it's quite understandable why they're doing it this way, if you read their FAQ), but it means the usability experience for anyone using let's encrypt with your email program really is quite annoying.

It'd be great if "strict" checking checked for validity vs either the system keychain or a keychain of my devising rather than showing everyone that "hey, let's encrypt autorefreshed, AGAIN". I really don't want to use "loose" checking, because why did I even bother with getting valid SSL certificates in the first place then?

What should matter for strict ssl is that the certificate hostname is valid, the certificate is in date, it's still signed by let's encrypt and it hasn't appeared on one of the revocation lists. It'd be great if your application followed this.
Thanks!

Edit: apologies for the accidental necro with this post to the wrong thread earlier :(

aquaj

  • Newbie
  • *
  • Posts: 5
Re: Missing information on "SSL certificate has been changed dialog"
« Reply #11 on: November 01, 2016, 09:52:51 pm »
For severs with let's encrypt certificates a "CA certificate pinning" feature would be of more use that a "server certificate pinning".
Google and OWASP both recommend it as the best method for implementing a certificate pinning mechanism.

@cpw: Have you enabled the SSL notification option in the general network settings? I thought the certificate changed dialog should not appear if it is disabled.

Kostya Vasilyev

  • Hero Member
  • *****
  • Posts: 12740
Re: Missing information on "SSL certificate has been changed dialog"
« Reply #12 on: November 01, 2016, 10:22:27 pm »
@cpw

Disabling "SSL cert checking" is *not* same as "Accept all".

Even with "SSL cert checking" *off*, the app will validate against CA roots, the usual way, but won't track *changes*.

And to both @cpw and @aquaj:

I've thought about cert pinning, but Google has a help page that specifically says "Do not do this, we can change our issuer cert".

As for a special case for LetsEncrypt --

Sorry this is not secure as any other special case would not be secure.

It would not prevent someone abusing LetsEncrypt to generate a "technically valid" cert for MITM.

Not supposed to happen, but there are not supposed to be any "validated yet malicious" SSL certs from "trustworthy" CA's, but these things happened too, haven't they?

And they're one of the reasons cert pinning even exists (if "isssued by trusted CA" really meant "always trustworthy" or putting it differently "the public CA architecture can be trusted and cannot be abused" -- then cert pinning won't be necessary).

---

To reiterate:

As long as you use "SSL (strict)" in *server* settings, the app will only accept CA-validated certs.

Only "SSL (accept all)" means "accept all even expired or self signed".

The "check SSL certs" in app settings networks works independently of the above, and only looks for changes.

And when there is a change, yes you will have to confirm, that's exactly what this feature is supposed to do - let the user decide when the app can't.


Creating debug logs for diagnostics: https://www.aqua-mail.com/troubleshooting/

The official FAQ: https://www.aqua-mail.com/faq/

Лог-файлы для диагностики: https://www.aqua-mail.com/ru/troubleshooting/

Вопросы и ответы: https://www.aqua-mail.com/ru/faq/