Я пишу плагин phonegap, который устанавливает как корневой сертификат CA, так и сертификат пользователя в цепочке ключей приложения.
Вот код, используемый для установки сертификата:
NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:certpath];
CFDataRef inPKCS12Data = (CFDataRef)PKCS12Data;
CFStringRef password = (CFStringRef)certPassword;
const void *keys[] = { kSecImportExportPassphrase };
const void *values[] = { password };
CFDictionaryRef optionsDictionary = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
OSStatus securityError = SecPKCS12Import(inPKCS12Data, optionsDictionary, &items);
if (securityError == 0) {
NSLog(@" *** Certificate install Success ***");
} else {
NSLog(@" *** Certificate install Failure ***");
}
Код выше работает отлично (securityError равно 0). Однако я получаю эти ошибки:
unknown apsd[59] <Warning>: <APSCourier: 0xee1ba80>: Stream error occurred for <APSTCPStream: 0x126940>: TLS Error Code=-9844 "peer dropped connection before responding"
unknown securityd[638] <Error>: CFReadStream domain: 12 error: 8
Это означает, что устройство не принимает установленный сертификат, поэтому мне интересно, что сертификат не проверен на сертификат CA Root, установленный на устройстве.
Нужно ли устанавливать сертификат CA Root для приложения?
Любые идеи?
P.S: Я новичок в среде Objective-C и XCode.
EDIT:
Код ниже используется для хранения корневого сертификата CA в цепочке ключей:
NSString *rootCertPath = [[NSBundle mainBundle] pathForResource:@"rootca" ofType:@"cer"];
NSData *rootCertData = [NSData dataWithContentsOfFile:rootCertPath];
OSStatus err = noErr;
SecCertificateRef rootCert = SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef) rootCertData);
CFTypeRef result;
NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
(id)kSecClassCertificate, kSecClass,
rootCert, kSecValueRef,
nil];
err = SecItemAdd((CFDictionaryRef)dict, &result);
if( err == noErr) {
NSLog(@"Install root certificate success");
} else if( err == errSecDuplicateItem ) {
NSLog(@"duplicate root certificate entry");
} else {
NSLog(@"install root certificate failure");
}
ИЗМЕНИТЬ
Кажется, что сертификат не отправляется на сервер. Я думаю, что я должен отправлять сертификат вручную каждый раз, когда выполняется запрос https... Я ищу способ поймать каждый вызов https в телефонном разговоре.