Хранение сертификатов и идентификационных данных в связке ключей ios? - PullRequest
0 голосов
/ 20 марта 2019

Резюме

У меня есть файл p12, который я импортирую в свое приложение. Я хочу сохранить сертификат вместе с его идентификацией на цепочке для ключей. Этот сертификат будет использоваться для аутентификации на сервере с использованием аутентификации сертификата клиента TLS.

Я изо всех сил пытался сохранить сертификат и личность в связке ключей. Насколько я понимаю, личность является его личным ключом сертификата.

Я использовал документацию Apple, чтобы помочь мне, но она не работает, как ожидалось.

Приведенный ниже код основан на документах Apple Хранение сертификатов и Хранение удостоверений

Хранение кода


    //Storing a Certificate Identity 
    if(CFDictionaryContainsKey(pkcs12Contents, kSecImportItemIdentity))
    {
        //Grab the identity from the dictionary
         SecIdentityRef identity = (SecIdentityRef)CFDictionaryGetValue(pkcs12Contents, kSecImportItemIdentity);
                CFRetain(identity);

         NSDictionary* dict = @{ (id)kSecClass:      (id)kSecClassIdentity, 
                                (id)kSecValueRef:   (__bridge id)identity,
                                (id)kSecAttrLabel:  "some_unique_tag_for_id",
                              };

         OSStatus securityError = SecItemAdd((CFDictionaryRef)dict, NULL);
         //More Code
    }

    //Storing the Certificate
    if(CFDictionaryContainsKey(pkcs12Contents, kSecImportItemCertChain))
    {

        CFArrayRef certs = (CFArrayRef) CFDictionaryGetValue(pkcs12Contents, kSecImportItemCertChain);
        CFRetain(certs);
        SecCertificateRef cert = (SecCertificateRef) CFArrayGetValueAtIndex(certs, 0);

        NSDictionary* dict = @{ (id)kSecValueRef:   (__bridge id)cert,
                                        (id)kSecClass:      (id)kSecClassCertificate,
                                        (id)kSecAttrLabel:  "some_unique_tag_for_cert,
                                        };

        OSStatus securityError = SecItemAdd((__bridge CFDictionaryRef)dict, NULL);

      //more code 
    }

поисковый код


+(SecIdentityRef)getLoginCertIdentityFromKeyChain
{
    NSDictionary *getquery = @{ (id)kSecClass:     (id)kSecClassIdentity,
                                (id)kSecAttrLabel: (id)KEY_LOGIN_CERT_ID_TAG,
                                (id)kSecReturnRef: @YES,
                                };

    SecIdentityRef identity = NULL;
    OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)getquery,
                                          (CFTypeRef *)&identity);

    if (status != errSecSuccess)
    {
        if (status == errSecItemNotFound)
        {
            return nil; 
        }
       //  Add Error Cases Here
    }

    return identity;
}

+(SecCertificateRef)getLoginCertChainFromKeyChain
{
    NSDictionary *getquery = @{ (id)kSecClass:     (id)kSecClassCertificate,
                                (id)kSecAttrLabel: (id)KEY_LOGIN_CERT_TAG,
                                (id)kSecReturnRef: @YES,
                                };

    SecCertificateRef cert = NULL;

    OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)getquery,
                                          (CFTypeRef *)&cert);
    if (status != errSecSuccess)
    {
    }

    return cert;
}

Проблемы

1. Не могу получить личность

Я успешно сохранил и получил сертификат. Когда я сохраняю личность, я получаю errSecSuccess, что означает, что личность успешно добавлена ​​в цепочку для ключей. Однако, когда я пытаюсь получить Идентификацию из цепочки для ключей, используя мой getLoginCertIdentityFromKeyChain, я получаю errSecItemNotFound. Это абсолютно бессмысленно для меня.

2. Сертификат уже существует, но не добавлен.

Чтобы обойти первую проблему, я удалил (id) kSecClass: (id) kSecClassIdentity

NSDictionary* dict = @{ (id)kSecValueRef:   (__bridge id)identity,
                      (id)kSecAttrLabel:  KEY_LOGIN_CERT_ID_TAG,
                      };

OSStatus securityError = SecItemAdd((CFDictionaryRef)dict, NULL);

Это позволило мне получить личность из цепочки для ключей. Не знаю, почему это работает, но это работает. Проблема сейчас в том, что при попытке сохранить сертификат я получаю errSecDuplicateItem. Почему это уже сохранено? Я гарантировал, что я удалил все из цепочки для ключей.

Становится страннее, когда я пытаюсь получить этот сертификат, который "уже сохранен", используя мой getLoginCertChainFromKeyChain метод, я получаю errSecItemNotFound.

Я полагаю, что проблема заключается в том, что сертификат хранится под тегом идентификации? Я подтвердил это, но я до сих пор не знаю почему. Документация Apple делает ужасную работу, объясняя, что происходит.

3. Объяснение SecIdentityCopyCertificate

Наконец, это больше вопрос. Выдает ли SecIdentityCopyCertificate тот же сертификат, который я получил при получении сертификата с использованием идентификационной метки?

Спасибо

Любое понимание того, что здесь происходит, будет высоко оценено.

...