I have sub-classed MKNetworkOperation in order to hijack the process whereby the server's TLS certificate is validated. The intention is to allow people to configure a server certificate from a private certificate authority. For testing purposes I have included my test server's public certificate as a resource.
I overrode the delegate function "connection:willSendRequestForAuthenticationChallenge:" (basically copy/pasted from MKNetworkOperation and then pared down to address the 2 specific cases I want to support). The portion that addresses server authentication is as follows:
NSData *iosTrustedCertDerData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"cert_name" ofType:@"cer"]];
SecCertificateRef certificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef) iosTrustedCertDerData);
SecTrustRef trust = [[challenge protectionSpace] serverTrust];
NSArray* trustArray = [NSArray arrayWithObjects:(__bridge id)(certificate), nil];
SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef) trustArray);
CFRelease(certificate);
SecTrustResultType result;
SecTrustEvaluate(trust, &result);
if(result == kSecTrustResultProceed || result == kSecTrustResultUnspecified)
//The cert is valid, but user has not explicitly accepted/denied. Ok to proceed (Ch 15: iOS PTL :Pg 269)
[challenge.sender useCredential:[NSURLCredential credentialForTrust:trust] forAuthenticationChallenge:challenge];
else {
// invalid or revoked certificate
if(self.shouldContinueWithInvalidCertificate)
[challenge.sender useCredential:[NSURLCredential credentialForTrust:trust] forAuthenticationChallenge:challenge];
else
[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}
So, in the first case if I do NOT include the code to set custom trust anchors but I DO set the flag to continue with an invalid certificate, then I can get through fine.
If I DO include the code to set custom trust anchors, I get the expected kSecTrustResultUnspecified but the network framework rejects my connection nonetheless.
What I find odd is, the exact same call is made in these two cases but one fails and one does not. I'm honestly not sure this is a MKNetworkKit issue per se, but I'm hoping someone here has tried something similar and can point out what's wrong.
Another option I considered was saving the server certificate in the app keychain but that failed as well and I was making more headway with this solution.
I've only been in objective-c for a couple months so there is a distinct possibility I'm just using all of this stuff incorrectly :p
I have sub-classed MKNetworkOperation in order to hijack the process whereby the server's TLS certificate is validated. The intention is to allow people to configure a server certificate from a private certificate authority. For testing purposes I have included my test server's public certificate as a resource. I overrode the delegate function "connection:willSendRequestForAuthenticationChallenge:" (basically copy/pasted from MKNetworkOperation and then pared down to address the 2 specific cases I want to support). The portion that addresses server authentication is as follows:
So, in the first case if I do NOT include the code to set custom trust anchors but I DO set the flag to continue with an invalid certificate, then I can get through fine.
If I DO include the code to set custom trust anchors, I get the expected kSecTrustResultUnspecified but the network framework rejects my connection nonetheless.
What I find odd is, the exact same call is made in these two cases but one fails and one does not. I'm honestly not sure this is a MKNetworkKit issue per se, but I'm hoping someone here has tried something similar and can point out what's wrong.
Another option I considered was saving the server certificate in the app keychain but that failed as well and I was making more headway with this solution.
I've only been in objective-c for a couple months so there is a distinct possibility I'm just using all of this stuff incorrectly :p
Thanks in advance for any help!