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/>
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 mails | Author | Date |
|---|---|---|
| Nick Zitzmann | May 17, 01:58 | |
| Dominik Pich | May 17, 11:24 | |
| Nick Zitzmann | May 18, 23:46 |






Cocoa mail archive

