-
Re: Why does NSURLSession in iOS9 return -9802?
eskimo Aug 7, 2015 12:57 AM (in response to dhoerl)[I'm using the latest Xcode 7b4 ...]
Please retry with Xcode 7.0b5. Stuff is changing pretty rapidly on this front and so I want to make sure we're all on the same page.
Share and Enjoy
—
Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardwarelet myEmail = "eskimo" + "1" + "@apple.com"
-
Re: Why does NSURLSession in iOS9 return -9802?
dhoerl Aug 7, 2015 8:01 AM (in response to eskimo)Still not working in 7b5.
Hmmm - just read the Xcode 7b5 release notes. I see this:
Networking
Note
When negotiating a TLS/SSL connection with Diffie-Hellman key exchange, iOS 9 requires a 1024-bit group or larger. These connections include:
- Secure Web (HTTPS)
...
Now, my forwared cipher is "ECDHE_RSA_WITH_AES_128_CBC_SHA" - hmmm - is DHE in that name stand for "Diffie-Hellman [key] Exchange"?
So the next question is - is the above a note on a limitation, or an announcement of what the future holds?
NOTE: there is this tidbit too - not sure if related or not:
Secure Transport
Note
- DHE_RSA ciphersuites 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. Applications that explicitly enable ciphersuites using
SSLSetEnabledCiphers()
are not affected and will still use DHE_RSA ciphersuites if explicetely enabled.
-
Re: Why does NSURLSession in iOS9 return -9802?
eskimo Aug 10, 2015 1:05 AM (in response to dhoerl)Still not working in 7b5.
Are you still seeing that
NSExceptionRequiresForwardSecrecy
works around the problem? I was playing around with this myself and that didn't work, so I'm curious about your experience.Share and Enjoy
—
Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardwarelet myEmail = "eskimo" + "1" + "@apple.com"
-
Re: Why does NSURLSession in iOS9 return -9802?
eskimo Aug 11, 2015 1:04 AM (in response to eskimo)dhoerl sent me the information I was looking for privately.
For those reading along at home, the reason why I was seeing weird results is that if you fetch the server's root (
https://s3.amazonaws.com
) via HTTPS, the server redirects you to an HTTP page. Once I disabled this redirect, I got a lot less confused.I believe that the connection is failing the ATS check because the leaf certificate (not the TLS cypher suite, but the certificate itself) uses SHA-1 (sha1withRSAEncryption) whereas ATS requires SHA-2/256 or better (sha256WithRSAEncryption). This requirement is documented in the ATS Technote, although the discussion is not super clear.
What is not documented is that
NSExceptionRequiresForwardSecrecy
relaxes this check. The docs say thatNSExceptionRequiresForwardSecrecy
simply enables extra cypher suites and says nothing about relaxing the SHA-2/256 requirement. I've filed a bug to get the docs updated.Anyway, the upshot of all of this is that dhoerl should set
NSExceptionRequiresForwardSecrecy
until such time as the server upgrades its certificate from SHA-1.Share and Enjoy
—
Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardwarelet myEmail = "eskimo" + "1" + "@apple.com"
-
Re: Why does NSURLSession in iOS9 return -9802?
eskimo Sep 9, 2015 7:33 AM (in response to eskimo)What is not documented is that NSExceptionRequiresForwardSecrecy relaxes this check. The docs say that NSExceptionRequiresForwardSecrecy simply enables extra cypher suites and says nothing about relaxing the SHA-2/256 requirement. I've filed a bug (r. 22227634) to get the docs updated.
It turns out that the fact that
NSExceptionRequiresForwardSecrecy
relaxes the SHA-2/256 requirement is a bug; the intended behaviour ofNSExceptionRequiresForwardSecrecy
is the behaviour documented in the App Transport Security Technote, namely that it should just enable specific cypher suites.Our plan is to fix this bug at some point in the future. We expect to fix this in some compatible fashion, so folks who’ve mistakenly used
NSExceptionRequiresForwardSecrecy
to disable the SHA-2/256 requirement won’t break. However, predicting the future is always a challenge.Which brings us to what you should do right now. [A previous version of this post gave less concrete advice. The following is an update that tightens things up.] After discussing this with ATS Engineering our recommendations are:
If you're using a specific hosting service, you should consult your hosting service to get the latest advice.
In situations like this, where the server is fully compatible with ATS except for the SHA-2/256 certificate signing requirement, we recommend that you accurately document that state of affairs by using
NSExceptionAllowsInsecureHTTPLoads
.You should attempt to make your server fully compatible with ATS as soon as possible.
When that happens, you should update your app with the more secure ATS settings.
I should stress that
NSExceptionAllowsInsecureHTTPLoads
isn't actually insecure. It's just as secure as your app currently is when it's running on iOS 8. Rather, it means that your app doesn't benefit from the extra security provided by ATS.Share and Enjoy
—
Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardwarelet myEmail = "eskimo" + "1" + "@apple.com"
-
Re: Why does NSURLSession in iOS9 return -9802?
dhoerl Aug 17, 2015 12:29 PM (in response to eskimo)Well, I think I'll just use NSExceptionAllowsInsecureHTTPLoads. Really, this is Amazon - surely they'll get enough blow back to fix the issue in the not too distant future.
Thank you very much for all your help tracking down this gnarly issue!
-
Re: Why does NSURLSession in iOS9 return -9802?
mtrpranata Aug 31, 2015 10:28 PM (in response to dhoerl)Hi Dhoerl,
I was just wondering if the issues is ressolved on the beta 6? I still get the
NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)
And this is what is in my plist:
<key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>s3.amazonaws.com</key> <dict> <key>NSIncludeSubdomains</key> <true/> <key>NSThirdPartyExceptionAllowsInsecureHTTPLoads</key> <true/> </dict> </dict> </dict>
I tried both NSThirdPartyExceptionAllowsInsecureHTTPLoads and NSExceptionAllowsInsecureHTTPLoads. Also tried the NSExceptionRequiresForwardSecrecy. Still no luck.
BUT
When I specify the full list mystuff.s3.amazonaws.com, it WORKS. Is it possible that NSIncludeSubdomains is broken?
-
Re: Why does NSURLSession in iOS9 return -9802?
eskimo Sep 1, 2015 12:18 AM (in response to mtrpranata)Is it possible that NSIncludeSubdomains is broken?
AFAIK this works, although you do have to spell it correctly (-:
The documented value is
NSIncludesSubdomains
whereas you’re usingNSIncludeSubdomains
(you need an “s” at the end of “includes”).Share and Enjoy
—
Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardwarelet myEmail = "eskimo" + "1" + "@apple.com"
-
Re: Why does NSURLSession in iOS9 return -9802?
mtrpranata Sep 1, 2015 4:14 PM (in response to eskimo)Thanks a lot. That was it. Doh :/
-
-
-
Re: Why does NSURLSession in iOS9 return -9802?
smizoguchi Sep 3, 2015 8:39 AM (in response to dhoerl)Looks like an Amazon fix no later than September 30th.
-
-
Re: Why does NSURLSession in iOS9 return -9802?
skunkworks Sep 17, 2015 10:38 AM (in response to eskimo)This is not the behavior we are seeing as of Xcode 7 GM and iOS 9 GM.
What we're seeing is that NSExceptionAllowsInsecureHTTPLoads = YES does not get around the SHA-256 requirement, but NSExceptionRequiresForwardSecrecy = NO does.
-
Re: Why does NSURLSession in iOS9 return -9802?
eskimo Sep 18, 2015 12:46 AM (in response to skunkworks)What we're seeing is that NSExceptionAllowsInsecureHTTPLoads = YES does not get around the SHA-256 requirement …
That makes no sense at all.
NSExceptionAllowsInsecureHTTPLoads
disables all ATS checking, so things behaviour like they did on iOS 8.Moreover, I tested this again. First, I confirmed that the site dhoerl referenced is still using a SHA-1 signature.
$ TLSTool s_client -connect s3.amazonaws.com:443 * input stream did open * output stream did open * output stream has space * protocol: TLS 1.2 * cipher: ECDHE_RSA_WITH_AES_128_CBC_SHA * trust result: unspecified * certificate info: * 0 rsaEncryption 2048 sha1-with-rsa-signature 's3.amazonaws.com' …
Then I wrote a small test app that uses NSURLSession to fetch the root of that site (making sure to disable redirection, as I discussed on 11 Aug). With the following ATS settings it connected just fine.
<key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>s3.amazonaws.com</key> <dict> <key>NSExceptionAllowsInsecureHTTPLoads</key> <true/> </dict> </dict> </dict>
If you have a specific example of it failing, please post it.
Share and Enjoy
—
Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardwarelet myEmail = "eskimo" + "1" + "@apple.com"
-
Re: Why does NSURLSession in iOS9 return -9802?
skunkworks Sep 18, 2015 3:30 PM (in response to eskimo)https://www.dropbox.com/s/2oncfpyg9w2gy2j/TestAppTransportSecurity.zip?dl=0
Here's a sample project that has NSExceptionAllowsInsecureHTTPLoads.
-
Re: Why does NSURLSession in iOS9 return -9802?
eskimo Sep 21, 2015 5:27 AM (in response to skunkworks)Here's a sample project that has NSExceptionAllowsInsecureHTTPLoads.
Thanks. It’s really helpful to have a simple example to play with. And, after a bit of spelunking, I have a rough idea what’s going on.
Your test app accesses
api.braintreegateway.com
, so I compared its TLS setup to dhoerl’s S3 example that I’ve been testing:$ TLSTool s_client -connect api.braintreegateway.com:443 … * protocol: TLS 1.2 * cipher: ECDHE_RSA_WITH_AES_128_CBC_SHA256 * trust result: unspecified * certificate info: * 0 rsaEncryption 2048 sha1-with-rsa-signature 'api.braintreegateway.com' … ^C $ TLSTool s_client -connect s3.amazonaws.com:443 … * protocol: TLS 1.2 * cipher: ECDHE_RSA_WITH_AES_128_CBC_SHA * trust result: unspecified * certificate info: * 0 rsaEncryption 2048 sha1-with-rsa-signature 's3.amazonaws.com' … ^C
The results are very similar, with two things to note:
Your site uses
ECDHE_RSA_WITH_AES_128_CBC_SHA256
, which is ‘better’ than theECDHE_RSA_WITH_AES_128_CBC_SHA
used by S3. Both are explicitly allowed by ATS.Both sites use
sha1-with-rsa-signature
, which is the ATS roadblock we’re trying to get around.
I then set up a test project with an ATS dictionary like this:
<key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>s3.amazonaws.com</key> <dict> <key>NSExceptionAllowsInsecureHTTPLoads</key> <true/> </dict> <key>api.braintreegateway.com</key> <dict> <key>NSExceptionAllowsInsecureHTTPLoads</key> <true/> </dict> </dict> </dict>
Weirdly, this works for S3 and not for your domain. Why?
After some digging I worked this out: the OS thinks that your site requires HTTP Strict Transport Security (HSTS). Now, I don’t know why the OS thinks that, but the fact that it does overrides the ATS exception in the
Info.plist
. In short, HSTS trumps ATS.Alas, I’ve totally run out of time to investigate this in the context of DevForums. I’d be happy to look into the HSTS side of things in the context of a DTS tech support incident.
Share and Enjoy
—
Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardwarelet myEmail = "eskimo" + "1" + "@apple.com"
-
-
Re: Why does NSURLSession in iOS9 return -9802?
ifdev Sep 20, 2015 7:43 AM (in response to eskimo)Eskimo, I am seeing the same as Skunkworks. None of the per-domain settings seems to relax the SHA-256 setting except the buggy one.
Say you have a domain like s3.amazonaws.com, which supports TLSv1.2 and ECDHE, but the RSA 2048-bit cert is signed using sha1WithRSAEncryption. Without ATS exceptions, NSURLConnection fails to connect with kCFStreamErrorDomainSSL -9802 (errSSLFatalAlert).
But setting NSExceptionAllowsInsecureHTTPLoads=true or NSThirdPartyExceptionAllowsInsecureHTTPLoads=true for that domain doesn't fix it so that NSURLConnection connects. You still get -9802.
(THIS PARAGRAPH NOT FACT CHECKED THIS MORNING) Based on some previous experimentation that I haven't retried on the GM, it doesn't fail at the socket layer anymore, and you could implement the various NSURLAuthenticationChallenge related callbacks for NSURLAuthenticationMethodServerTrust to get around the default trust policy that disallows weak certificate fingerprints. But leave me implementing certificate trust myself or figuring out a proper incantation to SecTrustEvaluate. This seems frought with peril. (END OF DISCLAIMED SECTION)
However, if I set NSThirdPartyExceptionRequiresForwardSecrecy=false, suddenly everything just works. In fact, one of my service providers sent an email to their customers on iOS 9 release day telling us they hadn't managed to deploy their sha256 thumbprinted certs and actually suggested including this nonsense exception (nonsense because they do support ECDHE). This was my first inkling that it did not behave as specified in the technote.
Furthermore, it's super scary setting AllowsInsecureHTTPLoads, since the technote says "Use this key to access domains with no certificate, or with an error for a self-signed, expired, or hostname-mismatch certificate." And we do want HTTPS-only. And we don't want to turn on NSAllowsArbitraryLoads because we much prefer a whitelist of known good (or at least necessary) service providers with outdated TLS deployments.
-
Re: Why does NSURLSession in iOS9 return -9802?
kharrison Sep 20, 2015 12:08 PM (in response to ifdev)You may want to retest on the public release. I am actually seeing different results between the GM and the final public release which I was not expecting.
The Twitter search api at https://api.twitter.com is similar to the Amazon S3 example above. It uses TLS 1.2 and ECDHE_RSA key exchange which provides forward secrecy but has a weakly signed SHA1 signature (see https://www.ssllabs.com/ssltest/analyze.html?d=api.twitter.com&s=199.59.148.87).
When testing with the GM I was seeing ATS rejections (error code -9802) which was fixed adding the NSThirdPartyExceptionAllowsInsecureHTTPLoads exception. This would seem to be expected if I have understood the ATS policy correctly.
What is odd is that with the public release of iOS 9 the exception is no longer required. The connection succeeds with the default ATS policy. Maybe the requirement for a SHA256 signed signature was relaxed but then at least the ATS Technote should be updated.
I have logged radar 22763438 with CFNetwork debug logs for both cases.
-
Re: Why does NSURLSession in iOS9 return -9802?
ifdev Sep 22, 2015 12:44 PM (in response to kharrison)It turns out the domain I'm actually interested in has HSTS headers like Skunkworks example. That seems to be the key.
-
-
-
-
-
-
-