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 swift| var 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