My app simply connects to a web server on a home device and reads some html. It works fine when using http, but now on iOS 8 when using https it does not work.
I use AFNetworking
v1 and override the SSL checks using these override methods (Yes I know in normal circumstances this shouldn't be done and is unsafe etc.., but thats another topic).
[self setAuthenticationChallengeBlock:^(NSURLConnection *connection, NSURLAuthenticationChallenge *challenge) {
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
}
}];
[self setAuthenticationAgainstProtectionSpaceBlock:^BOOL(NSURLConnection *connection, NSURLProtectionSpace *protectionSpace) {
if([[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust]) {
return YES; // Self-signed cert will be accepted
}
// If no other authentication is required, return NO for everything else
// Otherwise maybe YES for NSURLAuthenticationMethodDefault and etc.
return NO;
}];
Now with iOS 8 I get an error like this:
CFNetwork SSLHandshake failed (-9806)
CFNetwork SSLHandshake failed (-9806)
CFNetwork SSLHandshake failed (-9806)
NSURLConnection/CFURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9806)
Error during connection: Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo=0x7b66c110 {NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorCodeKey=-9806, NSErrorFailingURLStringKey=https://xxx.xxx.xxx.xxx:443/live.htm, _kCFStreamErrorDomainKey=3, NSUnderlyingError=0x7c0d8a20 "An SSL error has occurred and a secure connection to the server cannot be made.", NSErrorFailingURLKey=https://xxx.xxx.xxx.xxx:443/Info.live.htm}
I have tried changing over to FSNetworking, and it sometimes
works when setting this:
- (void)connection:(NSURLConnection *)connection
willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
{
NSLog(@"Ignoring SSL");
SecTrustRef trust = challenge.protectionSpace.serverTrust;
NSURLCredential *cred;
cred = [NSURLCredential credentialForTrust:trust];
[challenge.sender useCredential:cred forAuthenticationChallenge:challenge];
return;
}
}
However doing 2 simultaneous request, only 1 will succeed and one will fail with a similar error to above. Only 1 request seems to reach the SSL override point.
Can anyone please shed some light on this and whats changed in iOS 8 to break this, and how I can possibly fix it?
Thanks
I ran into the same kind of problem with iOS 8.
Scenario:
UIWebView
NSURLConnection
s fail with a SSLHandshake
error useCredential:forAuthenticationChallenge
was causing this error (but only after opening a page in https hosted on the same server) when we called SecTrust* methods right after.
This code triggered the error:
[challenge.sender useCredential:urlCredential forAuthenticationChallenge:challenge];
SecTrustRef trustRef = [[challenge protectionSpace] serverTrust];
CFIndex count = SecTrustGetCertificateCount(trustRef);
But this one did not:
SecTrustRef trustRef = [[challenge protectionSpace] serverTrust];
CFIndex count = SecTrustGetCertificateCount(trustRef);
[challenge.sender useCredential:urlCredential forAuthenticationChallenge:challenge];
It is not clear to me why this was causing the SSLHandshake
to fail on iOS 8 but not iOS 7. Maybe AFNetworking does something after useCredential:forAuthenticationChallenge
which is causing the same problem.
The error you are seeing can be found in SecureTransport.h
. It is a transport-level error: the connection failed because it was aborted.
A number of things could be the cause, on both the client and server. This is more likely to happen if the server is asking the client for a certificate and the client isn't providing one, at which point the server decides to give up. If the server is asking the client for a certificate, your delegate method should see an attempt to authenticate using a client certificate in addition to server trust.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With