SSLHandshake(sslContext) returns -36

I am trying to use TLS 1.2 to reach our server with Secure Transport Reference.

However, I got -36 after running SSLHandshake. I have no idea what it is. Would anyone help?


Thank you~!



This is my code:

CFSocketRef mySock = CFSocketCreate(kCFAllocatorDefault, PF_INET, SOCK_STREAM, IPPROTO_TCP,
                                        kCFSocketAcceptCallBack, listenerCallBack, NULL);

    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_len = sizeof(addr);
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = inet_addr([host UTF8String]);

    CFDataRef connectAddr = CFDataCreate(kCFAllocatorDefault, (UInt8 *)&addr, sizeof(addr));
    if (connectAddr == NULL)
        NSLog(@"Error");
    result = CFSocketConnectToAddress(mySock, connectAddr, 30);
    NSLog(@"CFSocketConnectToAddress(): %d", result);

    CFRelease(connectAddr);


    SSLContextRef sslContext = SSLCreateContext(kCFAllocatorDefault, kSSLClientSide, kSSLStreamType);
    result = SSLSetIOFuncs(sslContext, readFromSocket, writeToSocket);
    NSLog(@"SSLSetIOFuncs(): %d", result);
    result = SSLSetConnection(sslContext, (SSLConnectionRef)(long)mySock);/
    NSLog(@"SSLSetConnection(): %d", result);
    result = SSLSetProtocolVersionMin(sslContext, kTLSProtocol12);
    NSLog(@"SSLSetProtocolVersionMin(): %d", result);


    OSStatus status = SSLHandshake(sslContext);
    NSLog(@"SSLHandshake(): %d", status);
    if (status == errSSLPeerAuthCompleted){
          //...
   }


Output is:

SSLHandshake(): -36

-36 is

errSecIO
. It’s likely that your one of your I/O callback functions failed.

What sort of TLS are you trying to do? The code snippet you posted implies that you’re doing TLS over TCP. If so, you’re way way way off in the weeds. Rather than trying to combine CFSocket and Secure Transport, you should just use CFSocketStream via the NSStream API. That’s a much higher-level API and is a lot easier to use.

The TLSTool sample code demonstrates this approach.

Now, there are good reasons for using Secure Transport directly, and there are (very few) good reasons for using CFSocket, but they all represent relatively obscure edge cases; most apps should use NSStream.

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thank you for your quick reply.


I am trying to do mutual authentication and starting from scratches 😐

I need to download a certificate from the server first....

There’s nothing preventing you from doing mutual authentication via the NSStream API. There are some edge cases that NSStream can’t handle (for example, you won’t be able to choose a different client identity based on the DN in the Server Hello, something that you can do with Secure Transport) but, in general, it works just fine.

If you have to stick with Secure Transport, you should read this post, which explains how to implement the read I/O function correctly.

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
SSLHandshake(sslContext) returns -36
 
 
Q