Skip navigation.
 
ml[SOLVED] Re: NSURLDownload and handling HTTPS certificates
FROM : Nick Zitzmann
DATE : Fri May 18 23:46:58 2007

On May 17, 2007, at 3:24 AM, Dominik Pich wrote:

> hack: override a private method / categorize it.
> ..... I had the same issue but as I dont remember the name, search 
> the archives of this list or macnetworkprog.


I figured it out, and did something similar to this (which should 
also work with NSURLConnection in case anyone's wondering), with 
"theDownload" being the name of a retained NSURLDownload/WebDownload 
ivar:

@interface NSURLRequest (SomePrivateAPIs)
+ (BOOL)allowsAnyHTTPSCertificateForHost:(id)fp8;
+ (void)setAllowsAnyHTTPSCertificate:(BOOL)fp8 forHost:(id)fp12;
@end


- (void)download:(NSURLDownload *)download didFailWithError:(NSError 
*)error
{
   if ([[error domain] isEqualToString:NSURLErrorDomain] && [error 
code] <= NSURLErrorServerCertificateHasBadDate && [error code] >= 
NSURLErrorServerCertificateNotYetValid)    // handle certificate failures
   {
       NSURL *failingURL = [[error userInfo] 
objectForKey:@"NSErrorFailingURLKey"];
       NSArray *badCerts = [[error userInfo] 
objectForKey:@"NSErrorPeerCertificateChainKey"];
       SecPolicySearchRef policySearch;
       
       if (SecPolicySearchCreate(CSSM_CERT_X_509v3, &CSSMOID_APPLE_TP_SSL, 
NULL, &policySearch) == noErr)
       {
           SecPolicyRef policy;
           
           while (SecPolicySearchCopyNext(policySearch, &policy) == noErr)    // 
this should only go through once
           {
               SecTrustRef trust;
               
               if (SecTrustCreateWithCertificates((CFArrayRef)badCerts, policy, 
&trust) == noErr)
               {
                   SFCertificateTrustPanel *panel = [[SFCertificateTrustPanel 
alloc] init];
                   int result;
                   NSString *host = [failingURL host];
                   
                   [panel setDefaultButtonTitle:@"Continue"];
                   [panel setAlternateButtonTitle:@"Cancel"];
                   
                   if ([panel respondsToSelector:@selector
(setInformativeText:)])    // this method is in Tiger but is undocumented
                       [panel performSelector:@selector(setInformativeText:) 
withObject:@"Some informative text here..."];
                   [panel setShowsHelp:YES];
                   
                   result = [panel runModalForTrust:trust message:@"Insert your own 
title here..."];
                   
                   [panel release];
                   [theDownload autorelease];
                   CFRelease(trust);
                   CFRelease(policy);
                   CFRelease(policySearch);
                   if (result == NSOKButton)
                   {
                       [NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:
[failingURL host]];    // unfortunately we have to use a private API here
                       theDownload = [[WebDownload alloc] initWithRequest:
[NSURLRequest requestWithURL:failingURL] delegate:self];    // once 
we've set the certificate to be ignored, then start the download again
                   }
                   else
                   {
                       // The user clicked on Cancel...
                   }
                   return;
               }
           }
       }
   }
   else
   {
       // Handle other download errors here.
   }
}


Nick Zitzmann
<http://www.chronosnet.com/>

Related mailsAuthorDate
mlNSURLDownload and handling HTTPS certificates Nick Zitzmann May 17, 01:58
mlRe: NSURLDownload and handling HTTPS certificates Dominik Pich May 17, 11:24
ml[SOLVED] Re: NSURLDownload and handling HTTPS certificates Nick Zitzmann May 18, 23:46