Я разрабатываю приложение iOS. У нас есть собственный орган сертификации с самоподписанным ca-cert. Орган сертификации выдает сертификаты как для пользователей, так и для https-сервера. Я хотел бы создать приложение iOS, которое может аутентифицировать https-сервер, используя сертификат ca, а также может связываться с сервером https с использованием сертификата клиента. У меня уже есть код для связи с сервером https с использованием сертификата клиента, но мне нужно, чтобы ca-сертификат импортировался в системный keyring. Я хотел бы иметь сертификат с жестким кодом в приложении. Мой код выглядит так:SecTrustSetAnchorCertificates с сертификатом клиента
- (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 ча-CERT загружены в системе брелока, все работает, даже сертификат клиента отправляется на сервер , и сервер может распознать пользователя. Я вещь, что
SecTrustSetAnchorCertificates(serverTrust, certArrayRef);
влияет как-то доверие, вызвать, когда я пропустить этот вызов, я могу просто сделать:
[[challenge sender] useCredential:cred forAuthenticationChallenge:challenge];
без каких-либо ошибок, но я не в состоянии проверить сертификат в этом случае.
Что я делаю неправильно?
Большое спасибо, Адам