【发布时间】:2015-03-07 06:42:36
【问题描述】:
我创建了一个证书(p12 类型),并使用 Apple Configurator 安装到 iPad 上。我现在想在我编写的应用程序中访问该证书,但我似乎找不到它的源示例。有很多关于如何使用证书的示例,但我一直无法找到有关如何将其导入应用程序的任何内容。
有人能指出我正确的方向吗?提前致谢。
* 新 *
所以我尝试按照这里的教程https://developer.apple.com/library/ios/documentation/Security/Conceptual/CertKeyTrustProgGuide/iPhone_Tasks/iPhone_Tasks.html#//apple_ref/doc/uid/TP40001358-CH208-SW13 使用清单 2-1 和清单 2-2。现在我放弃了从钥匙串获取证书,而是从主包中加载它。
NSData *certData = [[NSData alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"myfile.com" ofType:@"pfx"]];
CFDataRef myCertData = (__bridge_retained CFDataRef)(certData);
我不确定我的加载是否正确,但是当我调试时 certData 不是 NULL 并且包含字节。
接下来我修改了两个清单中的代码,因为方法签名与 Objective C 方法签名并不真正匹配。有人在这里帮助我,为什么Apple会以这种方式显示它?函数内部没有代码被修改。
- (OSStatus) extractIdentityAndTrust: (CFDataRef) inPKCS12Data withIdentity:(SecIdentityRef *) outIdentity withTrust:(SecTrustRef *) outTrust withPassword:(CFStringRef) keyPassword
{
OSStatus securityError = errSecSuccess;
const void *keys[] = { kSecImportExportPassphrase };
const void *values[] = { keyPassword };
CFDictionaryRef optionsDictionary = NULL;
optionsDictionary = CFDictionaryCreate(NULL, keys, values, (keyPassword ? 1 : 0), NULL, NULL);
CFArrayRef items = NULL;
securityError = SecPKCS12Import(inPKCS12Data, optionsDictionary, &items);
if (securityError == 0) {
CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex (items, 0);
const void *tempIdentity = NULL;
tempIdentity = CFDictionaryGetValue (myIdentityAndTrust,
kSecImportItemIdentity);
CFRetain(tempIdentity);
*outIdentity = (SecIdentityRef)tempIdentity;
const void *tempTrust = NULL;
tempTrust = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemTrust);
CFRetain(tempTrust);
*outTrust = (SecTrustRef)tempTrust;
}
if (optionsDictionary)
CFRelease(optionsDictionary);
if (items)
CFRelease(items);
return securityError;
}
接下来我修改了 copySummaryString 的方法签名。我还必须在函数内部为“身份”变量添加一个尊重。
- (NSString *)copySummaryString:(SecIdentityRef *) identity
{
// Get the certificate from the identity.
SecCertificateRef myReturnedCertificate = NULL;
OSStatus status = SecIdentityCopyCertificate (*identity, &myReturnedCertificate);
if (status) {
NSLog(@"SecIdentityCopyCertificate failed.\n");
return NULL;
}
CFStringRef certSummary = SecCertificateCopySubjectSummary
(myReturnedCertificate);
NSString* summaryString = [[NSString alloc] initWithString:(__bridge NSString *)certSummary];
CFRelease(certSummary);
return summaryString;
}
最后,在我的调用函数中,我创建了一个身份和信任变量并传递:
[self extractIdentityAndTrust:myCertData withIdentity:identity withTrust:trust withPassword:CFSTR("supersecret")];
[self copySummaryString:identity];
当我尝试运行它时,我得到一个 Thread 1: EXC_BAD_ACCESS(code=1, adress=0x2b) 错误并且 XCode 在以下行暂停:
CFStringRef certSummary = SecCertificateCopySubjectSummary
这段代码没有引用我创建的任何变量,所以我真的很惊讶它在这里崩溃了。加载此证书的最终目标是将其用于 HTTPS。我希望我至少在正确的道路上。
【问题讨论】:
标签: ios objective-c ipad certificate