int hx509_certs_iter_f(hx509_context context, hx509_certs certs, int (*func)(hx509_context, void *, hx509_cert), void *ctx) { hx509_cursor cursor; hx509_cert c; int ret; ret = hx509_certs_start_seq(context, certs, &cursor); if (ret) return ret; while (1) { ret = hx509_certs_next_cert(context, certs, cursor, &c); if (ret) break; if (c == NULL) { ret = 0; break; } ret = (*func)(context, ctx, c); hx509_cert_free(c); if (ret) break; } hx509_certs_end_seq(context, certs, cursor); return ret; }
static int file_iter(hx509_context context, hx509_certs certs, void *data, void *iter, hx509_cert *cert) { struct ks_file *f = data; return hx509_certs_next_cert(context, f->certs, iter, cert); }
static int keychain_iter(hx509_context context, hx509_certs certs, void *data, void *cursor, hx509_cert *cert) { struct iter *iter = cursor; OSStatus ret = 0; if (iter->certs) return hx509_certs_next_cert(context, iter->certs, iter->cursor, cert); *cert = NULL; next: if (iter->index < CFArrayGetCount(iter->search)) { CFTypeRef secCert = CFArrayGetValueAtIndex(iter->search, iter->index); ret = hx509_cert_init_SecFramework(context, (void *)secCert, cert); iter->index++; if (ret) goto next; } if (iter->index == CFArrayGetCount(iter->search)) return 0; return ret; }
static int p11_iter(hx509_context context, hx509_certs certs, void *data, void *cursor, hx509_cert *cert) { struct p11_cursor *c = cursor; return hx509_certs_next_cert(context, c->certs, c->cursor, cert); }
static int dir_iter(hx509_context context, hx509_certs certs, void *data, void *iter, hx509_cert *cert) { struct dircursor *d = iter; int ret = 0; *cert = NULL; do { struct dirent *dir; char *fn; if (d->certs) { ret = hx509_certs_next_cert(context, d->certs, d->iter, cert); if (ret) { hx509_certs_end_seq(context, d->certs, d->iter); d->iter = NULL; hx509_certs_free(&d->certs); return ret; } if (*cert) { ret = 0; break; } hx509_certs_end_seq(context, d->certs, d->iter); d->iter = NULL; hx509_certs_free(&d->certs); } dir = readdir(d->dir); if (dir == NULL) { ret = 0; break; } if (strcmp(dir->d_name, ".") == 0 || strcmp(dir->d_name, "..") == 0) continue; if (asprintf(&fn, "FILE:%s/%s", (char *)data, dir->d_name) == -1) return ENOMEM; ret = hx509_certs_init(context, fn, 0, NULL, &d->certs); if (ret == 0) { ret = hx509_certs_start_seq(context, d->certs, &d->iter); if (ret) hx509_certs_free(&d->certs); } /* ignore errors */ if (ret) { d->certs = NULL; ret = 0; } free(fn); } while(ret == 0); return ret; }
static int p12_iter(hx509_context context, hx509_certs certs, void *data, void *cursor, hx509_cert *cert) { struct ks_pkcs12 *p12 = data; return hx509_certs_next_cert(context, p12->certs, cursor, cert); }
static int match_keys(hx509_context context, struct private_key *value, hx509_certs certs) { hx509_cursor cursor; hx509_cert c; int ret, found = HX509_CERT_NOT_FOUND; if (value->private_key == NULL) { hx509_set_error_string(context, 0, HX509_PRIVATE_KEY_MISSING, "No private key to compare with"); return HX509_PRIVATE_KEY_MISSING; } ret = hx509_certs_start_seq(context, certs, &cursor); if (ret) return ret; c = NULL; while (1) { ret = hx509_certs_next_cert(context, certs, cursor, &c); if (ret) break; if (c == NULL) break; if (_hx509_cert_private_key(c)) { hx509_cert_free(c); continue; } ret = _hx509_match_keys(c, value->private_key); if (ret) { _hx509_cert_assign_key(c, value->private_key); hx509_cert_free(c); found = 0; break; } hx509_cert_free(c); } hx509_certs_end_seq(context, certs, cursor); if (found) hx509_clear_error_string(context); return found; }
int hx509_certs_find(hx509_context context, hx509_certs certs, const hx509_query *q, hx509_cert *r) { hx509_cursor cursor; hx509_cert c; int ret; *r = NULL; _hx509_query_statistic(context, 0, q); if (certs->ops->query) return (*certs->ops->query)(context, certs, certs->ops_data, q, r); ret = hx509_certs_start_seq(context, certs, &cursor); if (ret) return ret; c = NULL; while (1) { ret = hx509_certs_next_cert(context, certs, cursor, &c); if (ret) break; if (c == NULL) break; if (_hx509_query_match_cert(context, q, c)) { *r = c; break; } hx509_cert_free(c); } hx509_certs_end_seq(context, certs, cursor); if (ret) return ret; if (c == NULL) { hx509_clear_error_string(context); return HX509_CERT_NOT_FOUND; } return 0; }
int hx509_get_one_cert(hx509_context context, hx509_certs certs, hx509_cert *c) { hx509_cursor cursor; int ret; *c = NULL; ret = hx509_certs_start_seq(context, certs, &cursor); if (ret) return ret; ret = hx509_certs_next_cert(context, certs, cursor, c); if (ret) return ret; hx509_certs_end_seq(context, certs, cursor); return 0; }
static int keychain_iter(hx509_context context, hx509_certs certs, void *data, void *cursor, hx509_cert *cert) { SecKeychainAttributeList *attrs = NULL; SecKeychainAttributeInfo attrInfo; uint32 attrFormat[1] = { 0 }; SecKeychainItemRef itemRef; SecItemAttr item[1]; struct iter *iter = cursor; OSStatus ret; UInt32 len; void *ptr = NULL; if (iter->certs) return hx509_certs_next_cert(context, iter->certs, iter->cursor, cert); *cert = NULL; ret = SecKeychainSearchCopyNext(iter->searchRef, &itemRef); if (ret == errSecItemNotFound) return 0; else if (ret != 0) return EINVAL; /* * Pick out certificate and matching "keyid" */ item[0] = kSecPublicKeyHashItemAttr; attrInfo.count = 1; attrInfo.tag = item; attrInfo.format = attrFormat; ret = SecKeychainItemCopyAttributesAndData(itemRef, &attrInfo, NULL, &attrs, &len, &ptr); if (ret) return EINVAL; ret = hx509_cert_init_data(context, ptr, len, cert); if (ret) goto out; /* * Find related private key if there is one by looking at * kSecPublicKeyHashItemAttr == kSecKeyLabel */ { SecKeychainSearchRef search; SecKeychainAttribute attrKeyid; SecKeychainAttributeList attrList; attrKeyid.tag = kSecKeyLabel; attrKeyid.length = attrs->attr[0].length; attrKeyid.data = attrs->attr[0].data; attrList.count = 1; attrList.attr = &attrKeyid; ret = SecKeychainSearchCreateFromAttributes(NULL, CSSM_DL_DB_RECORD_PRIVATE_KEY, &attrList, &search); if (ret) { ret = 0; goto out; } ret = SecKeychainSearchCopyNext(search, &itemRef); CFRelease(search); if (ret == errSecItemNotFound) { ret = 0; goto out; } else if (ret) { ret = EINVAL; goto out; } set_private_key(context, itemRef, *cert); } out: SecKeychainItemFreeAttributesAndData(attrs, ptr); return ret; }