iPhone: проверка подлинности клиента HTTPS - PullRequest
20 голосов
/ 22 сентября 2009

Я борюсь с проверкой подлинности сертификата клиента. Когда серверу нужны учетные данные (в данном случае сертификат), этот метод вызывается из NSURLConnection делегат:

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge

Я хочу загрузить сертификат из файла, заполнить учетные данные и запустить этот метод:

[[challenge sender] useCredential:[self credential] forAuthenticationChallenge:challenge];

Но я не знаю, как инициализировать (или заполнить) параметр SecIdentityRef . Вот мой код, который создает учетные данные:

NSString *certPath = [[NSBundle mainBundle] pathForResource:@"certificate" ofType:@"cer"];
NSData *certData = [[NSData alloc] initWithContentsOfFile:certPath];

SecIdentityRef myIdentity;  // ???

SecCertificateRef myCert = SecCertificateCreateWithData(NULL, (CFDataRef)certData);
[certData release];
SecCertificateRef certArray[1] = { myCert };
CFArrayRef myCerts = CFArrayCreate(NULL, (void *)certArray, 1, NULL);
CFRelease(myCert);
NSURLCredential *credential = [NSURLCredential credentialWithIdentity:myIdentity
                                  certificates:(NSArray *)myCerts
                                   persistence:NSURLCredentialPersistencePermanent];
CFRelease(myCerts);

Кто-нибудь знает, как это решить? Спасибо.


Я наконец нашел решение, но здесь появилась новая проблема:

мой клиент не отправляет сертификат на сервер. После того, как сервер запросит сертификат, приложение запускает этот метод:

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge

и я заполняю учетные данные (как я упоминал выше), но соединение заканчивается с ошибкой: NSURLErrorDomain -1206 . По логам сервера клиентский сертификат не отправляется приложением.

Кто-нибудь имеет опыт такого поведения? Нужно ли как-то проверять сертификат в приложении? Или что-нибудь еще, чтобы заставить это работать? Я могу предоставить свой текущий код, если это поможет. Спасибо за любые идеи ...

Ответы [ 3 ]

4 голосов
/ 11 ноября 2009

Я использую эти шаги:

  1. извлечение SecIdentityRef из файла сертификата pkcs12 с помощью функции SecPKCS12Import
  2. используйте функцию SecIdentityCopyCertificate, чтобы получить SecCertificateRef

а остальные (инициализация учетных данных) такие же, как в моем вопросе ... Я могу добавить сюда больше кода, если хотите. Обратите внимание, что в симуляторе iphone есть ошибка (http://openradar.appspot.com/7090030), поэтому в симуляторе невозможно работать с большим количеством сертификатов.

1 голос
/ 30 сентября 2014

Вы также можете искать личность в связке ключей, если храните эту информацию там:

+ (SecIdentityRef)dumpSecIdentityRef
{
OSStatus    err;
CFArrayRef  result;
CFIndex     resultCount;
CFIndex     resultIndex;

result = NULL;
err = SecItemCopyMatching((__bridge CFDictionaryRef) [NSDictionary dictionaryWithObjectsAndKeys:
                                                      (__bridge id)kSecClassIdentity,
                                                      kSecClass, kSecMatchLimitAll,
                                                      kSecMatchLimit, kCFBooleanTrue,
                                                      kSecReturnRef, kCFBooleanTrue,
                                                      kSecReturnAttributes, nil],
                          (CFTypeRef *) &result);

if ((result != NULL) && (err == noErr)) {

    NSMutableArray *identitiesArray = [NSMutableArray new];

    resultCount = CFArrayGetCount(result);
    for (resultIndex = 0; resultIndex < resultCount; resultIndex++) {
        NSDictionary *  thisResult;
        thisResult = (__bridge NSDictionary *) CFArrayGetValueAtIndex(result, resultIndex);
        NSLog(@"%@", (__bridge id)(result));
        [identitiesArray addObject:thisResult];
    }

    CFRelease(result);
    //TO DO - choose correct identity object from array.
    SecIdentityRef myIdentity = (__bridge SecIdentityRef)([[identitiesArray objectAtIndex:0] valueForKey:@"v_Ref"]);

    return myIdentity;
}
return nil;
}
0 голосов
/ 30 октября 2009

Конечно проблема была с симулятором iPhone в xcode :) После обновления до версии 3.1 он начал работать ...

...