Skip to content

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
iOS SSL based NSURLConnection to a site using a self-signed certificate
This code was taken from: http://blog.wingsofhermes.org/?p=58&cpage=1, and the following done to it:
- code was ARCified
- the "certificate authority certificate", provided to me as a .crt file, was converted to a der format needed by iOS, and is read from the bundle
- the repetitive Security framework code was done once in the initialize method
#if ! __has_feature(objc_arc)
#error THIS CODE MUST BE COMPILED WITH ARC ENABLED!
#endif
static CFArrayRef certs;
@implementation MyWebFetcher
+ (void)initialize
{
if(self == [MyWebFetcher class]) {
// I had a crt certificate, needed a der one, so found this site:
// http://fixunix.com/openssl/537621-re-der-crt-file-conversion.html
// and did this from Terminal: openssl x509 -in crt.crt -outform der -out crt.der
NSString *path = [[NSBundle mainBundle] pathForResource:@"crt" ofType:@"der"];
assert(path);
NSData *data = [NSData dataWithContentsOfFile:path];
assert(data);
/* Set up the array of certs we will authenticate against and create cred */
SecCertificateRef rootcert = SecCertificateCreateWithData(NULL, CFBridgingRetain(data));
const void *array[1] = { rootcert };
certs = CFArrayCreate(NULL, array, 1, &kCFTypeArrayCallBacks);
CFRelease(rootcert); // for completeness, really does not matter
}
}
#pragma mark -
#pragma mark Connection Authentication Handling
@implementation MyWebFetcher (NSURLConnectionDelegate)
- (BOOL)connection:(NSURLConnection *)conn canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
#pragma unused(conn)
NSString * challenge = [protectionSpace authenticationMethod];
NSLog(@"canAuthenticateAgainstProtectionSpace challenge %@ isServerTrust=%d", challenge, [challenge isEqualToString:NSURLAuthenticationMethodServerTrust]);
if ([challenge isEqualToString:NSURLAuthenticationMethodServerTrust]) {
return YES;
}
return NO;
}
/* Look to see if we can handle the challenge */
- (void)connection:(NSURLConnection *)conn didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
#pragma unused(conn)
NSLog(@"didReceiveAuthenticationChallenge %@ FAILURES=%d", [[challenge protectionSpace] authenticationMethod], (int)[challenge previousFailureCount]);
/* Setup */
NSURLProtectionSpace *protectionSpace = [challenge protectionSpace];
assert(protectionSpace);
SecTrustRef trust = [protectionSpace serverTrust];
assert(trust);
CFRetain(trust); // Make sure this thing stays around until we're done with it
NSURLCredential *credential = [NSURLCredential credentialForTrust:trust];
#if 0 // moved to initialize for re-use
NSString *path = [[NSBundle mainBundle] pathForResource:@"Lot18-CA" ofType:@"der"];
assert(path);
NSData *data = [NSData dataWithContentsOfFile:path];
assert(data);
SecCertificateRef rootcert = SecCertificateCreateWithData(NULL, CFBridgingRetain(data));
const void *array[1] = { rootcert };
/* Set up the array of certs we will authenticate against and create cred */
CFArrayRef certs = CFArrayCreate(NULL, array, 1, &kCFTypeArrayCallBacks);
CFRelease(rootcert); // for completeness, really does not matter
CFRelease(rootcert); // for completeness, really does not matter
#endif
/* Build up the trust anchor using our root cert */
int err;
SecTrustResultType trustResult = 0;
err = SecTrustSetAnchorCertificates(trust, certs);
if (err == noErr) {
err = SecTrustEvaluate(trust,trustResultP);
}
CFRelease(trust); // OK, now we're done with it
// http://developer.apple.com/library/mac/#qa/qa1360/_index.html
BOOL trusted = (err == noErr) && ((trustResult == kSecTrustResultProceed) || (trustResult == kSecTrustResultConfirm) || (trustResult == kSecTrustResultUnspecified));
// Return based on whether we decided to trust or not
if (trusted) {
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
} else {
NSLog(@"Trust evaluation failed for service root certificate");
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
}
@end
@Stille

Hi
I try to test with your code, but I always receive kSecTrustResultRecoverableTrustFailure event. Could you help me ? Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.