So I know the ATS stuff and how to edit the info.plist to allow HTTP. However, the URL is https://api.map.baidu.com/api?v=2. 0&ak=1XjLLEhZhQNUzd93EjU5nOGQ&s=1, which is a HTTPS request, but I still get
NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)
Then I add setenv("CFNETWORK_DIAGNOSTICS", "3", 1);
in didFinishLaunchingWithOptions
to enable verbose log.
In the log, I find the error log:
5510 Jan 14 10:52:01 MCompass[8549] <Notice>: CFNetwork Diagnostics [3:363] 10:52:01.458 {
5511 Response Error
5512 Request: <CFURLRequest 0x7fecf3cddcb0 [0x10aff37b0]> {url = https://api.map.baidu.com/api?v=2.0&ak=1XjLLEhZhQNUzd93EjU5nOGQ&s=1, cs = 0x0}
5513 Error: Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x7fecf406bbf0>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, kCFStreamPropertySSLPeerCertificates=<CFArray 0x7fecf406cda0 [0x10aff37b0]>{type = immutable, count = 3, values = (
5514 0 : <cert(0x7fecf3fa80e0) s: baidu.com i: VeriSign Class 3 International Server CA - G3>
5515 1 : <cert(0x7fecf3fa8920) s: VeriSign Class 3 International Server CA - G3 i: VeriSign Class 3 Public Primary Certification Authority - G5>
5516 2 : <cert(0x7fecf4069fd0) s: VeriSign Class 3 Public Primary Certification Authority - G5 i: Class 3 Public Primary Certification Authority>
5517 )}}
5518 } [3:363]
5519 Jan 14 10:52:01 MCompass[8549] <Notice>: CFNetwork Diagnostics [3:364] 10:52:01.459 {
5520 Did Fail
5521 Loader: <CFMutableURLRequest 0x7fecf3cdd9f0 [0x10aff37b0]> {url = https://api.map.baidu.com/api?v=2.0&ak=1XjLLEhZhQNUzd93EjU5nOGQ&s=1, cs = 0x0}
5522 Error: Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x7fecf406bbf0>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, kCFStreamPropertySSLPeerCertificates=<CFArray 0x7fecf406cda0 [0x10aff37b0]>{type = immutable, count = 3, values = (
5523 0 : <cert(0x7fecf3fa80e0) s: baidu.com i: VeriSign Class 3 International Server CA - G3>
5524 1 : <cert(0x7fecf3fa8920) s: VeriSign Class 3 International Server CA - G3 i: VeriSign Class 3 Public Primary Certification Authority - G5>
5525 2 : <cert(0x7fecf4069fd0) s: VeriSign Class 3 Public Primary Certification Authority - G5 i: Class 3 Public Primary Certification Authority>
5526 )}}
5527 init to origin load: 0.00280595s
5528 total time: 0.447458s
5529 total bytes: 0
5530 } [3:364]
I am confused, because it's HTTPS request, but still have the issue. I tried the URL on Chrome, it is returning a valid cert (I have the cert knowledge like X509). But cannot figure out why it is blocked.
Could someone help? Thank in advance. Add this domain into ATS exceptions will help, but I don't want to add it, because it's HTTPS already!
UPDATE:
Running
/usr/bin/nscurl --ats-diagnostics -v "https://api.map.baidu.com/api?v=2.0&ak=1XjLLEhZhQNUzd93EjU5nOGQ&s=1"
Will return ALL PASS:
Xuans-MacBook-Pro:~ xuan$ /usr/bin/nscurl --ats-diagnostics -v "https://api.map.baidu.com/api?v=2.0&ak=1XjLLEhZhQNUzd93EjU5nOGQ&s=1"
Starting ATS Diagnostics
Configuring ATS Info.plist keys and displaying the result of HTTPS loads to https://api.map.baidu.com/api?v=2.0&ak=1XjLLEhZhQNUzd93EjU5nOGQ&s=1.
A test will "PASS" if URLSession:task:didCompleteWithError: returns a nil error.
================================================================================
Default ATS Secure Connection
---
ATS Default Connection
ATS Dictionary:
{
}
Result : PASS
---
================================================================================
Allowing Arbitrary Loads
---
Allow All Loads
ATS Dictionary:
{
NSAllowsArbitraryLoads = true;
}
Result : PASS
---
================================================================================
Configuring TLS exceptions for api.map.baidu.com
---
TLSv1.2
ATS Dictionary:
{
NSExceptionDomains = {
"api.map.baidu.com" = {
NSExceptionMinimumTLSVersion = "TLSv1.2";
};
};
}
Result : PASS
---
---
TLSv1.1
ATS Dictionary:
{
NSExceptionDomains = {
"api.map.baidu.com" = {
NSExceptionMinimumTLSVersion = "TLSv1.1";
};
};
}
Result : PASS
---
---
TLSv1.0
ATS Dictionary:
{
NSExceptionDomains = {
"api.map.baidu.com" = {
NSExceptionMinimumTLSVersion = "TLSv1.0";
};
};
}
Result : PASS
---
================================================================================
Configuring PFS exceptions for api.map.baidu.com
---
Disabling Perfect Forward Secrecy
ATS Dictionary:
{
NSExceptionDomains = {
"api.map.baidu.com" = {
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
================================================================================
Configuring PFS exceptions and allowing insecure HTTP for api.map.baidu.com
---
Disabling Perfect Forward Secrecy and Allowing Insecure HTTP
ATS Dictionary:
{
NSExceptionDomains = {
"api.map.baidu.com" = {
NSExceptionAllowsInsecureHTTPLoads = true;
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
================================================================================
Configuring TLS exceptions with PFS disabled for api.map.baidu.com
---
TLSv1.2 with PFS disabled
ATS Dictionary:
{
NSExceptionDomains = {
"api.map.baidu.com" = {
NSExceptionMinimumTLSVersion = "TLSv1.2";
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
---
TLSv1.1 with PFS disabled
ATS Dictionary:
{
NSExceptionDomains = {
"api.map.baidu.com" = {
NSExceptionMinimumTLSVersion = "TLSv1.1";
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
---
TLSv1.0 with PFS disabled
ATS Dictionary:
{
NSExceptionDomains = {
"api.map.baidu.com" = {
NSExceptionMinimumTLSVersion = "TLSv1.0";
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
================================================================================
Configuring TLS exceptions with PFS disabled and insecure HTTP allowed for api.map.baidu.com
---
TLSv1.2 with PFS disabled and insecure HTTP allowed
ATS Dictionary:
{
NSExceptionDomains = {
"api.map.baidu.com" = {
NSExceptionAllowsInsecureHTTPLoads = true;
NSExceptionMinimumTLSVersion = "TLSv1.2";
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
---
TLSv1.1 with PFS disabled and insecure HTTP allowed
ATS Dictionary:
{
NSExceptionDomains = {
"api.map.baidu.com" = {
NSExceptionAllowsInsecureHTTPLoads = true;
NSExceptionMinimumTLSVersion = "TLSv1.1";
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
---
TLSv1.0 with PFS disabled and insecure HTTP allowed
ATS Dictionary:
{
NSExceptionDomains = {
"api.map.baidu.com" = {
NSExceptionAllowsInsecureHTTPLoads = true;
NSExceptionMinimumTLSVersion = "TLSv1.0";
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
================================================================================
As discussed on this answer, by simply accessing your API url by HTTPS does not mean it will comply with Apple's ATS. I also use nscurl
, but I believe the tool has not yet matured enough and may be quite inefficient at times.
SSL Labs test is far more better and detailed, imho. It will help you track down what's lacking in your SSL configuration.
Note that ATS requires TLS 1.2 at minimum and Perfect Forward Secrecy cipher suites.