I'm trying around with an app that is to securely connect from an iPhone client to a TLS server via sockets/streams for general data-exchange. For that purpose I set up an own CA with the mac keychain-tool and included the certificat in the code bundle.
Now my app should trust any server certificate issued by that CA. (I do not care how other apps treat those certs, I assume that they will not trust it because of the sandbox.)
I have found several similar issues online but seem to have gotten something wrong.
Connecting with the server seems to work fine if I drag & drop the CA certificate into the Simulator and manually accept to trust it.
However, when I try to establish trust for the CA cert programmatically my connection attempts later to the server are refused, despite the code below does not generate errors.
Therefore I must have got the certificate implementation part wrong... Any ideas?
Many thanks in advance!
NSString* certPath = [[NSBundle mainBundle] pathForResource:@"MyTestCA2" ofType:@"cer"]; //cer = CA certificate
NSData* certData = [NSData dataWithContentsOfFile:certPath];
SecCertificateRef cert;
if( [certData length] ) {
cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certData);
if( cert != NULL ) {
CFStringRef certSummary = SecCertificateCopySubjectSummary(cert);
NSString* summaryString = [[NSString alloc] initWithString:(__bridge NSString*)certSummary];
NSLog(@"CERT SUMMARY: %@", summaryString);
certSummary = nil;
} else {
NSLog(@" *** ERROR *** trying to create the SSL certificate from data located at %@, but failed", certPath);
}
}
OSStatus err = noErr;
CFTypeRef result;
NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
(__bridge id)kSecClassCertificate, kSecClass,
cert, kSecValueRef,
nil];
err = SecItemAdd((__bridge CFDictionaryRef)dict, &result);
if(err!=noErr) NSLog(@"error while importing");
if (err==errSecDuplicateItem) NSLog(@"Cert already installed");
NSLog(@":%i",(int)err);
assert(err==noErr||err==errSecDuplicateItem); // accept no errors other than duplicate
err = noErr;
SecTrustRef trust;
err = SecTrustCreateWithCertificates(cert, SecPolicyCreateBasicX509() ,&trust);
assert(err==noErr);
err = noErr;
CFMutableArrayRef newAnchorArray = CFArrayCreateMutable(kCFAllocatorDefault,0,&kCFTypeArrayCallBacks);
CFArrayAppendValue(newAnchorArray,cert);
err = SecTrustSetAnchorCertificates(trust, newAnchorArray);
assert(err==noErr);
SecTrustResultType trustResult;
err=SecTrustEvaluate(trust,&trustResult);
assert(err==noErr);
cert=nil;