title: NSURLSession Fails With SSL Page Using TLS 1.2
body: <p>I'm using NSULConnection to send data to a webservice over SSL. The server is signed with a wildcard certificate (*.mydomain.com). The certificate is using RES SHA256 and TLS 1.2 and is signed by a CA. I'm trying to send my data using the following code:</p>
  
  <pre><code>NSMutableURLRequest *req = [[NSMutableURLRequest alloc] init];
  [req setTimeoutInterval:60];
  [req setHTTPMethod:@"POST"];
  // ... Set content type and add data to body ... //
  
  [req setURL:@"https://subdomain.mydomain.com/service/"];
  NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
  NSLog(@"Starting Upload");
  NSURLSessionDataTask *task = [session dataTaskWithRequest:req
                                          completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){
      // .. Handle Completion .. //
  }];
  
  [task resume];
  </code></pre>
  
  <p>When I run the above code I get the following output. </p>
  
  <pre>
  CFNetwork SSLHandshake failed (-9801) 
  NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9801)
  </pre>
  
  <p>So, I tried adding the exceptions explained in this post: <a href="https://stackoverflow.com/questions/30720813/cfnetwork-sslhandshake-failed-ios-9">CFNetwork SSLHandshake failed iOS 9</a></p>
  
  <p>But had no luck in getting the error to resolve itself. I then switched to using <code>http</code> instead of <code>https</code>, while leaving in the configuration changes explained above and it did work. However, that is far from an ideal solution. The <code>http</code> is fine for testing, but this app will be handling data where SSL is required. How can I get the SSL working? </p>
  
  <p><strong>Edit</strong></p>
  
  <p>Here are the results of running <code>nscurl --ats-diagnostics</code> on the <code>https</code> version of my service url</p>
  
  <pre>
  ================================================================================
  
  Default ATS Secure Connection
  ---
  ATS Default Connection
  Result : PASS
  ---
  
  ================================================================================
  
  Allowing Arbitrary Loads
  
  ---
  Allow All Loads
  Result : PASS
  ---
  
  ================================================================================
  
  Configuring TLS exceptions for ****
  
  ---
  TLSv1.2
  Result : PASS
  ---
  
  ---
  TLSv1.1
  Result : PASS
  ---
  
  ---
  TLSv1.0
  Result : PASS
  ---
  
  ================================================================================
  
  Configuring PFS exceptions for ****
  
  ---
  Disabling Perfect Forward Secrecy
  Result : PASS
  ---
  
  ================================================================================
  
  Configuring PFS exceptions and allowing insecure HTTP for ****
  
  ---
  Disabling Perfect Forward Secrecy and Allowing Insecure HTTP
  Result : PASS
  ---
  
  ================================================================================
  
  Configuring TLS exceptions with PFS disabled for ****
  
  ---
  TLSv1.2 with PFS disabled
  Result : PASS
  ---
  
  ---
  TLSv1.1 with PFS disabled
  Result : PASS
  ---
  
  ---
  TLSv1.0 with PFS disabled
  Result : PASS
  ---
  
  ================================================================================
  
  Configuring TLS exceptions with PFS disabled and insecure HTTP allowed for ****
  
  ---
  TLSv1.2 with PFS disabled and insecure HTTP allowed
  Result : PASS
  ---
  
  ---
  TLSv1.1 with PFS disabled and insecure HTTP allowed
  Result : PASS
  ---
  
  ---
  TLSv1.0 with PFS disabled and insecure HTTP allowed
  Result : PASS
  ---
  
  ================================================================================ 
  </pre>
  
  <p><strong>Edit 2</strong></p>
  
  <p>Here are the exceptions I added:</p>
  
  <pre><code>&lt;dict&gt;
      &lt;key&gt;mydomain.com&lt;/key&gt;
      &lt;dict&gt;
          &lt;key&gt;NSIncludesSubdomains&lt;/key&gt;
          &lt;true/&gt;
          &lt;key&gt;NSTemporaryExceptionAllowsInsecureHTTPLoads&lt;/key&gt;
          &lt;true/&gt;
          &lt;key&gt;NSTemporaryExceptionMinimumTLSVersion&lt;/key&gt;
          &lt;string&gt;1.0&lt;/string&gt;
          &lt;key&gt;NSTemporaryExceptionRequiresForwardSecrecy&lt;/key&gt;
          &lt;false/&gt;
      &lt;/dict&gt;
  &lt;/dict&gt;
  </code></pre>
  
  <p>Result of <code>curl -v</code></p>
  
  <pre>
  *   CAfile: /opt/local/share/curl/curl-ca-bundle.crt
    CApath: none
  * SSLv3, TLS handshake, Client hello (1):
  * SSLv3, TLS handshake, Server hello (2):
  * SSLv3, TLS handshake, CERT (11):
  * SSLv3, TLS handshake, Server key exchange (12):
  * SSLv3, TLS handshake, Server finished (14):
  * SSLv3, TLS handshake, Client key exchange (16):
  * SSLv3, TLS change cipher, Client hello (1):
  * SSLv3, TLS handshake, Finished (20):
  * SSLv3, TLS change cipher, Client hello (1):
  * SSLv3, TLS handshake, Finished (20):
  * SSL connection using TLSv1.2 / ECDHE-RSA-AES256-SHA384
  * Server certificate:
  *    subject: C=XXX; ST=XXX; L=XXX; O=XXX; CN=*.mydomain.com
  *    start date: 2015-08-17 00:00:00 GMT
  *    expire date: 2018-11-14 12:00:00 GMT
  *    subjectAltName: subdomain.mydomain.com matched
  *    issuer: C=US; O=DigiCert Inc; CN=DigiCert SHA2 Secure Server CA
  *    SSL certificate verify ok.
  </pre>
  
  <p>Result of <code>openssl s_client -connect</code></p>
  
  <pre>
  CONNECTED(00000003)
  depth=1 C = US, O = DigiCert Inc, CN = DigiCert SHA2 Secure Server CA
  verify error:num=20:unable to get local issuer certificate
  verify return:0
  ---
  Certificate chain
   0 s:/C=XXX/ST=XXX/L=XXX/O=XXX/CN=*.mydomain.com
     i:/C=US/O=DigiCert Inc/CN=DigiCert SHA2 Secure Server CA
   1 s:/C=US/O=DigiCert Inc/CN=DigiCert SHA2 Secure Server CA
     i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root CA
  ---
  Server certificate
  -----BEGIN CERTIFICATE-----
  .
  .
  .
  -----END CERTIFICATE-----
  subject=/C=XXX/ST=XXX/L=XXX/O=XXX/CN=*.mydomain.com
  issuer=/C=US/O=DigiCert Inc/CN=DigiCert SHA2 Secure Server CA
  ---
  No client certificate CA names sent
  ---
  SSL handshake has read 3033 bytes and written 490 bytes
  ---
  New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-SHA384
  Server public key is 2048 bit
  Secure Renegotiation IS supported
  Compression: NONE
  Expansion: NONE
  SSL-Session:
      Protocol  : TLSv1.2
      Cipher    : ECDHE-RSA-AES256-SHA384
      Session-ID: XXX
      Session-ID-ctx: 
      Master-Key: XXX
      Key-Arg   : None
      PSK identity: None
      PSK identity hint: None
      SRP username: None
      Start Time: 1454971371
      Timeout   : 300 (sec)
      Verify return code: 20 (unable to get local issuer certificate)
  ---
  </pre>