NSUrlConnection sendAsynchronousRequest and self-signed certificates - ios

I'm writing some API code that does http requests, and I've been using [NSUrlConnection:sendAsynchronousRequest:queue:completionHandler] for the calls, as it makes it pretty easy to write simple handlers, and also so that I don't have to have different classes with different delegates for each call.
The problem that I'm having is that it seems that the only way to accept self-signed certificates is to have a delegate that implements a couple of functions saying that the certificate is okay. Is there any way to do this with the asynchronous method that uses blocks?

No, but the delegate calls are not all that hard. This is the code you need:
1) Make this a file static
static CFArrayRef certs;
2) DO this in your initialize:
// 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:#"<your name>" ofType:#"der"];
assert(path);
NSData *data = [NSData dataWithContentsOfFile:path];
assert(data);
SecCertificateRef rootcert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)data);
if(rootcert) {
const void *array[1] = { rootcert };
certs = CFArrayCreate(NULL, array, 1, &kCFTypeArrayCallBacks);
CFRelease(rootcert); // for completeness, really does not matter
} else {
NSLog(#"BIG TROUBLE - ROOT CERTIFICATE FAILED!");
}
3) Then add this method:
- (void)connection:(NSURLConnection *)conn didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
#pragma unused(conn)
// NSLog(#"didReceiveAuthenticationChallenge %# FAILURES=%zd", [[challenge protectionSpace] authenticationMethod], (ssize_t)[challenge previousFailureCount]);
/* Setup */
NSURLProtectionSpace *protectionSpace = [challenge protectionSpace];
assert(protectionSpace);
SecTrustRef trust = [protectionSpace serverTrust];
assert(trust);
CFRetain(trust); // Don't know when ARC might release protectionSpace
NSURLCredential *credential = [NSURLCredential credentialForTrust:trust];
BOOL trusted = NO;
OSStatus err;
SecTrustResultType trustResult = 0;
err = SecTrustSetAnchorCertificates(trust, certs);
if (err == noErr) {
err = SecTrustEvaluate(trust, &trustResult);
if(err == noErr) {
// http://developer.apple.com/library/mac/#qa/qa1360/_index.html
switch(trustResult) {
case kSecTrustResultProceed:
case kSecTrustResultConfirm:
case kSecTrustResultUnspecified:
trusted = YES;
break;
}
}
}
CFRelease(trust);
// Return based on whether we decided to trust or not
if (trusted) {
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
} else {
NSLog(#"Trust evaluation failed");
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
}

Related

Certificate pinning in Xcode

I got below code for certificate pinning in Android
CertificatePinner certificatePinner = new CertificatePinner.Builder()
.add("publicobject.com", "sha1/DmxUShsZuNiqPQsX2Oi9uv2sCnw=")
.add("publicobject.com", "sha1/SXxoaOSEzPC6BgGmxAt/EAcsajw=")
.add("publicobject.com", "sha1/blhOM3W9V/bVQhsWAcLYwPU6n24=")
.add("publicobject.com", "sha1/T5x9IXmcrQ7YuQxXnxoCmeeQ84c=")
.build();
How do i achieve same task in IOS using NSURLSession method?
Got some reference code here
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, 0);
NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate));
NSString *cerPath = [[NSBundle mainBundle] pathForResource:#"MyLocalCertificate" ofType:#"cer"];
NSData *localCertData = [NSData dataWithContentsOfFile:cerPath];
if ([remoteCertificateData isEqualToData:localCertData]) {
NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}
else {
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
EDIT PART
I got below solution, which delegate function is called automatically in NSURLSession, can anyone explain how it will work ? ALSO Need to send multiplier certificate how do i do it?
(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler
{
NSString *authMethod = [[challenge protectionSpace] authenticationMethod];
if ([authMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
completionHandler(NSURLSessionAuthChallengeUseCredential,credential);
} else {
SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, 0);
NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate));
NSString *cerPath = [[NSBundle mainBundle] pathForResource:#"MyLocalCertificate" ofType:#"cer"];
NSData *localCertData = [NSData dataWithContentsOfFile:cerPath];
NSURLCredential *credential;
if ([remoteCertificateData isEqualToData:localCertData]) {
credential = [NSURLCredential credentialForTrust:serverTrust];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}
else {
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
NSLog(#"Finished Challenge");
}
}
The if block skips certificate pinning if the authentication method is NSURLAuthenticationMethodServerTrust. I'm not quite sure why you'd do that---you'll have to look at the source where you got this code snippet and see what it's requirements are.
If the authentication method is anything else, the else block does certificate pinning.
The variable serverTrust is sent to the SSL transaction state from the server. The main thing here is that it has a chain of certificates that authenticate the server. In the next line, certificate is set to the leaf certificate in the chain, i.e. the server's certificate.
remoteCertificateData is essentially a big binary blob representing the information in the certificate. The call to CFBridgingRelease is needed for memory management (all the CFxxx functions are C/C++ functions, not Objective-C, and the memory management is a little bit more complicated than normal).
localCertData is a binary blob of the information in the local copy of the certificate. Note that iOS apps are (more or less) a collection of files including the executable as well as various resources, etc. As part of the build process, you would arrange for a copy of the server's certificate to be included in thes collection (NSBundle) of files. The cerPath variable is set to the file path of the local copy of the certificate.
Finally, we check to see if the two binary blobs are equal. If not, then the certificate from the server is bogus and we don't proceed with the request.
I'm not completely sure what you mean by "Need to send multiplier certificate". Judging from the Java code you reference I am assuming what you mean is that you want to compare the server certificate with multiple local certificates. In that case, something (roughly) like the following (note: untested code):
SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, 0);
NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate));
BOOL match = NO;
NSURLCredential *credential;
for (NSString *path in [[NSBundle mainBundle] pathsForResourcesOfType:#"cer" inDirectory:#"."]) {
NSData *localCertData = [NSData dataWithContentsOfFile:path];
if ([remoteCertificateData isEqualToData:localCertData]) {
credential = [NSURLCredential credentialForTrust:serverTrust];
match = YES;
break;
}
}
if (match) {
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
} else {
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
NSLog(#"Finished Challenge");

Intermittent SSL error in iOS for NSURLConnection

I am connecting to a server with a custom SSL which is no longer a valid SSL Certificate. I have updated my info.plist to allow arbitrary and added code to bypass challenge on NSURLConnection delegate.
-(void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
NSLog(#"willSendRequestForAuthenticationChallenge");
BOOL trusted = NO;
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
NSString *thePath = [[NSBundle mainBundle] pathForResource:#"cert" ofType:#"der"];
NSData *certData = [[NSData alloc] initWithContentsOfFile:thePath];
CFDataRef certDataRef = (__bridge_retained CFDataRef)certData;
SecCertificateRef cert = SecCertificateCreateWithData(NULL, certDataRef);
SecPolicyRef policyRef = SecPolicyCreateBasicX509();
SecCertificateRef certArray[1] = { cert };
CFArrayRef certArrayRef = CFArrayCreate(NULL, (void *)certArray, 1, NULL);
SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
SecTrustSetAnchorCertificates(serverTrust, certArrayRef);
SecTrustResultType trustResult;
SecTrustEvaluate(serverTrust, &trustResult);
trusted = (trustResult == kSecTrustResultUnspecified);
CFRelease(certArrayRef);
CFRelease(policyRef);
CFRelease(cert);
CFRelease(certDataRef);
}
if (trusted) {
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
} else {
[challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge];
}
}
However, intermittently happening, I am getting the SSL error. It is not calling the delegate willSendRequestForAuthenticationChallenge instead going directly to didFailWithError delegate.
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
Your code is subtly wrong. The cert is trusted if the result status is either:
kSecTrustResultUnspecified
kSecTrustResultProceed
Additionally, for an expired cert, the code above should see a kSecTrustResultRecoverableTrustFailure error unless you call:
SecTrustSetOptions(serverTrust,kSecTrustOptionAllowExpired);
However, allowing expired certificates is strongly discouraged.
Unless by "no longer valid", you mean that it violates the minimum requirements for iOS 9, in which case yes, you'll get exactly the behavior you described when running on iOS 9, if compiled against the iOS 9 SDK. For more info, do a Google search for App Transport Security.

NSURLAuthenticationMethodServerTrust challenge called every time

Situation: I am building an enterprise App which can be used for sharing Pictures etc. It was using HTTP and now I moved to HTTPS as it is going public. I have the client certificates (.cer) bundled in the App.
I have followed through most of the discussions here and the post by Eskimo on AppDev forum (https://devforums.apple.com/message/737087#737087) and here (http://www.techrepublic.com/blog/software-engineer/use-https-certificate-handling-to-protect-your-ios-app/). But my problem is that my App has multiple calls to the same HTTPS server and for each time I keep getting the NSURLAuthenticationMethodServerTrust challenge. Is this normal? 'coz for each challenge I lose close to 4 seconds of transaction time and my pictures take time to load.
Also, please see the NSURLAuthenticationMethodDefault challenge IF condition comment, really not sure why that is going this way.
So to sum up.
1. Do I have to check certificates and verify for every HTTPS call?
2. Why is the Authentication challenge (NSURLAuthenticationMethodDefault) not working if I put inside the IF block.
Any help here would be appreciated.
-(BOOL) shouldTrustProtectionSpace:(NSURLProtectionSpace *) protectionSpace{
NSString *certPath = [[NSBundle mainBundle] pathForResource:#"file.something.com" ofType:#"cer"];
NSData *certData = [[NSData alloc] initWithContentsOfFile:certPath];
CFDataRef certDataRef = (__bridge_retained CFDataRef)certData;
SecCertificateRef cert = SecCertificateCreateWithData(NULL,certDataRef);
CFArrayRef certArrayRef = CFArrayCreate(NULL, (void *)&cert,1,NULL);
SecTrustRef serverTrust = protectionSpace.serverTrust;
SecTrustSetAnchorCertificates(serverTrust, certArrayRef);
SecTrustResultType trustResult;
SecTrustEvaluate(serverTrust, &trustResult);
if ( trustResult == kSecTrustResultRecoverableTrustFailure){
NSLog(#"kSecTrustResultRecoverableTrustFailure");
CFDataRef errDataRef = SecTrustCopyExceptions(serverTrust);
SecTrustSetExceptions(serverTrust, errDataRef);
SecTrustEvaluate(serverTrust, &trustResult);
}
if ( trustResult == kSecTrustResultUnspecified){
NSLog(#"In Trust: kSecTrustResultUnspecified");
}
if ( trustResult == kSecTrustResultProceed){
NSLog(#"In Trust: kSecTrustResultProceed");
}
return trustResult == kSecTrustResultUnspecified || trustResult == kSecTrustResultProceed;
}
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler{
NSLog(#"didReceiveChallenge");
if ([self shouldTrustProtectionSpace:[challenge protectionSpace]]) {
SecTrustRef trust = [[challenge protectionSpace] serverTrust];
SecCertificateRef certificate = SecTrustGetCertificateAtIndex(trust, 0);
NSData *serverCertificateData = (__bridge NSData *)SecCertificateCopyData(certificate);
NSURL *bundledCertURL = [[NSBundle mainBundle] URLForResource:#"file.something.com" withExtension:#"cer"];
NSData *bundledCertData = [[NSData alloc] initWithContentsOfURL:bundledCertURL];
BOOL whatWeExpected = [serverCertificateData isEqual:bundledCertData];
if (whatWeExpected == TRUE ){
NSLog(#"As Expected");
NSURLCredential *cred = [[NSURLCredential alloc] initWithTrust:trust];
[[challenge sender] useCredential:cred forAuthenticationChallenge:challenge];
}
}
if ([[[challenge protectionSpace] authenticationMethod] isEqualToString: NSURLAuthenticationMethodDefault]) {
NSLog(#"NSURLAuthenticationMethodDefault");
}
//This piece of code I put it outside the above IF for now else I never get
//the NSURLAuthenticationMethodDefault challenge?????
NSURLCredential *newCredential;
newCredential = [NSURLCredential credentialWithUser:userName
password:passWord
persistence:NSURLCredentialPersistenceNone];
completionHandler(NSURLSessionAuthChallengeUseCredential, newCredential);
}

Client Certificate Authentication on iOS UIWebView Works on iOS 6.1 but not iOS 7

I am trying to use Client Certificate authentication to access a secure website. The code I am using works fine in iOS 6.1 but fails with the server returning a 403.7 error when using iOS 7.
I use the connection:willSendRequestForAuthenticationChallenge handler to check the authentication method and provide the client certificate.
My code is:
- (void)connection: (NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
{
NSLog(#"Trust Challenge");
SecTrustResultType trustResultType;
OSStatus err = SecTrustEvaluate(challenge.protectionSpace.serverTrust, &trustResultType);
NSLog(#"SecTrustResult %u %d",trustResultType, (int)err);
if (trustResultType == kSecTrustResultProceed || trustResultType == kSecTrustResultConfirm || trustResultType == kSecTrustResultUnspecified) {
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
}
else{
[challenge.sender cancelAuthenticationChallenge:challenge];
}
} else {
NSString *path = [[NSBundle mainBundle]pathForResource:#"mycert" ofType:#"pfx"];
NSData *p12data = [NSData dataWithContentsOfFile:path];
CFDataRef inP12data = (__bridge CFDataRef)p12data;
SecIdentityRef myIdentity;
SecTrustRef myTrust;
extractIdentityAndTrust(inP12data, &myIdentity, &myTrust);
assert(myIdentity != nil);
assert(myTrust != nil);
long count = SecTrustGetCertificateCount(myTrust);
NSMutableArray* myCertificates = nil;
if(count > 1) {
myCertificates = [NSMutableArray arrayWithCapacity:count];
for(int i = 1; i < count; ++i) {
[myCertificates addObject:(__bridge id)SecTrustGetCertificateAtIndex(myTrust, i)];
}
}
NSURLCredential *credential = [NSURLCredential credentialWithIdentity:myIdentity certificates:myCertificates persistence:NSURLCredentialPersistenceNone];
assert(credential != nil);
NSLog(#"User: %#, certificates %# identity:%#", [credential user], [credential certificates], [credential identity]);
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}
}
I use this function to extract the contents of the certificate:
OSStatus extractIdentityAndTrust(CFDataRef inP12data, SecIdentityRef *identity, SecTrustRef *trust)
{
OSStatus securityError = errSecSuccess;
CFStringRef password = CFSTR("password");
const void *keys[] = { kSecImportExportPassphrase };
const void *values[] = { password };
CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
securityError = SecPKCS12Import(inP12data, options, &items);
if (securityError == 0) {
CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex(items, 0);
const void *tempIdentity = NULL;
tempIdentity = CFDictionaryGetValue(myIdentityAndTrust, kSecImportItemIdentity);
*identity = (SecIdentityRef)tempIdentity;
const void *tempTrust = NULL;
tempTrust = CFDictionaryGetValue(myIdentityAndTrust, kSecImportItemTrust);
*trust = (SecTrustRef)tempTrust;
CFIndex count = CFArrayGetCount(items);
NSLog(#"Certificates found: %ld",count);
}
if (options) {
CFRelease(options);
}
return securityError;
}
The mycert.pfx file contains the intermediate certificate along with the client cert.
The connection:didFailWithError function is never called.
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(#"Error: %#", [error userInfo]);
}
So it seems like the certificate negotiation succeeds at some level.
My problem is similar to SSL - behaves differently in iOS7? but I am using Windows Server 2008 R2 with IIS 7.5. The TLS 1.1 and TLS 1.2 protocols have been enabled on the server.
A WireShark trace shows that the certificate frame during the TLS handshake is empty when using iOS 7. The certificate is sent and verified when using iOS 6.1.
I can access the site in iOS 7 using Safari.
Any help is greatly appreciated.
I was able to find a solution with the help of Apple Developer support. The solution involves creating a custom NSURLProtocol. I used the Apple sample code at https://developer.apple.com/library/ios/#samplecode/CustomHTTPProtocol/. The sample code shows how to override HTTPS server trust evaluation so it needs to be modified to work with client certificate authentication.
I modified the AppDelegate didRecieveAuthenticationChallenge function.
- (void)customHTTPProtocol:(CustomHTTPProtocol *)protocol didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
// A CustomHTTPProtocol delegate callback, called when the protocol has an authenticate
// challenge that the delegate accepts via - customHTTPProtocol:canAuthenticateAgainstProtectionSpace:.
// In this specific case it's only called to handle server trust authentication challenges.
// It evaluates the trust based on both the global set of trusted anchors and the list of trusted
// anchors returned by the CredentialsManager.
{
OSStatus err;
NSURLCredential * credential;
assert(protocol != nil);
assert(challenge != nil);
credential = nil;
// Handle ServerTrust and Client Certificate challenges
NSString *authenticationMethod = [[challenge protectionSpace] authenticationMethod];
if ([authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
NSLog(#"Trust Challange");
SecTrustResultType trustResultType;
err = SecTrustEvaluate(challenge.protectionSpace.serverTrust, &trustResultType);
NSLog(#"SecTrustResult %u %d",trustResultType, (int)err);
if (trustResultType == kSecTrustResultProceed || trustResultType == kSecTrustResultUnspecified) {
credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
assert(credential != nil);
}
} else {
NSString *path = [[NSBundle mainBundle]pathForResource:#"mycert" ofType:#"pfx"];
NSData *p12data = [NSData dataWithContentsOfFile:path];
SecIdentityRef identity = NULL;
SecCertificateRef certificate = NULL;
[Util identity:&identity andCertificate:&certificate fromPKCS12Data:p12data withPassphrase:#"asia1215"];
assert(identity != NULL);
NSArray *certArray = [NSArray arrayWithObject:(__bridge id)certificate];
credential = [NSURLCredential credentialWithIdentity:identity certificates:certArray persistence:NSURLCredentialPersistencePermanent];
}
[protocol resolveAuthenticationChallenge:challenge withCredential:credential];
}

SecTrustSetAnchorCertificates with client certificate

I am developing iOS Application. We have custom certificate authority with self-signed ca-cert. Certification authority issues certificates both for users and for https server too. I would like to create iOS application which can authenticate https server using ca certificate and also can communicate to https server using client certificate. I already have the code for communicating with https server using client certificate, but I need to have ca-certificate imported to system keyring. I would like to have ca certificate hard-coded into application. My code looks like this:
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
bool result=NO;
if ([protectionSpace authenticationMethod] == NSURLAuthenticationMethodServerTrust) {
result= YES;
} else if([protectionSpace authenticationMethod] == NSURLAuthenticationMethodClientCertificate) {
result = YES;
}
return result;
}
- (BOOL)shouldTrustProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
CFDataRef certDataRef = (__bridge_retained CFDataRef)self.rootCertData;
SecCertificateRef cert = SecCertificateCreateWithData(NULL, certDataRef);
SecTrustRef serverTrust = protectionSpace.serverTrust;
CFArrayRef certArrayRef = CFArrayCreate(NULL, (void *)&cert, 1, NULL);
SecTrustSetAnchorCertificates(serverTrust, certArrayRef);
SecTrustResultType trustResult;
SecTrustEvaluate(serverTrust, &trustResult);
return trustResult == kSecTrustResultUnspecified;
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
NSLog(#"Did receive auth challange %#",[challenge debugDescription]);
NSURLProtectionSpace *protectionSpace = [challenge protectionSpace];
NSString *authMethod = [protectionSpace authenticationMethod];
if(authMethod == NSURLAuthenticationMethodServerTrust ) {
NSLog(#"Verifying The Trust");
NSURLCredential* cred=[NSURLCredential credentialForTrust:[protectionSpace serverTrust]];
if ([self shouldTrustProtectionSpace:challenge.protectionSpace]) {
[[challenge sender] useCredential:cred forAuthenticationChallenge:challenge];
NSLog(#"OK");
} else {
NSLog(#"FAILED");
[challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge];
}
}
if(authMethod == NSURLAuthenticationMethodClientCertificate ) {
NSLog(#"Trying Certificate");
.....
Everything works like a charm, until server does not require client certificate. At this moment I will receive error The certificate for this server is invalid and execution will never reach point
NSLog(#"Trying Certificate");
When I have .der ca-cert loaded into system keyring, everything works, even client certificate is sent to server, and server can recognize user. I thing that
SecTrustSetAnchorCertificates(serverTrust, certArrayRef);
affects somehow trust, cause when I skip this call, I can simply do:
[[challenge sender] useCredential:cred forAuthenticationChallenge:challenge];
without any error, but I'm not able to verify certificate in this case.
What am I doing wrong?
Big thanks,
Adam
Have a look at this code
https://github.com/dirkx/Security-Pinning-by-CA
which does both by fairly carefully keeping the two trust blocks separate (which you seem to be mixing).

Resources