CFArrayRef CUICertificateCredentialProvider::copyMatchingCredentials(CFDictionaryRef attributes, CUIUsageFlags usageFlags, CFIndex *defaultCredentialIndex, CFErrorRef *error) { CFArrayRef identities; CFTypeRef targetName = CUIControllerGetTargetName(_controller); CFMutableArrayRef creds = CFArrayCreateMutable(CFGetAllocator(_controller), 0, &kCFTypeArrayCallBacks); SecCertificateRef certificate = NULL; SecIdentityRef identity = NULL; if (creds == NULL) return NULL; if (attributes) { identity = (SecIdentityRef)CFDictionaryGetValue(attributes, kCUIAttrCredentialSecIdentity); if (identity) { CFRetain(identity); } else { certificate = (SecCertificateRef)CFDictionaryGetValue(attributes, kCUIAttrCredentialSecCertificate); if (certificate) (void)SecIdentityCreateWithCertificate(NULL, certificate, &identity); } } if (identity) { CUICredentialRef credRef = createCredentialWithIdentity(identity, usageFlags); if (credRef) { CFArrayAppendValue(creds, credRef); CFRelease(credRef); } CFRelease(identity); } else if (CUIControllerGetUsageScenario(_controller) == kCUIUsageScenarioNetwork) { identities = copyMatchingIdentities(attributes, targetName, error); if (identities) { for (CFIndex index = 0; index < CFArrayGetCount(identities); index++) { CUICredentialRef credRef; credRef = createCredentialWithIdentity((SecIdentityRef)CFArrayGetValueAtIndex(identities, index), usageFlags); if (credRef == NULL) continue; CFArrayAppendValue(creds, credRef); CFRelease(credRef); } CFRelease(identities); } } return creds; }
static SecIdentityRef CERT_FindIdentityByCertificate (CFTypeRef keychainOrArray, SecCertificateRef certificate) { SecIdentityRef identity = NULL; SecIdentityCreateWithCertificate(keychainOrArray, certificate, &identity); if (!identity) PORT_SetError(SEC_ERROR_NOT_A_RECIPIENT); return identity; }
SecIdentityRef CERT_FindIdentityByUsage(SecKeychainRef keychainOrArray, char *nickname, SECCertUsage usage, Boolean validOnly, void *proto_win) { SecIdentityRef identityRef = NULL; SecCertificateRef cert = CERT_FindCertByNicknameOrEmailAddr(keychainOrArray, nickname); if (!cert) return NULL; SecIdentityCreateWithCertificate(keychainOrArray, cert, &identityRef); CFRelease(cert); return identityRef; }
static int keychain_query(hx509_context context, hx509_certs certs, void *data, const hx509_query *query, hx509_cert *retcert) { CFArrayRef identities = NULL; hx509_cert cert = NULL; CFIndex n, count; int ret; int kdcLookupHack = 0; /* * First to course filtering using security framework .... */ #define FASTER_FLAGS (HX509_QUERY_MATCH_PERSISTENT|HX509_QUERY_PRIVATE_KEY) if ((query->match & FASTER_FLAGS) == 0) return HX509_UNIMPLEMENTED_OPERATION; CFMutableDictionaryRef secQuery = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); /* * XXX this is so broken, SecItem doesn't find the kdc certificte, * and kdc certificates happend to be searched by friendly name, * so find that and mundge on the structure. */ if ((query->match & HX509_QUERY_MATCH_FRIENDLY_NAME) && (query->match & HX509_QUERY_PRIVATE_KEY) && strcmp(query->friendlyname, "O=System Identity,CN=com.apple.kerberos.kdc") == 0) { ((hx509_query *)query)->match &= ~HX509_QUERY_PRIVATE_KEY; kdcLookupHack = 1; } if (kdcLookupHack || (query->match & HX509_QUERY_MATCH_PERSISTENT)) { CFDictionaryAddValue(secQuery, kSecClass, kSecClassCertificate); } else CFDictionaryAddValue(secQuery, kSecClass, kSecClassIdentity); CFDictionaryAddValue(secQuery, kSecReturnRef, kCFBooleanTrue); CFDictionaryAddValue(secQuery, kSecMatchLimit, kSecMatchLimitAll); if (query->match & HX509_QUERY_MATCH_PERSISTENT) { CFDataRef refdata = CFDataCreateWithBytesNoCopy(NULL, query->persistent->data, query->persistent->length, kCFAllocatorNull); CFDictionaryAddValue(secQuery, kSecValuePersistentRef, refdata); CFRelease(refdata); } OSStatus status = SecItemCopyMatching(secQuery, (CFTypeRef *)&identities); CFRelease(secQuery); if (status || identities == NULL) { hx509_clear_error_string(context); return HX509_CERT_NOT_FOUND; } heim_assert(CFArrayGetTypeID() == CFGetTypeID(identities), "return value not an array"); /* * ... now do hx509 filtering */ count = CFArrayGetCount(identities); for (n = 0; n < count; n++) { CFTypeRef secitem = (CFTypeRef)CFArrayGetValueAtIndex(identities, n); #ifndef __APPLE_TARGET_EMBEDDED__ if (query->match & HX509_QUERY_MATCH_PERSISTENT) { SecIdentityRef other = NULL; OSStatus osret; osret = SecIdentityCreateWithCertificate(NULL, (SecCertificateRef)secitem, &other); if (osret == noErr) { ret = hx509_cert_init_SecFramework(context, (void *)other, &cert); CFRelease(other); if (ret) continue; } else { ret = hx509_cert_init_SecFramework(context, (void *)secitem, &cert); if (ret) continue; } } else #endif { ret = hx509_cert_init_SecFramework(context, (void *)secitem, &cert); if (ret) continue; } if (_hx509_query_match_cert(context, query, cert)) { #ifndef __APPLE_TARGET_EMBEDDED__ /* certtool/keychain doesn't glue togheter the cert with keys for system keys */ if (kdcLookupHack) { SecIdentityRef other = NULL; OSStatus osret; osret = SecIdentityCreateWithCertificate(NULL, (SecCertificateRef)secitem, &other); if (osret == noErr) { hx509_cert_free(cert); ret = hx509_cert_init_SecFramework(context, other, &cert); CFRelease(other); if (ret) continue; } } #endif *retcert = cert; break; } hx509_cert_free(cert); } if (kdcLookupHack) ((hx509_query *)query)->match |= HX509_QUERY_PRIVATE_KEY; CFRelease(identities); if (*retcert == NULL) { hx509_clear_error_string(context); return HX509_CERT_NOT_FOUND; } return 0; }