22

アプリのキーチェーンに CA ルート証明書とユーザー証明書の両方をインストールする phonegap プラグインを作成しています。

証明書のインストールに使用されるコードは次のとおりです。

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 ルート証明書に対して証明書が検証されていないのではないかと考えています。

アプリの CA ルート証明書をインストールする必要がありますか?

何か案は ?

PS: Objective-C と XCode 環境は初めてです。

編集:

以下のコードは、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 要求が行われるたびに証明書を手動で送信する必要があると思います... phonegap ですべての https 呼び出しをキャッチする方法を探しています。

4

3 に答える 3

6

証明書をキーチェーンにインポートするだけでは十分ではありません。新しいルート証明書も、ユーザーまたはシステムによって信頼されています。

SecCertificateRef変数にまだ があると仮定しcertificateて、次のコードを使用して信頼レベルを上げます。

NSDictionary *newTrustSettings = @{(id)kSecTrustSettingsResult: [NSNumber numberWithInt:kSecTrustSettingsResultTrustRoot]};
status = SecTrustSettingsSetTrustSettings(certificate, kSecTrustSettingsDomainUser, (__bridge CFTypeRef)(newTrustSettings));
if (status != errSecSuccess) {
    NSLog(@"Could not change the trust setting for a certificate. Error: %d", status);
    exit(0);
}

信頼レベルを変更すると、ポップアップ ウィンドウでユーザーが変更を受け入れるかどうか尋ねられます。

于 2014-03-02T13:12:58.230 に答える
0

私が探していたものは、システムキーチェーン証明書に「常に信頼」を設定し、

// Trust always, as root certificated.
    NSDictionary *newTrustSettings = @{(id)kSecTrustSettingsResult: [NSNumber numberWithInt:kSecTrustSettingsResultTrustRoot]};
    status = SecTrustSettingsSetTrustSettings(myCertificate, kSecTrustSettingsDomainAdmin, (__bridge CFTypeRef)(newTrustSettings));
于 2015-06-24T11:17:44.147 に答える