iOSアプリケーションを開発しています。自己署名CA証明書を使用したカスタム認証局があります。証明機関は、ユーザーとhttpsサーバーの両方に対しても証明書を発行します。ca証明書を使用してhttpsサーバーを認証し、クライアント証明書を使用してhttpsサーバーと通信できるiOSアプリケーションを作成したいと思います。クライアント証明書を使用してhttpsサーバーと通信するためのコードはすでに持っていますが、ca-certificateをシステムキーリングにインポートする必要があります。アプリケーションにCA証明書をハードコードしてもらいたいのですが。私のコードは次のようになります:
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
bool result=NO;
if ([protectionSpace authenticationMethod] == NSURLAuthenticationMethodServerTrust) {
result= YES;
} else if([protectionSpace authenticationMethod] == NSURLAuthenticationMethodClientCertificate) {
result = YES;
}
return result;
}
- (BOOL)shouldTrustProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
CFDataRef certDataRef = (__bridge_retained CFDataRef)self.rootCertData;
SecCertificateRef cert = SecCertificateCreateWithData(NULL, certDataRef);
SecTrustRef serverTrust = protectionSpace.serverTrust;
CFArrayRef certArrayRef = CFArrayCreate(NULL, (void *)&cert, 1, NULL);
SecTrustSetAnchorCertificates(serverTrust, certArrayRef);
SecTrustResultType trustResult;
SecTrustEvaluate(serverTrust, &trustResult);
return trustResult == kSecTrustResultUnspecified;
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
NSLog(@"Did receive auth challange %@",[challenge debugDescription]);
NSURLProtectionSpace *protectionSpace = [challenge protectionSpace];
NSString *authMethod = [protectionSpace authenticationMethod];
if(authMethod == NSURLAuthenticationMethodServerTrust ) {
NSLog(@"Verifying The Trust");
NSURLCredential* cred=[NSURLCredential credentialForTrust:[protectionSpace serverTrust]];
if ([self shouldTrustProtectionSpace:challenge.protectionSpace]) {
[[challenge sender] useCredential:cred forAuthenticationChallenge:challenge];
NSLog(@"OK");
} else {
NSLog(@"FAILED");
[challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge];
}
}
if(authMethod == NSURLAuthenticationMethodClientCertificate ) {
NSLog(@"Trying Certificate");
.....
サーバーがクライアント証明書を必要としないまで、すべてが魅力のように機能します。この時点でエラーが発生しますこのサーバーの証明書は無効であり、実行はポイントに到達しません
NSLog(@"Trying Certificate");
.der ca-certをシステムキーリングにロードすると、すべてが機能し、クライアント証明書もサーバーに送信され、サーバーはユーザーを認識できます。私はそれを
SecTrustSetAnchorCertificates(serverTrust, certArrayRef);
どういうわけか信頼に影響します、私がこの呼び出しをスキップするとき、私は単にすることができます:
[[challenge sender] useCredential:cred forAuthenticationChallenge:challenge];
エラーは発生していませんが、この場合、証明書を確認できません。
私は何が間違っているのですか?
どうもありがとう、アダム