Используйте kSecMatchIssuers для фильтрации сертификатов в KeyChain - PullRequest
0 голосов
/ 23 апреля 2020

Мне нужно найти все сертификаты в KeyChain, для которых указан c Issuer в их цепочке сертификатов. Глядя на документацию, есть ключ kSecMatchIssuers, который, похоже, решит мою проблему.

В документации говорится, что kSecMatchIssuers принимает CFArray в качестве значения, но я получаю недопустимые ошибки параметров, независимо от содержимого CFArray.

В этом сообщении: Swift 4: поисковый запрос цепочки ключей kSecMatchIssuers не соответствует сертификату X.509 говорит, что элементы в CFArray должны иметь определенный формат c (DER закодированный ASN.1). И на этом другом форуме https://forums.developer.apple.com/thread/106083 сказал, чтобы проверить один из сертификатов на моем KeyChain и проверил атрибут kSecAttrIssuer, чтобы получить представление о том, что я должен добавить в CFArray, поэтому я проверил один из сертификаты в связке ключей, проверили указанный атрибут и подтвердили, что это то же значение, которое я получаю при вызове SecCertificateCopyNormalizedSubjectSequence в моем сертификате эмитента, поэтому я ожидаю, что SecItemCopyMatching по крайней мере вернет этот сертификат.

Теперь проблема возникает при вызове SecItemCopyMatching, независимо от того, что я установил в качестве значения KsecMatchIssuers, он всегда возвращает errSecParam (Invalid Parameter), я попытался установить значения CFArray как CFString и CFData, также я попытался установить пустой CFArray в качестве значения для ksecMatchIssuers ( Я ожидаю, что он не потерпит неудачу и не вернет результаты).

Есть ли что-то, чего я здесь не хватает? Должны ли эмитенты быть в другом формате?

SecCertificateRef cert = ... // Parse the certificate from a .cer file;
CFDataRef myCertSubject[1];
myCertSubject[0] = SecCertificateCopyNormalizedSubjectSequence(cert);

CFArrayRef myCertArray = CFArrayCreate(kCFAllocatorDefault, (const void**)myCertSubject, 1, NULL);

NSDictionary *query = [NSDictionary dictionaryWithObjectsAndKeys:
                               kSecClassCertificate, kSecClass,
                                kCFBooleanTrue, kSecReturnAttributes,
                                myCertArray, kSecMatchIssuers,
                               kSecMatchLimitAll, kSecMatchLimit,
                           nil];

CFArrayRef arrayItems = nil;
OSStatus status = SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef *)&arrayItems);
if (status == -50) // OSStatus for invalid param
{
   printf("Error Searching certificates: Invalid Param");
}
...