创建 iOS 12 使用客户端证书的 NWConnection

create iOS 12 NWConnection that uses client cert

我正在尝试设置一个执行客户端证书的 NWConnection

self.connection = NWConnection(
    host: NWEndpoint.Host("servername"),
    port: NWEndpoint.Port(integerLiteral: 8899),
    using: .tls)

但我认为简单的 .tls class var 需要涉及更多 NWParameters 对象,但我完全不知所措(文档非常稀疏)我在那里创建的将客户端证书附加到参数的内容。我也不知道我是如何从 .crt/.pem 文件移动到应用程序以编程方式管理的文件的。

如何配置 NWParameters 以支持客户端证书的示例是什么?

上下文

我正在尝试建立客户端连接以使用客户端证书与 MQTT 代理进行通信。我已经能够使用命令行在 Linux 端对这一切进行概念验证。 MQTT 代理设置为需要客户端证书,以及如下命令:

mosquitto_pub -h servername -p 8899 -t 1234/2/Q/8 -m myMessage --cafile myChain.crt --cert client.crt --key client.pem

做得很好。但是 OpenSSL 就足够了 iOS 上的黑匣子(对我来说),我不知道从这里去哪里。我 能够让所有其他 MQTT 通信与我的 NWConnection 实例一起工作,包括服务器端 TLS,即使它是自签名的。

Apple 开发者论坛上的好心人帮助解决了这个问题。在 iOS 你必须使用 p12 导入能力:

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)")

现在有了身份,您可以使用它来配置 TLS 选项的 securityProtocolOptions

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

作为参考,Apple Developer Forum topic where this is discussed.