Hi
I have an iOS 10 (only) app. The app needs to be able to support the use of self-signed certifcates for IP addresses i.e https://192.168.2.1 in a "test" mode. The IP addresses and certifcates are spawned virtual servers and they don't have access to a DNS or a certificate authority, importantly they are for testing only.
In the app info.plist I have the following entry:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>If the app is in "test" mode, this is the code that gets executed:
class AllowSelfSignedCertificate: NSObject, URLSessionDelegate
{
private func urlSession(session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: (NSURLSession.AuthChallengeDisposition, URLCredential?) -> Void)
{
completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))
}
}
if mode == OperationMode.test
{
let session = URLSession(configuration: URLSessionConfiguration.ephemeral, delegate: AllowSelfSignedCertificate(), delegateQueue: nil)
}When I run the app in "test" mode I get the following error:
The certificate for this server is invalid. You might be connecting to a server that is pretending to be "192.168.2.1" which could put your confidential information
at riskWhen I connect the app to the same network as the test server and include NSAllowsLocalNetworking, I get the same error. Following is the output of nsurl:
nscurl --ats-diagnostics https:/
Starting ATS Diagnostics
Configuring ATS Info.plist keys and displaying the result of HTTPS loads to https:/
A test will "PASS" if URLSession:task:didCompleteWithError: returns a nil error.
Use '--verbose' to view the ATS dictionaries used and to display the error received in URLSession:task:didCompleteWithError:.
================================================================================
Default ATS Secure Connection
---
ATS Default Connection
2016-12-28 14:52:50.763 nscurl[36062:6500411] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9824)
Result : FAIL
---
================================================================================
Allowing Arbitrary Loads
---
Allow All Loads
2016-12-28 14:52:50.794 nscurl[36062:6500411] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)
Result : FAIL
---
================================================================================
Configuring TLS exceptions for 192.168.2.1
---
TLSv1.2
2016-12-28 14:52:50.830 nscurl[36062:6500411] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9824)
Result : FAIL
---
---
TLSv1.1
2016-12-28 14:52:50.868 nscurl[36062:6500411] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9824)
Result : FAIL
---
---
TLSv1.0
2016-12-28 14:52:50.934 nscurl[36062:6500411] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9824)
Result : FAIL
---
================================================================================
Configuring PFS exceptions for 192.168.2.1
---
Disabling Perfect Forward Secrecy
2016-12-28 14:52:50.948 nscurl[36062:6500411] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)
Result : FAIL
---
================================================================================
Configuring PFS exceptions and allowing insecure HTTP for 192.168.2.1
---
Disabling Perfect Forward Secrecy and Allowing Insecure HTTP
2016-12-28 14:52:50.959 nscurl[36062:6500411] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)
Result : FAIL
---
================================================================================
Configuring TLS exceptions with PFS disabled for 192.168.2.1
---
TLSv1.2 with PFS disabled
2016-12-28 14:52:50.971 nscurl[36062:6500411] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)
Result : FAIL
---
---
TLSv1.1 with PFS disabled
2016-12-28 14:52:50.980 nscurl[36062:6500411] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)
Result : FAIL
---
---
TLSv1.0 with PFS disabled
2016-12-28 14:52:50.990 nscurl[36062:6500411] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)
Result : FAIL
---
================================================================================
Configuring TLS exceptions with PFS disabled and insecure HTTP allowed for 192.168.2.1
---
TLSv1.2 with PFS disabled and insecure HTTP allowed
2016-12-28 14:52:51.022 nscurl[36062:6500411] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)
Result : FAIL
---
---
TLSv1.1 with PFS disabled and insecure HTTP allowed
2016-12-28 14:52:51.041 nscurl[36062:6500411] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)
Result : FAIL
---
---
TLSv1.0 with PFS disabled and insecure HTTP allowed
2016-12-28 14:52:51.052 nscurl[36062:6500411] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)
Result : FAIL
---When I run openssl -s_client, this is the output (certificate information omitted)
openssl s_client -connect 192.168.2.1:443
CONNECTED(00000003)
verify error:num=18:self signed certificate
verify return:1
---
No client certificate CA names sent
---
SSL handshake has read 979 bytes and written 456 bytes
---
New, TLSv1/SSLv3, Cipher is AES128-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : AES128-SHA
Session-ID: BC8C61C53D3BBBC9CEAEA468BCC54FA4C494C43192274A48E4195A80FDB36EDC
Session-ID-ctx:
Master-Key: 511F32CC76D8D7C457003B1042D9E678E159DC653D1F8AE844E6EA9A280727D0BA41E6329FFECFE628C1B8CC41EF71A0
Key-Arg : None
Start Time: 1482901084
Timeout : 300 (sec)
Verify return code: 18 (self signed certificate)
---
read:errno=0What ATS configuration should I adopt in the app to enable http://<ip_address> in a test operation mode?
Thanks for your help
Is it your opinion, that I should remove the NSAppTransportSecurity stanza from info.plist and to manually get the self-signed certifcate onto the test device to prevent having to handle URLSessionDelegate?
Yes. Writing code to override HTTPS server trust evaluation is extra work and it carries with it significant security riks. If you can avoid doing so, you should.
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"