Reputation: 10709
I'm having trouble connecting to a TLS-only backend. The configuration is the following:
Client: Android device (Moto X gen 2, Android 5.1) with curl version:
curl 7.21.3 (arm-unknown-eabi) libcurl/7.21.3 OpenSSL/1.0.1j zlib/1.2.8
Protocols: http https
Features: IPv6 NTLM SSL libz
Server: Wildcard cert (DigiCert SHA2 Secure Server CA), with backend accepting TLS 1.0 or higher-only.
When using cURL 7.43.0 in OS X the connection works fine, since the client is respecting the server's highest TLS version:
curl -vvv -X GET -o /dev/null https://domain
* Rebuilt URL to: https://domain
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying ip...
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to domain (ip) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
* Server certificate: *.domain
* Server certificate: DigiCert SHA2 Secure Server CA
* Server certificate: DigiCert Global Root CA
0 0 0 0 0 0 0 0 --:--:-- 0:00:01 --:--:-- 0> GET / HTTP/1.1
> Host: domain
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 200 OK
But no luck in Android. Since no SSLv3 connections will be accepted, the --tlsv1
option is passed. Still, the client chooses to use SSLv3, thus failing to conclude the handshake:
curl -vvv --tlsv1 -X GET https://domain
* About to connect() to domain port 443 (#0)
* Trying ip... connected
* Connected to domain (ip) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs/
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS alert, Server hello (2):
* SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
* Closing connection #0
Same results without specifying TLS 1.0: curl -vvv -X GET https://domain
Is there any way that I can tell the client to use TLS and not SSLv3?
Edit: Check the accepted answer, since it's a good way to really check what cURL is doing in your device. The issue itself was being caused because the cert didn't have the full chain attached to it (intermediate + root certs). Here are a couple of online SSL health checkers that can help you further debug the issue:
https://www.ssllabs.com/ssltest/
https://www.digicert.com/help/
Upvotes: 1
Views: 7099
Reputation: 123481
- SSLv3, TLS handshake, Client hello (1):
Although this looks like SSLv3 is used maybe it is not used. OpenSSL implements most of the TLS1.x protocol within SSLv3 functions because TLS1.x is just the better SSLv3 and the protocols don't differ that much.
To test this I've setup a simple server which echos the cipher and protocol version back which gives on the curl side:
$ curl -vvv --tlsv1 -o /dev/null --insecure https://127.0.0.1:12345
...
* SSLv3, TLS handshake, Client hello (1):
} [data not shown]
* SSLv3, TLS handshake, Server hello (2):
{ [data not shown]
* SSLv3, TLS handshake, CERT (11):
{ [data not shown]
* SSLv3, TLS handshake, Server key exchange (12):
{ [data not shown]
* SSLv3, TLS handshake, Server finished (14):
{ [data not shown]
* SSLv3, TLS handshake, Client key exchange (16):
} [data not shown]
* SSLv3, TLS change cipher, Client hello (1):
} [data not shown]
* SSLv3, TLS handshake, Finished (20):
} [data not shown]
* SSLv3, TLS change cipher, Client hello (1):
{ [data not shown]
* SSLv3, TLS handshake, Finished (20):
{ [data not shown]
* SSL connection using ECDHE-RSA-AES128-GCM-SHA256
But on the server side:
cipher=ECDHE-RSA-AES128-GCM-SHA256 version=TLSv1_2
GET / HTTP/1.1
User-Agent: curl/7.35.0
Host: 127.0.0.1:12345
Accept: */*
Thus even if the debug output says SSLv3 it is actually TLS1.2.
Upvotes: 4