iossocketssslcertificate-authorityroot-certificate

SSL Socket connection iOS


I am trying to setup a secure connection to a java run SSLServerSocket.

I have created my own root CA, and have signed the certificate that the Java SSLServerSocket using this certificate.

I want to add this root certificate to my app so that any certificate signed by the root certificate will work.

So far I have the secure connection working fine by setting the read and write stream properties to this:

NSDictionary *settings = [[NSDictionary alloc] initWithObjectsAndKeys:
(id)kCFStreamSocketSecurityLevelNegotiatedSSL, kCFStreamPropertySocketSecurityLevel,
[NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredCertificates,
[NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredRoots,
[NSNumber numberWithBool:NO], kCFStreamSSLValidatesCertificateChain,nil];

I add the certificate to the keychain like this:

-(void)addRootCert{
NSString* rootCertPath = [[NSBundle mainBundle] pathForResource:@"rootCA" ofType:@"der"];
NSData* rootCertData = [NSData dataWithContentsOfFile:rootCertPath];

OSStatus err = noErr;
SecCertificateRef rootCert = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)rootCertData);
NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:(__bridge_transfer id)kSecClassCertificate, kSecClass, rootCert, kSecValueRef, nil];

err = SecItemAdd((__bridge CFDictionaryRef) dict, NULL);
if (err == noErr) {
    NSLog(@"Sucessfully added root certificate");
}else if (err == errSecDuplicateItem){
    NSLog(@"Root certificate already exists");
}else{
    NSLog(@"Root certificate add failed");
}
}

This is fine but I want to validate the certificate chain, so that my app only accepts certificates signed by my CA (or the default trusted ones)

How can I do this?

If I set kCFStreamSSLValidatesCertificateChain to yes, I get the error: CFNetwork SSLHandshake failed (-9807) but if it's no, it doesn't matter who signed the server certificate, it will connect regardless (I assume that's right?)

Thanks!


Solution

  • Technote 2232, "HTTPS Server Trust Evaluation", should have all the answers you need. There is documentation and several examples of how to evaluate server trust.