我不确定此代码失败的原因。我总是得到errSecDuplicateItem
首先,我试图调用SecPKCS12Import。
CFDataRef inId = (CFDataRef)certToImport_;
OSStatus securityError = errSecSuccess;
CFStringRef pw = (CFStringRef)password;
const void *keys[] = { kSecImportExportPassphrase };
const void *values[] = { pw };
CFDictionaryRef myDict = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
securityError = SecPKCS12Import(inId, myDict, &items);
if (securityError == errSecSuccess) {
securityError = [self addIdentityToKeychain:items];
if (securityError == errSecSuccess)
{
securityError = [self addRootCaToKeychain:items];
....
所以从上面的代码中,我调用了addIdentityToKeychain,它返回成功。
- (OSStatus)addIdentityToKeychain:(CFArrayRef)importDict
{
CFDictionaryRef myId = CFArrayGetValueAtIndex(importDict, 0);
const void *tempId = NULL;
tempId = CFDictionaryGetValue(myId,kSecImportItemIdentity);
SecIdentityRef secId = (SecIdentityRef)tempId;
SecCertificateRef certRef;
OSStatus securityError = SecIdentityCopyCertificate(secId, &certRef);
if (securityError == errSecSuccess) {
uniqueLabel_ = [[NSString alloc] initWithString:[self GetUniqueLabel:certRef]];
NSMutableDictionary *secIdentityParams = [[NSMutableDictionary alloc] init];
[secIdentityParams setObject:(id)secId forKey:(id)kSecValueRef];
securityError = SecItemAdd((CFDictionaryRef) secIdentityParams, NULL);
[secIdentityParams release];
}
return securityError;
}
但是当我最终尝试调用addRootCaToKeychain失败时,抱怨我们有一个重复的条目。它第一次失败,随机证书无论如何都无法导入。
- (OSStatus)addRootCaToKeychain:(CFArrayRef)importDict
{
OSStatus securityError = errSecSuccess;
CFDictionaryRef myId = CFArrayGetValueAtIndex(importDict, 0);
NSArray *certs = (NSArray*)CFDictionaryGetValue(myId, kSecImportItemCertChain);
CFIndex cnt = [certs count];
if (cnt)
{
CFIndex i = 0;
while ((i < cnt)) {
SecCertificateRef certRef = (SecCertificateRef)[certs objectAtIndex:i];
NSMutableDictionary *secCertParams = [[NSMutableDictionary alloc] init];
[secCertParams setObject:(id)certRef forKey:(id)kSecValueRef];
[secCertParams setObject:(id)uniqueLabel_ forKey:(id)kSecAttrLabel];
securityError = SecItemAdd((CFDictionaryRef) secCertParams, NULL);
[secCertParams release];
// if we get something other than success or duplicate, we will quit right here and report the error.
if ((securityError != errSecSuccess) && (securityError != errSecDuplicateItem)) {
return securityError;
}
i++;
}
}
return securityError;
}
代码有什么问题?任何的想法?
答案 0 :(得分:0)
在添加addRootCaToKeychain
之前SecItemAdd
进行检查,如果项目已经存在,如下所示:
//adding access key
[secCertParams setObject:(id)key forKey:(id) kSecValueRef];
[secCertParams setObject:(id)uniqueLabel_ forKey:(id) kSecAttrLabel];
//check and removing item if it exists
SecItemDelete((CFDictionaryRef) secCertParams);
//setting data (private key)
[secCertParams setObject:(id) secCertParams forKey:(id)kSecValueData];
另请在此处查看答案以获取更多详细信息:https://stackoverflow.com/a/12387678/5575752