Objective-C指定的项目已存在于钥匙串[iOS]中

时间:2016-06-22 13:38:15

标签: ios objective-c iphone certificate

我不确定此代码失败的原因。我总是得到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;
    }

代码有什么问题?任何的想法?

1 个答案:

答案 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