So the question is, how can I configure my app so that it will trust the certificates from these terminals, but only at certain known possible local IP ranges?
As junkpile said, determining trust based on IP addresses is pretty pointless.
I mean, if a server is on the LAN, why can't we assume it's trusted (for crying out loud it's on the LAN).
You trust your WLAN? I don’t. There are a variety of ways that LANs might be attacked. For example:
There might be a compromised STA on the WLAN. Most APs don’t protect you from STA to STA attacks, for example, [ARP spoofing][refAs-Wtfe].
The AP itself might have been compromised. Based on recent news reports, the security of your average ISP-provided AP is quite dire.
https://en.wikipedia.org/wiki/ARP_spoofing
What I’d do in your situation is:
Configure the reader with a certificate that issued by a CA you control.
Bundle the CA’s root certificate in your app.
In your app, disable ATS; there’s some subtlety here, which I’ll cover below.
In your app, when you get the server trust authentication challenge, do your own trust evaluation; again, there’s some subtlety here which I’ll come back to later.
If that trust evaluation succeeds, allow the connection by resolving the challenge with
.UseCredential
; if not, deny it with .CancelAuthenticationChallenge
.
Running your own CA need not be difficult. Technote 2326 Creating Certificates for TLS Testing shows one simple approach. OTOH, if you’re dealing with financial transactions you may suffer from regulatory entanglements, which is not something I can advise you on.
On the subject of disabling ATS, ATS has no special affordance for local devices. For the backstory here, read this thread.
That leaves you with various options:
If the reader supports Bonjour, which it should, you could disable ATS for
local
and all its subdomains.You could use some sort of DNS-for-IP-address synthesiser.
If neither of the above work out, you will have to disable ATS globally for your app using
NSAllowsArbitraryLoads
.
WARNING In the last case you really should use
NSExceptionDomains
to re-enable ATS for any other domains used by your app. For example, if your app uses HTTPS to talk to some business logic web service, you want to make sure that that communication is protected by the enhanced security guaranteed by ATS.
On the subject of trust evaluation, there’s likely to be two sticking points here:
On the certificate authority front, you can use
SecTrustSetAnchorCertificates
to configure a trust object to trust your CA’s root certificate. Note that this implicitly disables trust for other root certificates (otherwise configured by
SecTrustSetAnchorCertificatesOnly
), which is what you’d want to do in this case. If you do configure the trust to use just your CA’s root certificate then, if the trust evaluates successfully, you know that the server holds a digital identity that was issued by your CA.
As far as trust policy is concerned, the trust object you get from the server trust authentication challenge will be set up to do standard (RFC 2818) TLS trust evaluation. Effectively it’s the policy you get back from
SecPolicyCreateSSL
. That checks that the server name you connect to matches the server name in the certificate. That’s probably too strict for your needs: that is, you don’t care which reader you’re talking to, as long as its a legitimate reader. As such, you need to disable the server name check. The simplest way to do that is to use the basic X.509 trust policy (as returned by
SecPolicyCreateBasicX509
).
OTOH, if you care which reader you’re talking to, you can tweak things to check that you’re talking to the right reader. For example, imagine you issued the reader 1 a certificate for the name “reader1”. To check that you’re talking to that reader, simply create an TLS trust policy with that name.
For more information about server trust evaluation, see Technote 2232 HTTPS Server Trust Evaluation.
Share and Enjoy
—
Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"