I'm working on two Swift applications which are using QUIC in Network.framework for communication, one serve as the listener (server) and the other serve as the client so that they can exchange data, both the server and the client app are running under the same LAN, the problem I met is that when client try to connect to the server, the connection will fail due to boring SSL, couple questions:
- Since both the server app and client app are running under the same LAN, do they need TLS certificate?
- If it does, will self-signed certificate P12 work? I might distribute the app in App Store or in signed/notarized dmg or pkg to our users.
- If I need a public certificate and self signed wouldn't work, since they are just pair of apps w/o fixed dns domain etc, Is there any public certificate only for standalone application, not for the fixed web domain?
Yes. While it’s theoretically possible to implement QUIC directly over TCP, Apple’s QUIC implementation always runs over TLS. Moreover, this is TLS 1.3, which doesn’t support TLS-PSK. You have to use TLS in its standard PKI mode, which means digital identities and certificates.
Yes, but you’ll have to override TLS server trust evaluation on the client in order to trust the server’s certificate.
Having said that, embedded a single digital identity in your app is hardly ideal security-wise. It’d be relatively easy for someone to extract that and then impersonate your app. There are better options available to you.
If you’d like to explore these better options, I’m happy to do that later. However, for the moment, I recommend that you get things up and limping with a fixed digital identity.
No.
Regarding the code in your second post, you’re definitely on the right track. Your server-side code looks fine. On the client side, I recommend that you do this:
// I normally avoid using the global concurrent queue but in this
// case, for the reasons I outline in “Avoid Dispatch Global
// Concurrent Queues”.
//
// <https://developer.apple.com/forums/thread/711736>
//
// In this case I can’t use `.main` because the main thread is
// running my UI. And it seems a bit silly to write a bunch of
// extract code to bounce back to the queue on which I’m running all
// the networking because I’m not actually doing anything on this
// queue other than call the completion handler.
sec_protocol_options_set_verify_block(self, { _, _, completionHandler in
completionHandler(true)
}, .global())
That just disables server trust evaluation completely. Once you get that working, you can add code to do trust evaluation properly.
Once you get to that stage, make sure you invoke sec_trust_copy_ref
. This lets you convert a sec_trust_t
, in the second argument to your verify block, to a SecTrust
object, which is what you need for the rest of your code.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"