I'm trying to set up an NWConnection that does client side certs:
self.connection = NWConnection(
host: NWEndpoint.Host("servername"),
port: NWEndpoint.Port(integerLiteral: 8899),
using: .tls)
But I think that simple .tls
class var needs to be a much more involved NWParameters
object, but I'm at a complete loss (documentation is pretty sparse) as to what I create there to attach the client certs to the parameters. Nor do I know how I even move from .crt/.pem file to something the app manages programatically.
What is an example of how one would configure the NWParameters
to support the client certs?
I'm trying to set up a client connection to communicate with an MQTT broker using client side certificates. I've been able to proof-of-concept this all on the Linux side using command line. The MQTT broker is set to require client cert, and a command like:
mosquitto_pub -h servername -p 8899 -t 1234/2/Q/8 -m myMessage --cafile myChain.crt --cert client.crt --key client.pem
does the job nicely. But OpenSSL is enough a black box (to me) on iOS that I don't know where to go from here. I have been able to get all of the other MQTT communications work with my NWConnection
instances, including server side TLS and even if it's self signed.
The kind folks on the Apple Developer Forums helped work this out. On iOS you have to use the p12 import ability:
let importOptions = [ kSecImportExportPassphrase as String: "" ]
var rawItems: CFArray?
let status = SecPKCS12Import(P12Data as CFData, importOptions as CFDictionary, &rawItems)
let items = rawItems! as! Array<Dictionary<String, Any>>
let firstItem = items[0]
let clientIdentity = firstItem[kSecImportItemIdentity as String]! as! SecIdentity
print("clientIdentity \(clientIdentity)")
Now that one has an identity, you can use that to configure the securityProtocolOptions
of the the TLS options:
let options = NWProtocolTLS.Options()
sec_protocol_options_set_local_identity(options.securityProtocolOptions, sec_identity_create(clientIdentity)!)
sec_protocol_options_set_challenge_block(options.securityProtocolOptions, { (_, completionHandler) in
completionHandler(sec_identity_create(clientIdentity)!)
}, .main)
let parameters = NWParameters(tls: options) // use this in the NWConnection creation
For reference, the Apple Developer Forum topic where this is discussed.