I have a few questions about network streams, particularly NSStreamSocketSecurityLevelKey and what looks like a private property on streams, _kCFStreamPropertySocketPeerName
The documentation for NSStreamSocketSecurityLevelKey on https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Streams/Articles/NetworkStreams.html states:
For SSL security, NSStream defines various security-level properties (for example, NSStreamSocketSecurityLevelSSLv2). You set these properties by sending setProperty:forKey: to the stream object using the key NSStreamSocketSecurityLevelKey, as in this sample message:
[inputStream setProperty:NSStreamSocketSecurityLevelTLSv1 forKey:NSStreamSocketSecurityLevelKey];
You must set the property before you open the stream. Once it opens, it goes through a handshake protocol to find out what level of SSL security the other side of the connection is using. If the security level is not compatible with the specified property, the stream object generates an error event.
We've seen that it is possible to set this property after opening the stream and sending/receiving some initial data, for example doing a handshake with a CONNECT proxy before starting the real TLS session with the final end point.
Is this ability to start the TLS negotiation at a later date via a delayed setProperty:forKey:NSStreamSocketSecurityLevelKey fully supported?
Also, there is still a problem in the CONNECT proxy case above: the SNI sent to the end-point will be the proxy host not the intended host. Facebook's SocketRocket library uses what looks like a private property to override this:
[self.outputStream setProperty:self.url.host forKey:@"_kCFStreamPropertySocketPeerName"];Is this supported? Even though it's kind of private, is this something we could use?
PS: Calling Quinn the Eskimo 😉