4
votes

I am trying to create a SSL connection over TCP/IP from iOS to an Erlang server. The server is using self-signed certificates (default certificates shipped with Erlang OTP).

Every time, the SSL Handshake fails: - CFNetwork SSLHandshake failed (-9824 -> -9829) - CFNetwork SSLHandshake failed (-9807)

This is one method I use:

CFReadStreamRef readStream;
CFWriteStreamRef writeStream;

CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"my-server-name", 1234, &readStream, &writeStream);

//------------------------------------------------------
// Set props.
//
CFReadStreamSetProperty(readStream, kCFStreamPropertySocketSecurityLevel, kCFStreamSocketSecurityLevelNegotiatedSSL);
CFReadStreamSetProperty(readStream, kCFStreamSSLAllowsExpiredCertificates, kCFBooleanTrue);
CFReadStreamSetProperty(readStream, kCFStreamSSLAllowsExpiredRoots, kCFBooleanTrue);
CFReadStreamSetProperty(readStream, kCFStreamSSLAllowsAnyRoot, kCFBooleanTrue);
CFReadStreamSetProperty(readStream, kCFStreamSSLValidatesCertificateChain, kCFBooleanFalse);
CFReadStreamSetProperty(readStream, kCFStreamSSLPeerName, kCFNull);

CFWriteStreamSetProperty(writeStream, kCFStreamPropertySocketSecurityLevel, kCFStreamSocketSecurityLevelNegotiatedSSL);
CFWriteStreamSetProperty(writeStream, kCFStreamSSLAllowsExpiredCertificates, kCFBooleanTrue);
CFWriteStreamSetProperty(writeStream, kCFStreamSSLAllowsExpiredRoots, kCFBooleanTrue);
CFWriteStreamSetProperty(writeStream, kCFStreamSSLAllowsAnyRoot, kCFBooleanTrue);
CFWriteStreamSetProperty(writeStream, kCFStreamSSLValidatesCertificateChain, kCFBooleanFalse);
CFWriteStreamSetProperty(writeStream, kCFStreamSSLPeerName, kCFNull);

//------------------------------------------------------
// Open streams.
//
if(!CFReadStreamOpen(readStream))
{
    NSLog(@"CFReadStreamOpen Failed!");
    return 0;
}

if(!CFWriteStreamOpen(writeStream))
{
    NSLog(@"CFWriteStreamOpen Failed!");
    CFReadStreamClose(readStream);
    return 0;
}

//------------------------------------------------------
// Send some data.
//
UInt8 data[20] = {0};

*(ushort*)data = 18;
for(int i = 2; i < 20; i++)
{
    data[i] = 'A' + i;
}

NSLog(@"Sending some data...");

CFIndex bytesSent = CFWriteStreamWrite(writeStream, data, 20);
NSLog(@"Bytes Sent: %d", (int)bytesSent);

//------------------------------------------------------
// Close streams.
//
CFReadStreamClose(readStream);
CFWriteStreamClose(writeStream);

I tried also with SecureTransport ( SSLCreateContext, SSLSetConnection, SSLHandshake and it is the same - SSL handshake fails.

Any suggestion is very appreciated.

2

2 Answers

1
votes

There are many possible reasons for the error. You should probably begin by using the curl command on your Mac to access the Erlang server. Curl will give you more descriptive errors. You'll need to pass the -k flag to tell it to ignore cert errors.

Some quick possibilities: Is your Objective-C code set to allow invalid certs? Is it set to validate the domain name, and your development setup doesn't do reverse DNS?

0
votes

If the issue is related to AppTransport you can find which exception you need by running /usr/bin/nscurl --ats-diagnostics --verbose yourdomain.com on MacOS 10.11.