1

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?

Context

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.

Community
  • 1
  • 1
Travis Griggs
  • 21,522
  • 19
  • 91
  • 167
  • https://stackoverflow.com/questions/54452129/how-to-create-ios-nwconnection-for-tls-with-self-signed-cert – Sachin Vas Feb 01 '19 at 08:27
  • @SachinVas, the question you reference is also posted by me. While both have to do with NWConnection questions, they're two different things. THAT question is about programmatically handling self signed *server* certs. THIS question is about how to configure *client side* certs for an NWConnection acting as the client. – Travis Griggs Feb 01 '19 at 17:48
  • Added links for context. Even though MQTT is 20 years old, it's likely that many readers won't know what it is. And NWConnection is a very new addition to iOS. – Caleb Feb 02 '19 at 19:10
  • Thanks @Caleb. I refactored the question to hopefully help the NWConnection part be the focus, and the MQTT stuff as "background context" – Travis Griggs Feb 02 '19 at 19:55
  • @TravisGriggs I know you only answered your previous question. I think https://developer.apple.com/documentation/network/security_symbols this link has answers to your question. – Sachin Vas Feb 09 '19 at 11:59

1 Answers1

0

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.

Travis Griggs
  • 21,522
  • 19
  • 91
  • 167