Sara
Sara

Reputation: 11

Can't connect to https://test.salesforce.com with ios9

With iOS 9's improved security we are not able to connect to https://test.salesforce.com

We get

NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9824)

which based on SecureTransport.h is related to a handshake failure

errSSLPeerHandshakeFail     = -9824,    /* handshake failure */

We can disable security and still connect (using NSAllowsArbitraryLoads) but we would prefer to use the new more secure ios features.

We tried making an exception just for Salesforce but still get same error

<key>NSExceptionDomains</key>
    <dict>
            <key>salesforce.com</key>
            <dict>
                    <key>NSExceptionMinimumTLSVersion</key>
                    <string>TLSv1.0</string>
                    <key>NSExceptionRequiresForwardSecrecy</key>
                    <false/>
                    <key>NSIncludesSubdomains</key>
                    <true/>
            </dict>
    </dict>

edit(to add a question): What is the best way to make requests from ios apps to https://test.salesforce.com as securely as possible? (Do I need to wait for Salesforce to update their certificates? Or is there something more under my control?)

Upvotes: 1

Views: 475

Answers (2)

Nicolas Miari
Nicolas Miari

Reputation: 16256

I ran the nscurl command line utility on the OAuth 2.0 endpoint (ROPC flow, sandbox environment):

nscurl --ats-diagnostics --verbose https://test.salesforce.com/services/oauth2/token

TL; DR:

I found out that the most secure setup that will PASS is the following:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>salesforce.com</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSExceptionRequiresForwardSecrecy</key>
            <false/>
        </dict>
    </dict>
</dict>

(No need to lower the minimum required TLS version. Also, Salesforce is dropping support for TLS 1.0)

The full results of the nscurl diagnostic:

Starting ATS Diagnostics

Configuring ATS Info.plist keys and displaying the result of HTTPS loads to https://test.salesforce.com/services/oauth2/token.
A test will "PASS" if URLSession:task:didCompleteWithError: returns a nil error.
================================================================================

Default ATS Secure Connection
---
ATS Default Connection
ATS Dictionary:
{
}
2016-06-17 10:49:21.533 nscurl[975:53055] CFNetwork SSLHandshake failed (-9824)
2016-06-17 10:49:21.533 nscurl[975:53055] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9824)
Result : FAIL
Error : Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={_kCFStreamErrorCodeKey=-9824, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, NSUnderlyingError=0x7fd67d100230 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, _kCFNetworkCFStreamSSLErrorOriginalValue=-9824, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9824}}, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://test.salesforce.com/services/oauth2/token, NSErrorFailingURLStringKey=https://test.salesforce.com/services/oauth2/token, _kCFStreamErrorDomainKey=3}
---

================================================================================

Allowing Arbitrary Loads

---
Allow All Loads
ATS Dictionary:
{
    NSAllowsArbitraryLoads = true;
}
Result : PASS
---

================================================================================

Configuring TLS exceptions for test.salesforce.com

---
TLSv1.2
ATS Dictionary:
{
    NSExceptionDomains =     {
        "test.salesforce.com" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.2";
        };
    };
}
2016-06-17 10:49:21.760 nscurl[975:53055] CFNetwork SSLHandshake failed (-9824)
2016-06-17 10:49:21.760 nscurl[975:53055] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9824)
Result : FAIL
Error : Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={_kCFStreamErrorCodeKey=-9824, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, NSUnderlyingError=0x7fd67d000aa0 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, _kCFNetworkCFStreamSSLErrorOriginalValue=-9824, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9824}}, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://test.salesforce.com/services/oauth2/token, NSErrorFailingURLStringKey=https://test.salesforce.com/services/oauth2/token, _kCFStreamErrorDomainKey=3}
---

