カスタム iOS 6 アプリで HTTPS を使用していくつかの Web リソースにアクセスしたいと考えています。一部のターゲット サーバーは、デフォルトでは iOS に含まれていないが、デバイスのキーチェーンに手動で追加された CA によって署名された証明書を使用しています。したがって、すべての URL は、警告やエラーなしで Safari で開くことができます。
私が達成したいのは、Safari と同じ動作です。Safari が Web サイトを信頼する場合は Web サイトをロードし、エラーが発生した場合は Web サイトのロードを拒否します。インストールされた証明書は場合によって変更される可能性があるため、アプリケーションのリソースに証明書を手動で含めたくありません。これは、ここ SO で多くの質問が寄せられていることです。
私の問題は、kSecTrustResultProceedSecTrustEvaluate
を返すことができないことです。私に何ができるか分かりますか?
myがNOcanAuthenticateAgainstProtectionSpace
を返した場合、iOS はそれ自体でサーバー証明書のチェックを処理しますが、(Safari のように) 追加でインストールされた証明書をチェックしていないようです。
これまでに得たものを理解しようとするコードを次に示します。
- (void)viewDidLoad
{
[super viewDidLoad];
[self loadURLWithString:@"https://myserver.com"];
}
+ (BOOL) isChallenge: (NSURLAuthenticationChallenge*) challenge validForConnection: (NSURLConnection*)conn{
SecTrustRef serverTrust=[[challenge protectionSpace] serverTrust];
//Some magic here?
// Check Server Certificate
SecTrustResultType evalResult;
if(SecTrustEvaluate(serverTrust,&evalResult) != errSecSuccess){
NSLog(@"Call to SecTrustEvaluate failed");
return NO;
}
if(evalResult != kSecTrustResultProceed){
NSLog(@"Server certificate invalid");
return NO;
}
NSLog(@"Server certificate valid");
return YES;
}
- (void)loadURLWithString: (NSString*)str{
NSURLConnection *conn =
[NSURLConnection connectionWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:str]] delegate:self];
[conn start];
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge{
if([[self class] isChallenge:challenge validForConnection:connection])
[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
else
[challenge.sender cancelAuthenticationChallenge:challenge];
}
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace{
return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
NSLog(@"Failed with error: %@",error);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
NSLog(@"loading complete");
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
}