Major issue with SSL connections in iOS 9!

Immediately after upgrading to Xcode 7 and iOS 9, my app is unable to communicate with my server due to an SSL error.


I understand that iOS 9 requires TLSv1.2 for all SSL connections. My server is Tomcat 7 running on Java 1.7. This combination supports TLSv1.2 and I had previously configured it to support TLSv1.2 and eliminated support for the cypher with the bug in it. I tried going into my Tomcat configuration and telling it to ONLY use TLSv1.2, but this doesn't help. The app still refuses to connect.


I know there's a way I can disable this check by adding an NSAppTransportSecurity key to my app, but I don't want to do that. I want to understand the problem and fix it the right way. What am I doing wrong?


Thanks.

FYI, I'm sure my server in fact supports TLSv1.2. I tested it:


$ openssl s_client -connect backflash.nobleapplications.com:8443 -tls1_2
CONNECTED(00000003)
depth=2 C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", CN = Go Daddy Root Certificate Authority - G2
verify error:num=19:self signed certificate in certificate chain
verify return:0
---
Certificate chain
0 s:/OU=Domain Control Validated/CN=*.nobleapplications.com
   i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http:/
1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http:/
   i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2
2 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2
   i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIFPzCCBCegAwIBAgIICLUNwIxpocEwDQYJKoZIhvcNAQELBQAwgbQxCzAJBgNV
BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRow
GAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjEtMCsGA1UECxMkaHR0cDovL2NlcnRz
LmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMTMwMQYDVQQDEypHbyBEYWRkeSBTZWN1
cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwHhcNMTUwNTEyMTUxMTQ5WhcN
MTgwNzA1MTgyNzAyWjBFMSEwHwYDVQQLExhEb21haW4gQ29udHJvbCBWYWxpZGF0
ZWQxIDAeBgNVBAMMFyoubm9ibGVhcHBsaWNhdGlvbnMuY29tMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAobeH9Buat8zTD4OwmmW4J7LWr8dZek/fuYPB
om/AtrLkj17pl38nwkoAHiLEvURJ+j+G6bh+CMFAhMgFxSmThHb1QaBHv/wIT5ig
X3aQyMFb5lIaqeRnTFv6sNOjob+2Cd+TFbbfZgY9SjXnSaysMOd4I7KzvewKwIBp
zzTImyh0AGWs7NHxmrSOUGgNo/8bvLtZ2/+3qucrIka2GhlNRoOFaYJaPHlEWb4l
wRYx69i2989zSTKSO7+kxZO99t0dUBsTSUgt5Y/SlTSHSdBI5p15uTZ1gy5xxIx6
JWgPxZjHDlT35R6wbZFmbWYLW9B1az1tujWxxxG3cQv9o8zTFwIDAQABo4IBwTCC
Ab0wDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw
DgYDVR0PAQH/BAQDAgWgMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwuZ29k
YWRkeS5jb20vZ2RpZzJzMS04Ny5jcmwwUwYDVR0gBEwwSjBIBgtghkgBhv1tAQcX
ATA5MDcGCCsGAQUFBwIBFitodHRwOi8vY2VydGlmaWNhdGVzLmdvZGFkZHkuY29t
L3JlcG9zaXRvcnkvMHYGCCsGAQUFBwEBBGowaDAkBggrBgEFBQcwAYYYaHR0cDov
L29jc3AuZ29kYWRkeS5jb20vMEAGCCsGAQUFBzAChjRodHRwOi8vY2VydGlmaWNh
dGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvZ2RpZzIuY3J0MB8GA1UdIwQYMBaA
FEDCvSeOzDSDMKIz1/tss/C0LIDOMDkGA1UdEQQyMDCCFyoubm9ibGVhcHBsaWNh
dGlvbnMuY29tghVub2JsZWFwcGxpY2F0aW9ucy5jb20wHQYDVR0OBBYEFDvDurpN
ym8TB6AlWce2cLVQ978iMA0GCSqGSIb3DQEBCwUAA4IBAQCch7SMChhhbMs02Ayt
kfV3UDDz9rNq0sR6WiJWIK3Mz54LwmjKfdraLgpjNxuEwY3XzjLkR7m5e6zW0pRR
WqjM4BDK/UpDFBgXmekoqjfn9pdry0EvMRlUpZxNIHEFPb0p/ZaEqVUpTQbkClCq
pg/RKRKMz1MfKcvop8emHqGQeQICjJAcWKojaTVJCE8y/8YxtPd+NXTXByCRfHBy
UixdjMDKHOvtrVlsl/V2RqoBzaZyBoM3RiU+B7XgYokl/S/1paRWsxxJ9TgCO2fi
qF86zYq/zaC9bAO1Pkd5Tw3jBUYNtJJpDTxTh0LeRvmhzpHrAGQzPh+5XcXFbkGJ
n7FM
-----END CERTIFICATE-----
subject=/OU=Domain Control Validated/CN=*.nobleapplications.com
issuer=/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http:/
---
No client certificate CA names sent
---
SSL handshake has read 3749 bytes and written 666 bytes
---
New, TLSv1/SSLv3, Cipher is AES256-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : AES256-SHA256
    Session-ID: 55FC30EFB2283130877041ECEE52E4111E1E5DE853DDF1CE671A8D27A1E763C5
    Session-ID-ctx:
    Master-Key: 5EF3350F997C889E8D667CABC419330963C2DB4DED3D6DF0167C59AC87B91EEB91F44C79670803157FF9A220421F7CDC
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1442590959
    Timeout   : 7200 (sec)
    Verify return code: 19 (self signed certificate in certificate chain)