---
TLSv1.1
ATS Dictionary:
{
    NSExceptionDomains =     {
        "test.salesforce.com" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.1";
        };
    };
}
2016-06-17 10:49:21.817 nscurl[975:53055] CFNetwork SSLHandshake failed (-9824)
2016-06-17 10:49:21.817 nscurl[975:53055] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9824)
Result : FAIL
Error : Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={_kCFStreamErrorCodeKey=-9824, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, NSUnderlyingError=0x7fd67b49bf10 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, _kCFNetworkCFStreamSSLErrorOriginalValue=-9824, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9824}}, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://test.salesforce.com/services/oauth2/token, NSErrorFailingURLStringKey=https://test.salesforce.com/services/oauth2/token, _kCFStreamErrorDomainKey=3}
---

---
TLSv1.0
ATS Dictionary:
{
    NSExceptionDomains =     {
        "test.salesforce.com" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.0";
        };
    };
}
2016-06-17 10:49:21.878 nscurl[975:53055] CFNetwork SSLHandshake failed (-9824)
2016-06-17 10:49:21.879 nscurl[975:53055] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9824)
Result : FAIL
Error : Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={_kCFStreamErrorCodeKey=-9824, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, NSUnderlyingError=0x7fd67d1002c0 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, _kCFNetworkCFStreamSSLErrorOriginalValue=-9824, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9824}}, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://test.salesforce.com/services/oauth2/token, NSErrorFailingURLStringKey=https://test.salesforce.com/services/oauth2/token, _kCFStreamErrorDomainKey=3}
---

================================================================================

Configuring PFS exceptions for test.salesforce.com

---
Disabling Perfect Forward Secrecy
ATS Dictionary:
{
    NSExceptionDomains =     {
        "test.salesforce.com" =         {
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

================================================================================

Configuring PFS exceptions and allowing insecure HTTP for test.salesforce.com

---
Disabling Perfect Forward Secrecy and Allowing Insecure HTTP
ATS Dictionary:
{
    NSExceptionDomains =     {
        "test.salesforce.com" =         {
            NSExceptionAllowsInsecureHTTPLoads = true;
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

================================================================================

Configuring TLS exceptions with PFS disabled for test.salesforce.com

---
TLSv1.2 with PFS disabled
ATS Dictionary:
{
    NSExceptionDomains =     {
        "test.salesforce.com" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.2";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

---
TLSv1.1 with PFS disabled
ATS Dictionary:
{
    NSExceptionDomains =     {
        "test.salesforce.com" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.1";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

---
TLSv1.0 with PFS disabled
ATS Dictionary:
{
    NSExceptionDomains =     {
        "test.salesforce.com" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.0";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

================================================================================

Configuring TLS exceptions with PFS disabled and insecure HTTP allowed for test.salesforce.com

---
TLSv1.2 with PFS disabled and insecure HTTP allowed
ATS Dictionary:
{
    NSExceptionDomains =     {
        "test.salesforce.com" =         {
            NSExceptionAllowsInsecureHTTPLoads = true;
            NSExceptionMinimumTLSVersion = "TLSv1.2";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

---
TLSv1.1 with PFS disabled and insecure HTTP allowed
ATS Dictionary:
{
    NSExceptionDomains =     {
        "test.salesforce.com" =         {
            NSExceptionAllowsInsecureHTTPLoads = true;
            NSExceptionMinimumTLSVersion = "TLSv1.1";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

---
TLSv1.0 with PFS disabled and insecure HTTP allowed
ATS Dictionary:
{
    NSExceptionDomains =     {
        "test.salesforce.com" =         {
            NSExceptionAllowsInsecureHTTPLoads = true;
            NSExceptionMinimumTLSVersion = "TLSv1.0";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

================================================================================

Upvotes: 1

Wombat
Wombat

Reputation: 1

To continue down the path of making an exception, try adding force.com to the exception list (instead of only salesforce.com) So... add this as another exception key:

<key>NSExceptionDomains</key>
    <dict>
            <key>force.com</key>
            <dict>
                    <key>NSExceptionMinimumTLSVersion</key>
                    <string>TLSv1.0</string>
                    <key>NSExceptionRequiresForwardSecrecy</key>
                    <false/>
                    <key>NSIncludesSubdomains</key>
                    <true/>
            </dict>
    </dict>

I also await a more permanent solution.

Upvotes: 0

Related Questions