Anyone got NSURLConnection working on iOS 9 without exceptions? - ios

I am trying to run my app on iOS 9 -- Xcode 7 beta 5. Although my URLs are https, NSURL connection is still throwing an error:
NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)
I am trying to avoid using an exception to get this working. My server supports the required protocols: https://developer.apple.com/library/prerelease/ios/technotes/App-Transport-Security-Technote/index.html
Thanks...
UPDATE: the release notes indicate that they have dropped default support of DHE_RSA ciphers:
"DHE_RSA cipher suites are now disabled by default in Secure Transport for TLS clients. This may cause failure to connect to TLS servers that only support DHE_RSA cipher suites. Apps that explicitly enable cipher suites using SSLSetEnabledCiphers are not affected and will still use DHE_RSA cipher suites if explicitly enabled."
These are the ciphers supported by my server. See the full list here:
https://developer.apple.com/library/prerelease/ios/technotes/App-Transport-Security-Technote/index.html
So I guess I need to use SSLSetEnabledCiphers for every NSURLConnection, or upgrade my server to support the DHE_ECDSA ciphers. Or use the exception mechanism for now.
Anything I've missed? And anyone got sample code for using SSLSetEnabledCiphers?
Thanks.

Here's the deal. The innocuous language about DHE_RSA cipher suites not being supported by default is a pretty big change by Apple in beta 5. A lot of servers out there don't support ECDHE_ECDSA ciphers by default. In order to support those ciphers on my server, it looks like I will have to upgrade something or several somethings. Or even recompile something. Ack.
And I assumed that I would just have to ensure all URLs were HTTPS!
Specifically I was able to support HTTPS-only links to my server by using the "NSExceptionRequiresForwardSecrecy = NO" key in info.plist. Also not forgetting the "NSIncludesSubdomains = YES" key if necessary.
Useful background, especially if Diffie-Helmen Exchange, Elliptical Curve and Forward Secrecy are not familiar to you:
http://blog.ivanristic.com/2013/08/configuring-apache-nginx-and-openssl-for-forward-secrecy.html
http://blog.lowsnr.net/2014/10/26/configuring-apache-2-2-ssltls-for-forward-secrecy/

Related

Indy "Connection Reset by Peer" Err. 10054 on Specific Website

I am encountering some problems using some code that worked for ages involving Indy and the download of a web page. I use RAD Studio 10.2 Tokyo.
The web page is as follows:
https://donet.rfi.it/RFIPlatform/showDoc.do?compartimentoHidden=AN&docTypeHidden=CC
The code I am using is part of an application which has the same code since 2011 and it always worked well. The code is as follows:
IDHTTP1.Get('https://donet.rfi.it/RFIPlatform/showDoc.do?compartimentoHidden=AN&docTypeHidden=CC');
I am getting a "Connection Reset by Peer 10054" error since the website went down, some days ago, and when it came up again, the code did not work anymore.
The aforementioned web page can be called from the browser, can even be downloaded with WGET, but Indy is failing.
I tried to play with various options (Cookie Handling, Handle Redirects, HTTPOptions, etc...) and I also updated the SSL libraries to 1.0.2q (Indy cannot use OpenSSL 1.1.0 yet), but the whole thing just doesn't want to work.
Can someone help me figure out what is going on? It has to be for sure something on the website, since the code I use is the same since 2011 and it has always worked. And before that, the same code worked in a similar application since 2008.
Indy's TIdSSLIOHandlerSocketOpenSSL component enables only TLS 1.0 by default. The website in question (https://donet.rfi.it) does not accept TLS 1.0 anymore (probably why it went offline, to update its software), it will accept only TLS 1.1+ now.
TIdHTTP is able to successfully establish a TCP/IP connection to donet.rfi.it:443, but as soon as TIdSSLIOHandlerSocketOpenSSL sends a TLS 1.0 handshake request, the server forcibly closes the TCP connection. You are getting the "connection reset by peer" error while TIdSSLIOHandlerSocketOpenSSL is trying to read the server's handshake response.
You need to configure TIdSSLIOHandlerSocketOpenSSL to enable TLS 1.1 and/or 1.2. You can do that via its SSLOptions.SSLVersions property. Then TIdHTTP.Get() will work again (I tested it).

Indy server supports SSL 2, but it should not

Indy Delphi 10.1 Berlin.
My customer had the HTTPS connection checked (using Qualys SSL Labs). The report states: "This server supports SSL 2" plus other warnings but I guess they are related to this.
The code used is as follows:
SSLIOhandler:=TIdServerIOHandlerSSLOpenSSL.Create(NIL);
SSLIOhandler.SSLOptions.Method:=sslvTLSv1_2;
SSLIOhandler.SSLOptions.Mode:=sslmServer;
SSLIOhandler.OnVerifyPeer:=OnVerifyPeer;
SSLIOhandler.SSLOptions.SSLVersions:=[sslvTLSv1,sslvTLSv1_1,sslvTLSv1_2];
HTTPServer:=TIdHTTPServer.Create(NIL);
HTTPServer.IOhandler:=SSLIOhandler;
I have read various posts but this area remains pretty much abacadabra to me. I limited the SSLVersions to just [sslvTLSv1_2] but the warning remains. What else can I do?
Update: Sorry to waste time. The Qualys test site apparently did not reload. I've restarted and retested and indeed it no longer complains about SSL2.
Next step is to pass its complaints about the ciphers, starting with TLS_RSA_WITH_DES_CBC_SHA. I have a list of ciphers but can't find how to assign them. When I use e.g.
SSLOptions.CipherList:='TLS_RSA_WITH_3DES_EDE_CBC_SHA';
I get an error: "SetCipher failed".

