This may be a problem with the server certificate ....
Check here , I solved the kSecTrustResultRecoverableTrustFailure problem by adding subjectAltName = DNS:example.com to the openssl configuration file, especially in server key generation ...
If you are not using openssl to create it, sorry, but I can help you .. Anyway, if you want to use openssl, here is a good tutorial for creating these keys and signing with its own root certification authority.
From this tutorial, I just changed the openssl server configuration file:
[server]
basicConstraints = critical, CA: FALSE
keyUsage = digitalSignature, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
nsCertType = server
subjectAltName = IP: 10.0.1.5, DNS: office.totendev.com
Hope this helps!
Edition:
My server rating code:
#pragma mark - SERVER Auth Helper //Validate server certificate with challenge + (BOOL)validateServerWithChallenge:(NSURLAuthenticationChallenge *)challenge { //Get server trust management object a set anchor objects to validate it SecTrustSetAnchorCertificates([challenge.protectionSpace serverTrust], (__bridge CFArrayRef)[self allowedCAcertificates]); //Set to server trust management object to JUST ALLOW those anchor objects assigned to it (ABOVE), and disable apple CA trusts SecTrustSetAnchorCertificatesOnly([challenge.protectionSpace serverTrust], YES); //Try to evalute it SecTrustResultType evaluateResult = kSecTrustResultInvalid; //evaluate result OSStatus sanityCheck = SecTrustEvaluate([challenge.protectionSpace serverTrust], &evaluateResult); //Check for no evaluate error if (sanityCheck == noErr) { //Check for result if ([[self class] validateTrustResult:evaluateResult]) { return YES ; } } //deny! return NO ; } //Validate SecTrustResulType + (BOOL)validateTrustResult:(SecTrustResultType)result { switch (result) { case kSecTrustResultProceed: { TDLog(kLogLevelHandshake,nil,@"kSecTrustResultProceed"); return YES ; } break; case kSecTrustResultConfirm: { TDLog(kLogLevelHandshake,nil,@"kSecTrustResultConfirm"); return YES ; } break; case kSecTrustResultUnspecified: { TDLog(kLogLevelHandshake,nil,@"kSecTrustResultUnspecified"); return YES ; } break; case kSecTrustResultDeny: { TDLog(kLogLevelHandshake,nil,@"kSecTrustResultDeny"); return YES ; } break; case kSecTrustResultFatalTrustFailure: { TDLog(kLogLevelHandshake,nil,@"kSecTrustResultFatalTrustFailure"); return NO ; } break; case kSecTrustResultInvalid: { TDLog(kLogLevelHandshake,nil,@"kSecTrustResultInvalid"); return NO ; } break; case kSecTrustResultOtherError: { TDLog(kLogLevelHandshake,nil,@"kSecTrustResultOtherError"); return NO ; } break; case kSecTrustResultRecoverableTrustFailure: { TDLog(kLogLevelHandshake,nil,@"kSecTrustResultRecoverableTrustFailure"); return NO ; } break; default: { TDLog(kLogLevelHandshake,nil,@"unkown certificate evaluate result type! denying..."); return NO ; } break; } }
Hope this helps now :)!