seadroid icon indicating copy to clipboard operation
seadroid copied to clipboard

Can't establish TLS connection to Seafile Server on Android 7.0 because of specific elliptic curve

Open moschlar opened this issue 9 years ago • 6 comments

In our Nginx configuration, we explicitly specified an elliptic curve that is supposed to be more secure than the default one:

    ssl_ecdh_curve secp384r1;

Since then, Seafdroid clients under Android 7.0 could not connect to the server anymore.

The error message that is displayed to the users is additionally confusing, since it implies that there was some error with the certificate, which is not the case: hdjhiabe

Somehow, explicitly specifying this elliptic curve in conjunction with the javax.net.ssl packages on Android 7.0 messes up the TLS handshake. We confirmed that this happens with another Android app, too, if its server is configured this way. But it does not happen when our Seahub site is accessed from the Default system browser of that Android device.

Maybe someone here has an idea how to prevent this from happening, even if it is a bug in the underlying operating system. Maybe @Logan676 has some insights on this, since he was the last one to touch the code in app/src/main/java/com/seafile/seadroid2/ssl ;-)

moschlar avatar Nov 22 '16 16:11 moschlar

Question is what the default browser is. Afaik in the meantime it is Chrome or likely based on Chrome. I also think that chrome doesn't depend on the system checks but it's likely that chrome implements its own checks to allow Google to enforce their newest SSL/TLS policies.

Edit: See also: http://stackoverflow.com/a/39800078

Looks like manually enabling the specific curve works - isn't a really nice solution, though.

shoeper avatar Nov 22 '16 17:11 shoeper

Chrome for Android ships its own SSL library. That might explain the different behavior compared with regular apps.

forouher avatar Nov 22 '16 17:11 forouher

@shoeper wrote:

Edit: See also: http://stackoverflow.com/a/39800078 Looks like manually enabling the specific curve works - isn't a really nice solution, though.

I don't know what you mean by that. The Nginx default value for ssl_ecdh_curve is prime256v1 but we changed it to secp384r1, which causes the problems. I don't see any mentioned possibility to enable something on the client side there?

moschlar avatar Nov 23 '16 21:11 moschlar

I don't see any mentioned possibility to enable something on the client side there?

Only via modifying the code of the app.

shoeper avatar Nov 24 '16 10:11 shoeper

Here is an article about playing with ECDH on Android:

https://nelenkov.blogspot.de/2011/12/using-ecdh-on-android.html

Maybe there is a way to patch Seadroid's SSL code to enable larger curves.

But, to be honest, I wouldn't spent too much time on this. The security benefit from switching from 256 bit EC to 384 bit EC is very, very, very theoretical [0]. If you're running from an adversary with the capability to brute-force 256 bit EC keys, you would be well advised to stop using computers in general. ;)

[0] https://www.keylength.com/en/8/

forouher avatar Nov 24 '16 11:11 forouher

Note that the system stack for SSL in Android 7.0 supports only elliptic curve secp256r1 alias prime256v1 alias NIST P-256. And the bad thing about that is that this applies to both the ECDHE curves and an ECDSA key, if you use one. I’d call this a very bad regression from older Android versions. It appears that 7.1.1, at least, has it fixed.

So if you generate an ECDSA key with, for example, secp384r1 there is no way to connect to it from Android 7.0 even if you enable the prime256v1 in your nginx’s ssl_ecdh_curve parameter. You have to generate a 256-bit ECC key or wait for 7.1(.1).

typingArtist avatar Nov 27 '16 10:11 typingArtist