How do I support TLS 1.1 and 1.2 only (in my webservice)?

In this question I asked about limiting the available SSL/TLS protocols for my webservice under Delphi XE2.
By using a TIdServerIOHandlerSSLOpenSSL component and setting its SSLOptions.SSLVersions properties to [sslvSSLv23,sslvTLSv1] I was able to limit he available protocols to TLS 1.x.
Now, after upgrading to Delphi Seattle Upgrade 1, I wanted to further limit this to TLS 1.1 and 1.2 only:
LIOHandleSSL.SSLOptions.SSLVersions := [sslvTLSv1_1,sslvTLSv1_2];
But this does not work at all. When trying to connect I get a
exception class EidOSSLUnderlying CryptoError with message
'Error accepting connection with SSL. error: 140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol'
and
Error connecting with SSL
EOF was observed that violates the protocol
What is going on here? How to fix it?
Notes:
Tested with OpenSSL 1.02f and 1.02h
Setting the 'old' combination [sslvSSLv23,sslvTLSv1] works
Including TLS 1.0 works as well: [sslvTLSv1,sslvTLSv1_1,sslvTLSv1_2]
I would personally just keep the SSLVersion to its default and use SSLOptions.CipherList instead to limit SSL using only known secure ciphers:
LIOHandleSSL.SSLOptions.CipherList := 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
This should disable older SSL versions implicitly because these do not support the specified ciphers AFAIK.
Note that OpenSSL 1.0.2g+ disables SSLv3 by default, unless one explicitly activates it during compilation.

How do I use HTTPS replication with iOS Couchbase Mobile?

I'm using iOS Couchbase Mobile to have a couchdb server on an iPad that uses replication to sync with a server on https://cloudant.com. cloudant uses HTTPS, and when I try replicating on the iPad, i just get spammed by errors.
This is a known issue, as seen on this FAQ article. It recommends using 1.0.2 to fix the issue, but how do i know if I'm running it on Erlang R14?
Version Info
On myserver.cloudant.com: {"couchdb":"Welcome","version":"1.0.2","cloudant_build":"1.3.49"}
On iOS Couchbase Mobile: {"couchdb":"Welcome","version":"2.0.0-beta"}
(For some reason it says I'm using 2.0.0-beta on iOS, even though I downloaded this version (2.0.1).)
Here's the kind of error that I get:
[info] [<0.327.0>] Retrying HEAD request to https://user:password#mycompany.cloudant.com/mydb/ in 16.0 seconds due to error {'EXIT',
{no_ssl_server,
{gen_server,call,
[<0.347.0>,
{send_req,
{{url,
"https://user:password#mycompany.cloudant.com/mydb/",
"mycompany.cloudant.com",443,"mycompany","password",
"/mydb/",https,hostname},
[{"Accept","application/json"},
{"User-Agent","CouchDB/2.0.0-beta"}],
head,<<>>,
[{response_format,binary},
{inactivity_timeout,30000},
{is_ssl,true},
{socket_options,[{keepalive,true},{nodelay,false}]},
{ssl_options,[{depth,3},{verify,verify_none}]}],
infinity}},
infinity]}}}
The issue of enabling https connection between CouchBase Mobile for iOS and another CouchDB/CouchBase instance is also discussed here: https://groups.google.com/d/msg/mobile-couchbase/DDHSisVWEyo/hxtlVRhQtwkJ
Apparently it can be done.
I've found a "nightly build" that enables SSL support in CouchBase Mobile for iOS, but it was never QA'd and it never got released in a "stable build". I have contacted someone who was working on Couchbase Mobile for iOS, and he told me that I should use TouchDB instead.
CouchDB provides information on current Erlang version in it's Server response header, like this:
HTTP/1.1 200 OK
Server: CouchDB/1.0.1 (Erlang OTP/R13B) <----------------------
Date: Fri, 05 Nov 2010 14:57:16 GMT
Content-Type: text/plain;charset=utf-8
Since error message says it can't find HTTPS server, you probably want to check it via plain HTTP.
BTW CouchDB and CouchBase are completely different database products (both use Erlang platform) and it seems like you are using them interchangeably. Maybe the problem is that you are trying to connect to CouchDB with CouchBase client or something like that?

Received fatal alert: bad_certificate RestAssured

I am using the RestAssured library to make calls to certain REST API's
These are https endpoints and I tried using the "relaxedHTTPSValidation()" method provided in RestAssured to bypass SSL validation
My request looks something like
RequestSpecification req = RestAssured.given().relaxedHTTPSValidation().body().post();
I keep getting the error
javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1959)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1077)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
Doeas anyone have an idea why this is happening ?
Which version are you using? We had the same issue before with an early version. After updating it to the latest the problem was solved.
Un-synched same java version b/w the client and server.
compatibility issues with different versions of SSL & TLS v1, where as client handles only using SSL v3).

Resources