static int match_localkeyid(hx509_context context, struct private_key *value, hx509_certs certs) { hx509_cert cert; hx509_query q; int ret; if (value->localKeyId.length == 0) { hx509_set_error_string(context, 0, HX509_LOCAL_ATTRIBUTE_MISSING, "No local key attribute on private key"); return HX509_LOCAL_ATTRIBUTE_MISSING; } _hx509_query_clear(&q); q.match |= HX509_QUERY_MATCH_LOCAL_KEY_ID; q.local_key_id = &value->localKeyId; ret = hx509_certs_find(context, certs, &q, &cert); if (ret == 0) { if (value->private_key) _hx509_cert_assign_key(cert, value->private_key); hx509_cert_free(cert); } return ret; }
static int set_private_key(hx509_context context, SecKeychainItemRef itemRef, hx509_cert cert) { struct kc_rsa *kc; hx509_private_key key; RSA *rsa; int ret; ret = _hx509_private_key_init(&key, NULL, NULL); if (ret) return ret; kc = calloc(1, sizeof(*kc)); if (kc == NULL) _hx509_abort("out of memory"); kc->item = itemRef; rsa = RSA_new(); if (rsa == NULL) _hx509_abort("out of memory"); /* Argh, fake modulus since OpenSSL API is on crack */ { SecKeychainAttributeList *attrs = NULL; uint32_t size; void *data; rsa->n = BN_new(); if (rsa->n == NULL) abort(); ret = getAttribute(itemRef, kSecKeyKeySizeInBits, &attrs); if (ret) abort(); size = *(uint32_t *)attrs->attr[0].data; SecKeychainItemFreeAttributesAndData(attrs, NULL); kc->keysize = (size + 7) / 8; data = malloc(kc->keysize); memset(data, 0xe0, kc->keysize); BN_bin2bn(data, kc->keysize, rsa->n); free(data); } rsa->e = NULL; RSA_set_method(rsa, &kc_rsa_pkcs1_method); ret = RSA_set_app_data(rsa, kc); if (ret != 1) _hx509_abort("RSA_set_app_data"); _hx509_private_key_assign_rsa(key, rsa); _hx509_cert_assign_key(cert, key); return 0; }
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; }