Hey Guys,
I have a quick question for you. I am connecting to a server through my application by means of SSL/HTTPS. I have all the code working to accept an untrusted certificate and connect when the certificate is trusted. Using the below delegate methods:
Code:
// prompted by SSL connection
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
if([protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
{
NSLog(@"Attempting SSL Connection...");
return YES;
}
NSLog(@"Cannot connect through SSL");
return NO;
}
-(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)theChallenge
{
challenge = theChallenge;
// "trust" related authentication challenge, prompted by SSL connection
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
{
//This takes the serverTrust object and checkes it against your keychain
SecTrustResultType result;
SecTrustEvaluate(challenge.protectionSpace.serverTrust, &result);
if (result == kSecTrustResultInvalid)
NSLog(@"SSL Challenge Result: Invalid");
else if (result == kSecTrustResultProceed)
NSLog(@"SSL Challenge Result: Proceed");
else if (result == kSecTrustResultConfirm)
NSLog(@"SSL Challenge Result: Confirm");
else if (result == kSecTrustResultDeny)
NSLog(@"SSL Challenge Result: Deny");
else if (result == kSecTrustResultUnspecified)
NSLog(@"SSL Challenge Result: Unspecified");
else if (result == kSecTrustResultRecoverableTrustFailure)
NSLog(@"SSL Challenge Result: Recoverable Trust Failure");
else if (result == kSecTrustResultFatalTrustFailure)
NSLog(@"SSL Challenge Result: Fatal Trust Failure");
else if (result == kSecTrustResultOtherError)
NSLog(@"SSL Challenge Result: Other Error");
if(result == kSecTrustResultProceed || result == kSecTrustResultConfirm || result == kSecTrustResultUnspecified)
{
[challenge.sender useCredential:[NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust] forAuthenticationChallenge: challenge];
}
else
{
[self promptForTrust];
}
}
}
-(void)promptForTrust
{
// display an error if there are any issues with the connection
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Cannot Verify Server Identity" message:[NSString stringWithFormat:@"xxxx can't verify the identity of \"%@\". Would you like to continue anyway?", [[Model sharedManager] returnServer]] delegate:self cancelButtonTitle:@"Continue" otherButtonTitles:@"Cancel",@"Details",nil];
[alert show];
[alert release];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0)
{
//May need to add a method to add serverTrust to the keychain like Firefox's "Add Exception"
// if the user decides to trust
[challenge.sender useCredential:[NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust] forAuthenticationChallenge: challenge];
}
else if (buttonIndex == 1)
{
// if the user decides not to trust
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
else if (buttonIndex == 2)
{
// show details of certificate
}
}
I am trying to give the option for the user to install the untrusted certificate and view the properties just like when hitting an untrusted server with safari. Any ideas how to do this? I can find a lot of information on making the connection, but am struggling to find this last bit.
Thanks!