macos 获取钥匙串中的证书

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5767957/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 07:59:18  来源:igfitidea点击:

Get Certificates in Keychain

cocoasecuritymacoskeychainappkit

提问by Dylan Copeland

I've looked over the Security framework documentation but I can't seem to be able to find a way to get all of the certificates on a given keychain. Are there methods to accomplish this?

我查看了安全框架文档,但似乎无法找到一种方法来获取给定钥匙串上的所有证书。有没有办法做到这一点?

回答by

After mining the documentation, header files, and source files, I've come up with the following code:

在挖掘文档、头文件和源文件后,我想出了以下代码:

#import <Security/Security.h>

- (void)logMessageForStatus:(OSStatus)status
               functionName:(NSString *)functionName
{
    CFStringRef errorMessage;
    errorMessage = SecCopyErrorMessageString(status, NULL);
    NSLog(@"error after %@: %@", functionName, (NSString *)errorMessage);
    CFRelease(errorMessage);  
}

- (void)listCertificates
{
    OSStatus status;
    SecKeychainSearchRef search = NULL;

    // The first argument being NULL indicates the user's current keychain list
    status = SecKeychainSearchCreateFromAttributes(NULL,
        kSecCertificateItemClass, NULL, &search);

    if (status != errSecSuccess) {
        [self logMessageForStatus:status
                     functionName:@"SecKeychainSearchCreateFromAttributes()"];
        return;
    }

    SecKeychainItemRef searchItem = NULL;

    while (SecKeychainSearchCopyNext(search, &searchItem) != errSecItemNotFound) {
        SecKeychainAttributeList attrList;
        CSSM_DATA certData;

        attrList.count = 0;
        attrList.attr = NULL;

        status = SecKeychainItemCopyContent(searchItem, NULL, &attrList,
            (UInt32 *)(&certData.Length),
            (void **)(&certData.Data));

        if (status != errSecSuccess) {
            [self logMessageForStatus:status
                         functionName:@"SecKeychainItemCopyContent()"];
            CFRelease(searchItem);
            continue;
        }

        // At this point you should have a valid CSSM_DATA structure
        // representing the certificate

        SecCertificateRef certificate;
        status = SecCertificateCreateFromData(&certData, CSSM_CERT_X_509v3,
            CSSM_CERT_ENCODING_BER, &certificate);

        if (status != errSecSuccess) {
            [self logMessageForStatus:status
                         functionName:@"SecCertificateCreateFromData()"];
            SecKeychainItemFreeContent(&attrList, certData.Data);
            CFRelease(searchItem);
            continue;
        }

        // Do whatever you want to do with the certificate
        // For instance, print its common name (if there's one)

        CFStringRef commonName = NULL;
        SecCertificateCopyCommonName(certificate, &commonName);
        NSLog(@"common name = %@", (NSString *)commonName);
        if (commonName) CFRelease(commonName);

        SecKeychainItemFreeContent(&attrList, certData.Data);
        CFRelease(searchItem);
    }

    CFRelease(search);
}

回答by Karoy Lorentey

If you target Mac OS 10.6 or later, you can use SecItemCopyMatchingto easily query the keychain:

如果您的目标是 Mac OS 10.6 或更高版本,您可以使用SecItemCopyMatching它轻松查询钥匙串:

SecKeychainRef keychain = ...
NSDictionary *query = [NSDictionary dictionaryWithObjectsAndKeys:
                       kSecClassCertificate, kSecClass, 
                       [NSArray arrayWithObject:(id)keychain], kSecMatchSearchList,
                       kCFBooleanTrue, kSecReturnRef,
                       kSecMatchLimitAll, kSecMatchLimit,
                       nil];
NSArray *items = nil;
OSStatus status = SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef *)&items);
if (status) {
    if (status != errSecItemNotFound)
        LKKCReportError(status, @"Can't search keychain");
    return nil;
}
return [items autorelease]; // items contains all SecCertificateRefs in keychain

Note that you must not use this to implement certificate validation — the presence of a CA certificate in a keychain does not indicate that it is trusted to sign certificates for any particular policy. See the Certificate, Key, and Trust Programming Guideto learn how to do certificate validation with the Keychain.

请注意,您不能使用它来实现证书验证——钥匙串中 CA 证书的存在并不表明它可以为任何特定策略签署证书。请参阅证书、密钥和信任编程指南以了解如何使用钥匙串进行证书验证。

http://developer.apple.com/library/mac/#documentation/Security/Conceptual/CertKeyTrustProgGuide/03tasks/tasks.html#//apple_ref/doc/uid/TP40001358-CH205-SW1

http://developer.apple.com/library/mac/#documentation/Security/Conceptual/CertKeyTrustProgGuide/03tasks/tasks.html#//apple_ref/doc/uid/TP40001358-CH205-SW1