I am trying to use an application that should securely connect from an iPhone client to a TLS server through sockets / streams for general communication. For this purpose, I configured my own CA using the keychain tool for mac and included the certificate in the code set.
My application should now trust any server certificate issued by this CA. (I do not care how other applications relate to these certificates, I assume that they will not trust him because of the sandbox.)
I found several similar questions on the Internet, but it seems I got something wrong.
Connecting to the server seems to work fine if I drag the CA certificate into Simulator and agree to it manually.
However, when I try to establish trust in the CA certificate programmatically, my attempts to connect to the server later are rejected, despite the fact that the code below does not generate errors.
Therefore, I must have the wrong part of the certificate implementation ... Any ideas?
Thank you very much in advance!
NSString* certPath = [[NSBundle mainBundle] pathForResource:@"MyTestCA2" ofType:@"cer"];
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);
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;