However, I cannot get the settings to have any effect on iOS 14.3 (Xcode 12.3).
Using
example.org with URLSession, I would suggest a few things while testing this functionality:
1) When you make changes to your info.plist, it's good to delete the app and test with a fresh install. Just to make sure the evaluation is not running into TLS caching each time. For example, with example.org I tested the following on a fresh install and all was good:
Code Block xml<key>NSIncludesSubdomains</key> |
<true/> |
<key>NSPinnedCAIdentities</key> |
<array> |
<dict> |
<key>SPKI-SHA256-BASE64</key> |
<string>r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=</string> |
</dict> |
</array> |
I then altered the SPKI-SHA256-BASE64 to be the following and received a positive result:
Code Block xml<key>NSIncludesSubdomains</key> |
<true/> |
<key>NSPinnedCAIdentities</key> |
<array> |
<dict> |
<key>SPKI-SHA256-BASE64</key> |
<string>r/333mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=</string> |
</dict> |
</array> |
This is most likely due to TLS caching,
as described here, but it can be confusing.
Looking at another example like
www.apple.com. you can get a PEM copy of the CA certificate in the chain by using something like:
% openssl s_client -showcerts -connect www.apple.com:443. Note that I am using
www.apple.com:443 in this example because you may run into a situation where images.apple.com is given to you if you use apple.com:443.
In the output from openssl s_client you should be able to save the PEM encoded form of the root certificate. From there, run the command provided in the article to make a public key hash output of this certificate:
Code Block text% cat appleca.pem | openssl x509 -inform pem -noout -outform pem -pubkey | openssl pkey -pubin -inform pem -outform der | openssl dgst -sha256 -binary | openssl enc -base64 |
lwTPN61Qg5+1qAU+Mik9sFaDX5hLo2AHP80YR+IgN6M= |
From there add pin this as a NSPinnedCAIdentities against:
Code Block xml<key>NSAppTransportSecurity</key> |
<dict> |
<key>NSPinnedDomains</key> |
<dict> |
<key>apple.com</key> |
<dict> |
<key>NSIncludesSubdomains</key> |
<true/> |
<key>NSPinnedCAIdentities</key> |
<array> |
<dict> |
<key>SPKI-SHA256-BASE64</key> |
<string>lwTPN61Qg5+1qAU+Mik9sFaDX5hLo2AHP80YR+IgN6M=</string> |
</dict> |
</array> |
</dict> |
</dict> |
</dict> |
In your app then use the follow URLSession example with apple.com:
Code Block swiftvar config: URLSessionConfiguration = URLSessionConfiguration.default |
var urlSession = URLSession(configuration: config, delegate: self, delegateQueue: .main) |
|
... |
|
guard let url = URL(string: "https://apple.com") else { return } |
|
var urlRequest = URLRequest(url: url) |
urlRequest.httpMethod = "GET" |
|
let task = urlSession?.dataTask(with: urlRequest, completionHandler: { (data, response, error) in |
... |
}) |
task?.resume() |
Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com