How to convert NSStream (NSInputStream / NSOutputStream) to SSL after opening the stream?

I have NSInputStream and NSOutputStream from this code

    var readStream: Unmanaged<CFReadStream>?
    var writeStream: Unmanaged<CFWriteStream>?

    CFStreamCreatePairWithSocket(kCFAllocatorDefault, sslSocket!, &readStream, &writeStream)
    if readStream != nil && writeStream != nil {
        CFReadStreamSetProperty(readStream!.takeUnretainedValue(), kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue)
        CFWriteStreamSetProperty(writeStream!.takeUnretainedValue(), kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue)

        inputStream = readStream!.takeRetainedValue()
        outputStream = writeStream!.takeRetainedValue()

        // Create strong delegate reference to stop ARC deallocating the object
        inputDelegate = self
        outputDelegate = self

        // Now that we have a strong reference, assign the object to the stream delegates
        inputStream!.delegate = inputDelegate
        outputStream!.delegate = outputDelegate


        // Schedule our run loops. This is needed so that we can recieve NSStreamEvents
        inputStream!.scheduleInRunLoop(NSRunLoop.mainRunLoop(), forMode: NSDefaultRunLoopMode)
        outputStream!.scheduleInRunLoop(NSRunLoop.mainRunLoop(), forMode: NSDefaultRunLoopMode)

        inputStream!.open()
        outputStream!.open()
    }

Problem . How to convert this stream to SSL after opening it?

I tried , but I get NSOSStatusErrorDomain:

The operation could not be completed. (Error OSStatus -9801)

if (sslEnable) {
    let sslSettings = [
        NSString(format: kCFStreamSSLValidatesCertificateChain): kCFBooleanFalse,
        NSString(format: kCFStreamSSLPeerName): kCFNull,
        NSString(format: kCFStreamSSLIsServer): kCFBooleanTrue,
    ]
    CFReadStreamSetProperty(inputStream, kCFStreamPropertySSLSettings, sslSettings)
    CFWriteStreamSetProperty(outputStream, kCFStreamPropertySSLSettings, sslSettings)

}
+4
source share
2 answers

Configuring Socket Streams

As you know, NSStreamit does not support connecting to a remote host on iOS natively; you instantiate CFStreamwith CFStreamCreatePairWithSocketToHost, and then go to NSStream. The code is correct.

, ssl ; , .

SSL NSStream [...]

, . , , , SSL .

, ( ).

if let inputStream = inputStream, let outputStream = outputStream {
    inputStream.schedule(in: RunLoop.main, forMode: RunLoopMode.defaultRunLoopMode)
    outputStream.schedule(in: RunLoop.main, forMode: RunLoopMode.defaultRunLoopMode)

    if (sslEnable) {
        inputStream.setProperty(StreamSocketSecurityLevel.tlSv1,
                               forKey: Stream.PropertyKey.socketSecurityLevelKey)
        outputStream.setProperty(StreamSocketSecurityLevel.tlSv1,
                                 forKey: Stream.PropertyKey.socketSecurityLevelKey)

        let sslSettings = [
            NSString(format: kCFStreamSSLValidatesCertificateChain): kCFBooleanFalse,
            NSString(format: kCFStreamSSLPeerName): kCFNull,
            NSString(format: kCFStreamSSLIsServer): kCFBooleanTrue,
            ] as [NSString : Any]

        inputStream.setProperty(sslSettings,
                                forKey: Stream.PropertyKey(rawValue:
                                    kCFStreamPropertySSLSettings as String))
        outputStream.setProperty(sslSettings,
                                 forKey: Stream.PropertyKey(rawValue:
                                    kCFStreamPropertySSLSettings as String))

    }
    inputStream.open()
    outputStream.open()
}
+2

errSSLNegotiation SecureTransport.h Security

-9801 The cipher suite negotiation failed.

, , , SSL , .

+1

Source: https://habr.com/ru/post/1665078/


All Articles