在Keychain中获取证书



我已经看过了安全框架文档,但我似乎无法找到一种方法来获得给定钥匙链上的所有证书。有办法做到这一点吗?

在挖掘了文档、头文件和源文件之后,我得到了以下代码:

#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);
}

如果您的目标是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

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

http://developer.apple.com/library/mac/文档/安全/概念/CertKeyTrustProgGuide/03任务/tasks.html #//apple_ref/doc/uid/TP40001358-CH205-SW1

相关内容

  • 没有找到相关文章

最新更新