2010-11-12 4 views
1

Из того, что я вижу в документации MPMoviewPlayerController, NSURLCredentialStorage может быть настроен как альтернатива задачам проверки подлинности NSURLConnection (это полезно для классов более высокого уровня, которые загружают ресурсы из URL-адресов, но абстрагируют NSURLConnection и дона 't предоставить делегата для обработки проблем с проверкой подлинности). Это похоже на установку сертификата в браузере и автоматическое выделение требуемого сертификата, когда это требует определенный адрес.NSURLCredentialStorage и аутентификация сертификата клиента

Чтобы проверить это, я создал свой собственный центр сертификации, сертификат сервера и клиентский сертификат (файл .p12). Я установил https-сервер и успешно протестировал сертификат клиента с помощью браузера с отдельной машины.

Теперь мне нужно иметь сертификат, интегрированный в мое приложение для iPhone.

Я укутан файл p12 и при запуске приложения я делаю это:

NSString *thePath = [[NSBundle mainBundle] pathForResource:@"clientside" ofType:@"p12"]; 
NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath]; 
CFDataRef inPKCS12Data = (CFDataRef)PKCS12Data;  
SecIdentityRef identity; 
SecTrustRef trust; 
extractIdentityAndTrust(inPKCS12Data, &identity, &trust); 

SecCertificateRef certificate = NULL; 
SecIdentityCopyCertificate (identity, &certificate); 

const void *certs[] = {certificate}; 
CFArrayRef certArray = CFArrayCreate(kCFAllocatorDefault, certs, 1, NULL); 

NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identity certificates:(NSArray*)certArray persistence:NSURLCredentialPersistencePermanent]; 

NSURLProtectionSpace *protectionSpace = [[NSURLProtectionSpace alloc] 
             initWithHost: @"myhostname" 
             port: 443 
             protocol: @"https" 
             realm: nil 
             authenticationMethod: NSURLAuthenticationMethodClientCertificate]; 

[[NSURLCredentialStorage sharedCredentialStorage] 
setDefaultCredential: credential 
forProtectionSpace: protectionSpace]; 

Функция extractIdentityAndTrust просто копируется формой сертификатов «Certificate, ключ, и целевые услуги Задача для IOS» страницы документации (Я просто заменил пароль сертификата своим).

Из чего я могу сказать, что личность и сертификат загружены красиво. Если я печатаю объект NSURLCredential в консоли, я получаю что-то вроде этого: <NSURLCredential: 0x140ea0>: (null) (я не могу сказать, является ли это хорошим знаком или нет).

Однако при выполнении setDefaultCredential приложение выходит из строя, не предоставляя много информации.

StackTrace выглядит примерно так:

#0 0x350a41c8 in CFHash 
#1 0x3515180c in __CFBasicHashStandardHashKey 
#2 0x351534e4 in ___CFBasicHashFindBucket_Linear 
#3 0x350a4000 in CFBasicHashFindBucket 
#4 0x350a3ecc in CFDictionaryGetValue 
#5 0x344a0df2 in URLCredentialStorage::setDefaultCredentialForProtectionSpace 
#6 0x3446a5aa in CFURLCredentialStorageSetDefaultCredentialForProtectionSpace 
#7 0x339ec79e in -[NSURLCredentialStorage setDefaultCredential:forProtectionSpace:] 
#8 0x00002612 in -[AVPlayerExampleViewController awakeFromNib] at AVPlayerExampleViewController.m:84 

кажется мне, что там что-то не создать в удостоверении.

Любые идеи о том, как это решить?

EDIT:

Только для тестирования я установил сертификат на iPhone, открыв файл из почты. Я могу получить доступ к страницам через https через Safari, но не через мое приложение.

Единственное, что работает: если я открою NSURLConnection для любого ресурса в защищенном домене, ответьте на didReceiveAuthenticationChallenge (где я загружаю свои учетные данные точно так же, как в приведенном выше коде, только я отправляю его непосредственно отправителю NSURLAuthenticationChallenge) и затем получить доступ к материалам, которые мне действительно нужны, с использованием класса более высокого уровня.

+0

У меня вопрос: где была объявлена ​​«extractIdentityAndTrust»? это ваш метод? или он был включен в библиотеку? Я получаю сообщение об ошибке, говорящее, что он не может найти этот метод. – mtmurdock

+0

Это метод, определенный в моем коде. Если вы посмотрите имя в документации iOS, вы найдете пример кода с этим методом. –

ответ

4

Похоже, что известная проблема заключается в том, что NSURLCredentialStorage работает только для имени пользователя & пароль NSURLCredentials (сертификаты не поддерживаются). К сожалению, в документации ничего не говорится об этом.

+0

Сертификаты не работают вообще? Где вы это читали? Не могли бы вы предоставить ссылку? – mtmurdock

+0

Да, пожалуйста, дайте нам знать, где у вас есть эта информация. Благодаря! – n8gray

+1

Это задокументировано в файле README для кода примера AdvancedURLConnections.Текущая ссылка (что Apple сломается со своим двухнедельным сценарием «перерыв всех ссылок на документацию»): http://developer.apple.com/library/ios/#samplecode/AdvancedURLConnections/Listings/Read_Me_About_AdvancedURLConnections_txt.html#//apple_ref/ doc/uid/DTS40009558-Read_Me_About_AdvancedURLConnections_txt-DontLinkElementID_24 – n8gray