我想将某些CA证书用于TLS验证添加到我的iOS 6应用程序的钥匙串中。证书包含在应用程序包中。我不想要添加任何身份(私钥/证书组合),这在几个示例中有所描述。
SecPKCS12Import
调用不会返回任何错误,但遗憾的是它也不会返回任何证书。
为了让您重现我的步骤,我以Google中级证书('Google Internet Authority')为例,并在下载的PEM证书上运行以下命令:
#convert PEM certificate to PKCS12
openssl pkcs12 -export -in google.pem -nokeys -out google.p12 -passout "pass:google"
#verification
openssl pkcs12 -in google.p12 -passin "pass:google"
MAC verified OK
Bag Attributes: <No Attributes>
subject=/C=US/O=Google Inc/CN=Google Internet Authority
issuer=/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
-----BEGIN CERTIFICATE-----
MIICsDCCAhmgAwIBAgIDFXfhMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT
MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0
[...]
ARlIjNvrPq86fpVg0NOTawALkSqOUMl3MynBQO+spR7EHcRbADQ/JemfTEh2Ycfl
vZqhEFBfurZkX0eTANq98ZvVfpg=
-----END CERTIFICATE-----
之后我将文件捆绑在我的应用程序中,执行以下代码:
NSMutableDictionary * options = [[[NSMutableDictionary alloc] init] autorelease];
[options setObject:@"google" forKey:(id)kSecImportExportPassphrase];
CFArrayRef items = NULL;
NSData *certData = [NSData dataWithContentsOfFile:[NSBundle pathForResource:@"google" ofType:@"p12" inDirectory:[[NSBundle mainBundle] bundlePath]]];
OSStatus result = SecPKCS12Import((CFDataRef)certData, (CFDictionaryRef)options, &items);
assert(result == errSecSuccess);
CFIndex count = CFArrayGetCount(items);
NSLog(@"Certificates found: %ld",count);
控制台结果输出为'找到证书:0'。 certData 变量填充了正确的字节数,如果我更改了提供的密码,结果将更改为 errSecAuthFailed 。
你知道问题可能是什么吗?
答案 0 :(得分:3)
我说这是一个错误,请参阅相关问题SSL Identity Certificate to run an HTTPS Server on iOS和错误SecPKCS12Import returns empty array when certificate expires after Jan 1st 10000。
由于您只需要一个没有私钥的证书,我会从DER格式文件中导入证书。
$ openssl x509 -in google.pem -out google.der -outform DER
$ openssl x509 -in google.der -noout -text
捆绑DER证书文件并导入它:
NSString *path = [[NSBundle mainBundle] pathForResource:@"google" ofType:@"der"];
NSData *derData = [NSData dataWithContentsOfFile:path];
SecCertificateRef cert = SecCertificateCreateWithData(NULL, (CFDataRef)derData);
// add cert to KeyChain or use it as you need
CFRelease(cert);