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_start(hx509_context context, hx509_certs certs, void *data, void **cursor) { struct ks_file *f = data; return hx509_certs_start_seq(context, f->certs, cursor); }
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_start(hx509_context context, hx509_certs certs, void *data, void **cursor) { struct ks_pkcs12 *p12 = data; return hx509_certs_start_seq(context, p12->certs, cursor); }
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 p11_iter_start(hx509_context context, hx509_certs certs, void *data, void **cursor) { struct p11_module *p = data; struct p11_cursor *c; int ret; size_t i; c = malloc(sizeof(*c)); if (c == NULL) { hx509_clear_error_string(context); return ENOMEM; } ret = hx509_certs_init(context, "MEMORY:pkcs11-iter", 0, NULL, &c->certs); if (ret) { free(c); return ret; } for (i = 0 ; i < p->num_slots; i++) { if (p->slot[i].certs == NULL) continue; ret = hx509_certs_merge(context, c->certs, p->slot[i].certs); if (ret) { hx509_certs_free(&c->certs); free(c); return ret; } } ret = hx509_certs_start_seq(context, c->certs, &c->cursor); if (ret) { hx509_certs_free(&c->certs); free(c); return 0; } *cursor = c; return 0; }
static int keychain_iter_start(hx509_context context, hx509_certs certs, void *data, void **cursor) { struct ks_keychain *ctx = data; struct iter *iter; iter = calloc(1, sizeof(*iter)); if (iter == NULL) { hx509_set_error_string(context, 0, ENOMEM, "out of memory"); return ENOMEM; } if (ctx->anchors) { CFArrayRef anchors; int ret; int i; ret = hx509_certs_init(context, "MEMORY:ks-file-create", 0, NULL, &iter->certs); if (ret) { free(iter); return ret; } ret = SecTrustCopyAnchorCertificates(&anchors); if (ret != 0) { hx509_certs_free(&iter->certs); free(iter); hx509_set_error_string(context, 0, ENOMEM, "Can't get trust anchors from Keychain"); return ENOMEM; } for (i = 0; i < CFArrayGetCount(anchors); i++) { SecCertificateRef cr; hx509_cert cert; CSSM_DATA cssm; cr = (SecCertificateRef)CFArrayGetValueAtIndex(anchors, i); SecCertificateGetData(cr, &cssm); ret = hx509_cert_init_data(context, cssm.Data, cssm.Length, &cert); if (ret) continue; ret = hx509_certs_add(context, iter->certs, cert); hx509_cert_free(cert); } CFRelease(anchors); } if (iter->certs) { int ret; ret = hx509_certs_start_seq(context, iter->certs, &iter->cursor); if (ret) { hx509_certs_free(&iter->certs); free(iter); return ret; } } else { OSStatus ret; ret = SecKeychainSearchCreateFromAttributes(ctx->keychain, kSecCertificateItemClass, NULL, &iter->searchRef); if (ret) { free(iter); hx509_set_error_string(context, 0, ret, "Failed to start search for attributes"); return ENOMEM; } } *cursor = iter; return 0; }
static int keychain_iter_start(hx509_context context, hx509_certs certs, void *data, void **cursor) { #ifndef __APPLE_TARGET_EMBEDDED__ struct ks_keychain *ctx = data; #endif struct iter *iter; iter = calloc(1, sizeof(*iter)); if (iter == NULL) { hx509_set_error_string(context, 0, ENOMEM, "out of memory"); return ENOMEM; } #ifndef __APPLE_TARGET_EMBEDDED__ if (ctx->anchors) { CFArrayRef anchors; int ret; int i; ret = hx509_certs_init(context, "MEMORY:ks-file-create", 0, NULL, &iter->certs); if (ret) { free(iter); return ret; } ret = SecTrustCopyAnchorCertificates(&anchors); if (ret != 0) { hx509_certs_free(&iter->certs); free(iter); hx509_set_error_string(context, 0, ENOMEM, "Can't get trust anchors from Keychain"); return ENOMEM; } for (i = 0; i < CFArrayGetCount(anchors); i++) { SecCertificateRef cr; hx509_cert cert; CFDataRef dataref; cr = (SecCertificateRef)CFArrayGetValueAtIndex(anchors, i); dataref = SecCertificateCopyData(cr); if (dataref == NULL) continue; ret = hx509_cert_init_data(context, CFDataGetBytePtr(dataref), CFDataGetLength(dataref), &cert); CFRelease(dataref); if (ret) continue; ret = hx509_certs_add(context, iter->certs, cert); hx509_cert_free(cert); } CFRelease(anchors); if (ret != 0) { hx509_certs_free(&iter->certs); free(iter); hx509_set_error_string(context, 0, ret, "Failed to add cert"); return ret; } } if (iter->certs) { int ret; ret = hx509_certs_start_seq(context, iter->certs, &iter->cursor); if (ret) { hx509_certs_free(&iter->certs); free(iter); return ret; } } else #endif { OSStatus ret; const void *keys[] = { kSecClass, kSecReturnRef, kSecMatchLimit }; const void *values[] = { kSecClassCertificate, kCFBooleanTrue, kSecMatchLimitAll }; CFDictionaryRef secQuery; secQuery = CFDictionaryCreate(NULL, keys, values, sizeof(keys) / sizeof(*keys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); ret = SecItemCopyMatching(secQuery, (CFTypeRef *)&iter->search); CFRelease(secQuery); if (ret) { free(iter); return ENOMEM; } } *cursor = iter; return 0; }