---
^C

Turns out I had to disable something called "requires forward secrecy". Amazon S3, which I also use in the same app, has the same problem.


  <key>NSAppTransportSecurity</key>
  <dict>
  <key>NSExceptionDomains</key>
  <dict>
  <key>backflash.nobleapplications.com</key>
  <dict>
  <key>NSExceptionRequiresForwardSecrecy</key>
  <false/>
  </dict>
  <key>s3.amazonaws.com</key>
  <dict>
  <key>NSExceptionRequiresForwardSecrecy</key>
  <false/>
  </dict>
  </dict>
  </dict>


I find it fairly incredible that this problem exists after all the months that iOS 9 has been available for testing.

Turns out I had to disable something called "requires forward secrecy". Amazon S3, which I also use in the same app, has the same problem.

For your server that seems to be the right short-term option. The sticking point is that your server negotiates a cypher suite that doesn’t provide forward secrecy (

RSA_WITH_AES_256_CBC_SHA256
) and thus you have to disable forward secrecy to get things working right now.

Of course the correct long-term option is to update the server to provide forward secrecy, which is an important security property.

Disabling forward secrecy is not the recommended option for Amazon S3, as discussed in this post.

I find it fairly incredible that this problem exists after all the months that iOS 9 has been available for testing.

Which “problem” exactly?

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks for the reply. It does give me some insight into the problem, although I am still unable to solve it.


The server I'm using is Tomcat. I can explicitly declare which ciphers I want to use, and I declared the following list:


TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA


I'm no SSL expert, but I believe that these should all be acceptable to iOS 9.


Nevertheless, my app still fails to connect without adding the exception.


I also don't understand one thing. If I have a server that can accept both ciphers that iOS 9 supports and ones that it does not support, why does iOS 9 negotiate a connection with an unsupported cipher and then fail? Why doesn't it ask for one it supports?

If I have a server that can accept both ciphers that iOS 9 supports and ones that it does not support, why does iOS 9 negotiate a connection with an unsupported cipher and then fail?

That’s not how TLS works. In TLS the client sends a list of list of cypher suites that it supports (in the Client Hello message) and the server chooses a cypher suite and sends that back to the client (in the Server Hello message). If I create a small app that disables ATS and point it at your server (

backflash.nobleapplications.com
, port 8443) I see this in the Client Hello message:
Cipher Suite: TLS_EMPTY_RENEGOTIATION_INFO_SCSV (0x00ff)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 (0xc024)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 (0xc023)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA (0xc008)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xc028)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
Cipher Suite: TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA (0xc012)
Cipher Suite: TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d)
Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c)
Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA256 (0x003d)
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA256 (0x003c)
Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
Cipher Suite: TLS_RSA_WITH_3DES_EDE_CBC_SHA (0x000a)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_RC4_128_SHA (0xc007)
Cipher Suite: TLS_ECDHE_RSA_WITH_RC4_128_SHA (0xc011)
Cipher Suite: TLS_RSA_WITH_RC4_128_SHA (0x0005)
Cipher Suite: TLS_RSA_WITH_RC4_128_MD5 (0x0004)

And this in the Server Hello message:

Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA256 (0x003d)

That is, the client has offered ECDHE suites and the server has explicitly chosen a non-ECDHE suite.

OTOH, if I enable ATS then the client only offers ECDHE suites:

Cipher Suite: TLS_EMPTY_RENEGOTIATION_INFO_SCSV (0x00ff)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 (0xc024)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 (0xc023)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xc028)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)

and the server responds by failing the connection.

In short, your server is not supporting ECDHE properly.

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

So I guess the question is: has anyone come up with a configuration that works for a java based server (Tomcat, Jboss (which I'm using), etc.) that works with iOS 9?


BTW as side note: if anyone tried the NSAppTransportSecurity bypass option and couldn't get it to work, try adding the port number e.g., myservice.example.com:8443 -- didn't work for me until appended the port #

So I guess the question is: has anyone come up with a configuration that works for a java based server (Tomcat, Jboss (which I'm using), etc.) that works with iOS 9?

Alas, I can’t help you there (but maybe someone else will chime in).

BTW as side note: if anyone tried the NSAppTransportSecurity bypass option and couldn't get it to work, try adding the port number e.g., myservice.example.com:8443 -- didn't work for me until appended the port #

I’m not sure what’s going on with your specific situation but a) this should not be necessary, b) it is not necessary in my experience, and c) I recommend against doing it because it runs counter to the documented specification of the ATS dictionary.

When testing this myself I got confused by one thing that might explain the behaviour you’re seeing. When I configured my ATS dictionary I set my

NSExceptionDomains
to
biff.local:12345
but I also had an
NSAllowsArbitraryLoads
value inherited from my project template. The “:12345” was causing ATS to ‘miss’ my
NSExceptionDomains
entry and thus its behaviour was set by the
NSAllowsArbitraryLoads
entry. The upshot of this was adding a “:12345” to my
NSExceptionDomains
key made things work, but not in the right way. Once I removed the “:12345” from my
NSExceptionDomains
key, ATS started using my
NSExceptionDomains
entry and then I went on to debug the actual cause of connection failure (which was a problem with my server).

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
Major issue with SSL connections in iOS 9!
 
 
Q