In the last couple of months I have found myself in situations where I have needed to diagnose transport security issues from from the context of an iOS application. This often can be difficult from the client side perspective as you may not know anything about the minimum TLS version, preferred cipher suite, or the certificate in use on the server. Often, the best move you have, if you do not have a direct line to the server side team, is to test different settings to diagnose what works and what does not. Then confirm your successful tests and transport setting with the server side team when they are available. Well, in debugging these types of issues I discovered the nscurl tool available in macOS. And that is why I wanted to write this tutorial, to provide a brief explanation on how to use nscurl, and what it can be used for.
NOTE: This tutorial was written and test on macOS version 10.13.5 beta, but should work on any macOS 10.13 version of the operating system as well. I have not tested this on anything below 10.13.
Using the nscurl Utility 🚀
If you are on OS X El Capitan or later then you most likely have the nscurl utility at your disposal. To test this out, go to the terminal and type in the following command: $ /usr/bin/nscurl -h and you should see a set of options like the one in the screen shot below along with the usage pattern set as $ nscurl [options... ] <URL>.
So how can this help you diagnose app transport security issues or TLS issues? Well, pointing this tool at a URL and running it with the --ats-diagnostics option will provide you the exact information on what version of TLS is configured and whether or not perfect forward secrecy is enable for the secure communication between your application and the server.
So running nscurl with the --ats-diagnostics option against www.agnosticdev.com will produce the results of of what version of TLS the server can communicate with. In the screen shot notice that TLS 1.0, 1.1, and 1.2 all pass, but 1.3 fails with a -9800 kCFStreamErrorDomainSSL error. Meaning that TLS 1.3 is not configured yet but are 1.0, 1.1, and 1.2 are all configured and ready to use.
$ /usr/bin/nscurl --ats-diagnostics https://www.agnosticdev.com
Next let's take a look at the PFS results, or better known as perfect forward secrecy. Perfect forward secrecy is a security mechanism in secure communication that ensures that if current or future session is compromised that this does not also compromise past sessions, and thus the name "forward secrecy."
The results displayed in the screen shot below are testing with nscurl against agnosticdev.com where the TLS version is set to a specific version and PFS flag is disabled. Thus testing whether your version of TLS supports PFS running with disabled. The results in the screen shot indicate that all versions of supported TLS can also support PFS disabled. So, the results below would indicate that the following App Transport Security settings would be valid to use in your app:
<key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>agnosticdev.com</key> <dict> <key>NSExceptionRequiresForwardSecrecy</key> <false/> <key>NSExceptionMinimumTLSVersion</key> <string>TLSv1.2</string> </dict> </dict> </dict>
Alternative Approach 👍
One other alternative approach if you are on a unix machine is to use the openssl s_client tool suite to validate options about a remote cert or a SSL/TLS setup. This can be very helpful for use cases outside of macOS, on Linux, where you do not have nscurl at your disposal. In fact, openssl may provide you more granular information about the cipher suites and the certificate authority in use on the remote server than nscurl does. If I had to guess also, nscurl is most likely using openssl under the hood too. (Again, that is just a guess)
$ openssl s_client -showcerts -connect www.agnosticdev.com:443
In Summary ⌛️
In summary I hope this tutorial has been helpful if you are struggling with what the best possible option is to configure for App Transport Security in your application. These settings can be a bit confusing at times, so it is always best to go right to the source if you can and test the remote SSL/TLS communication back to the client. Please leave a comment if you have any questions comments or concerns, and I will try and get back to you as soon as possible. Thank you!