I have a local server running on Laravel Homestead:
https://laravel.com/docs/5.3/homestead
Homestead comes pre-packaged with an SSL certificate and I make all my requests through HTTPS. However, when trying to make a request from my iOS app, I get the following error:
ATS failed system trust
Connection 3: system TLS Trust evaluation failed(-9802)
Connection 3: TLS Trust encountered error 3:-9802
Connection 3: encountered error(3:-9802)
Task <892C4896-1D02-4465-AF06-D7534BE39828>.<1> HTTP load failed, 0/0 bytes (error code: -1200 [3:-9802])
Task <892C4896-1D02-4465-AF06-D7534BE39828>.<1> finished with error [-1200] Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, NSErrorPeerCertificateChainKey=(
"<cert(0x7fc76e82d800) s: mydomain.test i: Homestead homestead Root CA>"
)
I've added the following to my Info.plist:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsLocalNetworking</key>
<true/>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
After reading some articles and Github issues on SSL pinning through Alamofire and Moya, I've also done the following:
let evaluators: [String: ServerTrustEvaluating] = [
"mydomain.test": DisabledEvaluator()
]
let manager = ServerTrustManager(evaluators: evaluators)
let session = Session(serverTrustManager: manager)
let provider = MoyaProvider<T>(session: session, plugins: [NetworkLoggerPlugin(verbose: true)])
I also installed the certificate on my Mac and set it to "Always Trust", but I still get the error when I run my iOS app.
What am I doing wrong? What am I missing?
This is my solution, maybe not complete your question.
I don't use url as "myweb.local". I used direct IP and change port for app in developement. When you use port, you will not need to SSL.
Example:
127.0.0.1:8000
Related
I am developing a web service and iOS app that hits the web service on my local machine. At first, I disabled the cleartext errors for interacting with the service, but now I would like to use https so that my development, test, and prod environments are as similar as possible.
I installed my self-signed cert locally, so going to the site directly is using https just fine:
I have followed the instructions to install a cert in the iPhone simulator:
However, when I hit the web service on my local machine that uses this cert, I still get these error in the console:
2020-10-17 09:59:10.891496-0500 cttios[45481:2146304] [] nw_protocol_get_quic_image_block_invoke dlopen libquic failed
2020-10-17 09:59:10.899475-0500 cttios[45481:2146304] ATS failed system trust
2020-10-17 09:59:10.899583-0500 cttios[45481:2146304] Connection 1: system TLS Trust evaluation failed(-9802)
2020-10-17 09:59:10.899744-0500 cttios[45481:2146304] Connection 1: TLS Trust encountered error 3:-9802
2020-10-17 09:59:10.900077-0500 cttios[45481:2146304] Connection 1: encountered error(3:-9802)
2020-10-17 09:59:10.901405-0500 cttios[45481:2146304] Task <BE791070-705B-4C7D-A1DB-F57BCF1DFBCE>.<1> HTTP load failed, 0/0 bytes (error code: -1200 [3:-9802])
2020-10-17 09:59:10.904343-0500 cttios[45481:2146304] Task <BE791070-705B-4C7D-A1DB-F57BCF1DFBCE>.<1> finished with error [-1200] Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, NSErrorPeerCertificateChainKey=(
"<cert(0x7ff4ce854600) s: cttweb.test i: Homestead homestead Root CA>"
), NSErrorClientCertificateStateKey=0, NSErrorFailingURLKey=https://cttweb.test/api/v1/login, NSErrorFailingURLStringKey=https://cttweb.test/api/v1/login, NSUnderlyingError=0x600001123ab0 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x600002d55cb0>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, kCFStreamPropertySSLPeerCertificates=(
"<cert(0x7ff4ce854600) s: cttweb.test i: Homestead homestead Root CA>"
)}}, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask <BE791070-705B-4C7D-A1DB-F57BCF1DFBCE>.<1>"
), _kCFStreamErrorCodeKey=-9802, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <BE791070-705B-4C7D-A1DB-F57BCF1DFBCE>.<1>, NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x600002d55cb0>, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made.}
Login api error: An SSL error has occurred and a secure connection to the server cannot be made.
Optional(["task": ["Login api error: An SSL error has occurred and a secure connection to the server cannot be made."]])
I have tried restarting the simulator after installing the cert, same result. What am I doing wrong?
It looks like I may not be trusting the cert even after installing it, but I can't find a way to trust it.
The problem is that I had the website cert installed, but not the CA cert generated for my local web server installed. That was as easy as dragging the CA root cert into Safari on the simulator.
I am displaying a web site in my iOS app (user's profile) that contains an option to purchase some services. The purchase is done inside the UIWebView by opening a third party payment page inside an iframe.
When trying to load this payment page, an SSL error is sent to webView:didFailLoadWithError: delegate method.
The SSL error:
Error Domain=NSURLErrorDomain Code=-1200 \"An SSL error has occurred and a secure connection to the server cannot be made.\" UserInfo={_kCFStreamErrorCodeKey=-9806, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, NSUnderlyingError=0x610000255c90 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 \"An SSL error has occurred and a secure connection to the server cannot be made.\" UserInfo={NSErrorFailingURLStringKey=https://SOME-URL, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFNetworkCFStreamSSLErrorOriginalValue=-9806, _kCFStreamPropertySSLClientCertificateState=0, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., _kCFStreamErrorDomainKey=3, NSErrorFailingURLKey=https://SOME-URL, _kCFStreamErrorCodeKey=-9806}}, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://SOME-URL, NSErrorFailingURLStringKey=https://SOME-URL, _kCFStreamErrorDomainKey=3}
I have tested this URL in a browser and I see that it uses TLSv1.2 so I don't understand what is the problem.
The same iframe works as expected in iOS Safari and in an Android app...
When I disable ATS (NSAppTransportSecurity) in the Info.plist then the payment page is displayed, but I'm afraid that Apple won't allow it is the AppStore (and I don't want to do it - it's a payment page and it should be secure).
This is the payment URL:
https://cgmpi.creditguard.co.il/CGMPI_Server/PerformTransaction?txId=a51270b0-9cb5-43aa-83cc-1cb0abe08691
I would put an exception regarding the webviews, the domain and the TLS version in the Info.plist to make sure that the ATS layer won't block any connection.
Something like this:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoadsInWebContent</key>
<true/>
<key>NSExceptionDomains</key>
<dict>
<key>creditguard.co.il</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSExceptionMinimumTLSVersion</key>
<string>TLSv1.2</string>
</dict>
</dict>
</dict>
I get the following error message (which is identical every try)
2016-07-20 20:09:28.013 MyApp[1140:374263] CFNetwork SSLHandshake failed (-9806)
2016-07-20 20:09:28.014 MyApp[1140:374263] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9806)
error=Optional(Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={_kCFStreamErrorCodeKey=-9806, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, NSUnderlyingError=0x154dda750 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, _kCFNetworkCFStreamSSLErrorOriginalValue=-9806, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9806}}, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://example.com:8080/api/login, NSErrorFailingURLStringKey=https://example.com:8080/api/login, _kCFStreamErrorDomainKey=3})
The certificate is a validated one provided by letsencrypt. I have tested my web server configuration over and over, and everything seems to be like it should.
Running the command openssl s_client -connect example.com:8080/api/login -tls1_2 gives all the expected results:
-It verifies the authority as DST Root CA X3, which is included in Apples root CA list
-The return is code is Verify return code: 0 (ok)
I have also run several ssl diagnostic tool websites such as digicert, which has given no error results.
I can load the domain from Safari ON the iOS device, as well as chrome from my computer without having to accept "untrusted certificates".
Any suggestions?
In case anyone encounter something the same problem, ill answer my own question.
At the time of the question, Let's Encrypt (the CA of the certificate used) did not support forward secrecy for their https certificates (atleast not the one I got). Apple by default required this in the iOS version used at that time (I believe it was around 9.5, but I might be mistaken here).
To get around the requirement of forward secrecy, this can be specified in the Info.plist under domain exceptions.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>example.com</key>
<dict>
<key>NSTemporaryExceptionRequiresForwardSecrecy</key>
<false/>
</dict>
</dict>
</dict>
Sometime along the road, they changed this to default land on false. I am not sure when this was, but after iOS 10.0 it was never a problem.
I am trying to download a file using NSURLSessionDownloadDelegate in Swift.But when I call the download method its showing the below error frequently.
Error Domain=NSURLErrorDomain Code=-1202 "The operation couldn’t be completed. (NSURLErrorDomain error -1202.)" UserInfo=0x7fbac2dd2f60 {NSErrorFailingURLStringKey=https://dl.dropboxusercontent.com/content_link/EvFVp1WYxrW15Vy6kfUGIChdHy4HVhatT0p6iQhhG24wzNsQ48CEDs0shjmTbCWb/file?dl=1, NSErrorFailingURLKey=https://dl.dropboxusercontent.com/content_link/EvFVp1WYxrW15Vy6kfUGIChdHy4HVhatT0p6iQhhG24wzNsQ48CEDs0shjmTbCWb/file?dl=1, NSURLErrorFailingURLPeerTrustErrorKey=, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9813, NSUnderlyingError=0x7fbac2ca07e0 "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error -1202.)"}
I tried to edit the info.plist but its not working.
Did you add arbitrary loads for ATS (Apple Transport Security) like:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Please note that this is unsafe, you may want to customize your ATS rules by domain like:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>dl.dropboxusercontent.com</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
</dict>
</dict>
</dict>
[UPDATE]
If we look better at the error we can see the key
NSURLErrorFailingURLPeerTrustErrorKey
Then a tech note by Apple about HTTPS Server Trust Evaluation may help.
Going though the docs we read
Domain=NSURLErrorDomain Code=-1202 "The certificate for this server is
invalid. You might be connecting to a server that is pretending to be
“example.com” which could put your confidential information at risk."
UserInfo=0x14a730 {NSErrorFailingURLStringKey=https://example.com/,
NSLocalizedRecoverySuggestion=Would you like to connect to the server
anyway?, NSErrorFailingURLKey=https://example.com/,
NSLocalizedDescription=The certificate for this server is invalid. You
might be connecting to a server that is pretending to be “example.com”
which could put your confidential information at risk.,
NSUnderlyingError=0x14a6c0 "The certificate for this server is
invalid. You might be connecting to a server that is pretending to be
“example.com” which could put your confidential information at risk.",
NSURLErrorFailingURLPeerTrustErrorKey=}
Well, that's pretty that one, since the error -1202 in the NSURLErrorDomain domain is NSURLErrorServerCertificateUntrusted, due to a possibile issue with TSL.
So we need to check TSL at this point:
We check the certs via CLI:
$ openssl s_client -showcerts -host dl.dropboxusercontent.com -port 443
CONNECTED(00000003)
depth=2 /C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
0 s:/OU=Domain Control Validated/CN=dl.dropboxusercontent.com
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
---
Server certificate
subject=/OU=Domain Control Validated/CN=dl.dropboxusercontent.com
issuer=/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2
---
No client certificate CA names sent
---
SSL handshake has read 4569 bytes and written 456 bytes
---
New, TLSv1/SSLv3, Cipher is AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : AES256-SHA
Session-ID:
Session-ID-ctx:
Master-Key: 50414926328455F36215516BEB0C40F1DD512C3C0989E0C090DC9277E754B35EFF0CE3AEA4D3FB524FFE071BE2D4426C
Key-Arg : None
Start Time: 1447281208
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
closed
and we can see here that this domain supports TLSv1/SSLv3,
We can do this online using SSL Server Test by SSL Quality Labs with the same good results here.
My wonder is if this issue is a duplicate of A couple users getting NSURLErrorServerCertificateUntrusted
But with the TSL checks above we can clearly see that the domain in question was ok.
So (simple) question
Did your phone time and date were correct?
I'm testing an app in iOS9 and getting SSL errors with ATS loading images from amazon.com. All my stuff is being delivered over https but I'm still having issues.
I've added the correct ATS keys (worked on another app).
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>amazonaws.com</key>
<dict>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>
I've been all over the forums, adc, and SO and I'm not having any luck.
I've tried removing ATS entirely, and I still get the same error.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Error:
NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)
Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, NSErrorPeerCertificateChainKey={type = immutable, count = 3, values = (
0 :
1 :
2 :
)}, NSUnderlyingError=0x7ffe70e2c690 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSErrorFailingURLStringKey=https://redacted.s3.amazonaws.com/14B78421-84F1-48D1-A8F4-73B688102EE7-21502-00003598C1B6C883_thumbnail.jpg, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, kCFStreamPropertySSLPeerCertificates={type = immutable, count = 3, values = (
0 :
1 :
2 :
)}, _kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., _kCFStreamErrorDomainKey=3, NSErrorFailingURLKey=https://redacted.s3.amazonaws.com/14B78421-84F1-48D1-A8F4-73B688102EE7-21502-00003598C1B6C883_thumbnail.jpg, _kCFStreamErrorCodeKey=-9802}}, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://redacted.s3.amazonaws.com/14B78421-84F1-48D1-A8F4-73B688102EE7-21502-00003598C1B6C883_thumbnail.jpg, NSErrorFailingURLStringKey=https://redacted.s3.amazonaws.com/14B78421-84F1-48D1-A8F4-73B688102EE7-21502-00003598C1B6C883_thumbnail.jpg, NSErrorClientCertificateStateKey=0}
Static files: AWS Amazon
Host: Heroku
Backend: Django
APIs: Django Rest Framework
I've tried every configuration I could find on ATS, cleaned/reset/rebuilt, modified the Django requests (originally they included querystring authentication), etc. I'm stumped on this and blocked.
After I did a substring replace on https links -- I got the messages saying ATS was blocking them. I knew I had the correct keys in the Info.plist - so I figured it had to be another Info.plist somewhere.
It turns out that the there was an Info.plist in the resources but it wasn't doing anything. We had to add the ATS keys to the Info tab on the Target panel. Not 100% sure what the difference is on these two as I've always edited the Info.plist in the past.
I had to add amazonaws.com to Info.plist like you did and to user the SDWebImageAllowInvalidSSLCertificates as an option for the sd_setImageWithURL: method to get it working.