static void free_private_key(struct private_key *key) { free_AlgorithmIdentifier(&key->alg); if (key->private_key) hx509_private_key_free(&key->private_key); der_free_octet_string(&key->localKeyId); free(key); }
static int mem_free(hx509_certs certs, void *data) { struct mem_data *mem = data; unsigned long i; for (i = 0; i < mem->certs.len; i++) hx509_cert_free(mem->certs.val[i]); free(mem->certs.val); for (i = 0; mem->keys && mem->keys[i]; i++) hx509_private_key_free(&mem->keys[i]); free(mem->keys); free(mem->name); free(mem); return 0; }
static int mem_getkeys(hx509_context context, hx509_certs certs, void *data, hx509_private_key **keys) { struct mem_data *mem = data; int i; for (i = 0; mem->keys && mem->keys[i]; i++) ; *keys = calloc(i + 1, sizeof(**keys)); for (i = 0; mem->keys && mem->keys[i]; i++) { (*keys)[i] = _hx509_private_key_ref(mem->keys[i]); if ((*keys)[i] == NULL) { while (--i >= 0) hx509_private_key_free(&(*keys)[i]); hx509_set_error_string(context, 0, ENOMEM, "out of memory"); return ENOMEM; } } (*keys)[i] = NULL; return 0; }
static int collect_private_key(hx509_context context, struct p11_module *p, struct p11_slot *slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object, void *ptr, CK_ATTRIBUTE *query, int num_query) { struct hx509_collector *collector = ptr; hx509_private_key key; heim_octet_string localKeyId; int ret; RSA *rsa; struct p11_rsa *p11rsa; localKeyId.data = query[0].pValue; localKeyId.length = query[0].ulValueLen; ret = hx509_private_key_init(&key, NULL, NULL); if (ret) return ret; rsa = RSA_new(); if (rsa == NULL) _hx509_abort("out of memory"); /* * The exponent and modulus should always be present according to * the pkcs11 specification, but some smartcards leaves it out, * let ignore any failure to fetch it. */ rsa->n = getattr_bn(p, slot, session, object, CKA_MODULUS); rsa->e = getattr_bn(p, slot, session, object, CKA_PUBLIC_EXPONENT); p11rsa = calloc(1, sizeof(*p11rsa)); if (p11rsa == NULL) _hx509_abort("out of memory"); p11rsa->p = p; p11rsa->slot = slot; p11rsa->private_key = object; if (p->ref == 0) _hx509_abort("pkcs11 ref == 0 on alloc"); p->ref++; if (p->ref == UINT_MAX) _hx509_abort("pkcs11 ref == UINT_MAX on alloc"); RSA_set_method(rsa, &p11_rsa_pkcs1_method); ret = RSA_set_app_data(rsa, p11rsa); if (ret != 1) _hx509_abort("RSA_set_app_data"); hx509_private_key_assign_rsa(key, rsa); ret = _hx509_collector_private_key_add(context, collector, hx509_signature_rsa(), key, NULL, &localKeyId); if (ret) { hx509_private_key_free(&key); return ret; } return 0; }
static int set_private_key(hx509_context context, hx509_cert cert, SecKeyRef pkey) { const SubjectPublicKeyInfo *spi; const Certificate *c; struct kc_rsa *kc; RSAPublicKey pk; hx509_private_key key; size_t size; 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"); CFRetain(pkey); kc->pkey = pkey; rsa = RSA_new(); if (rsa == NULL) _hx509_abort("out of memory"); RSA_set_method(rsa, &kc_rsa_pkcs1_method); ret = RSA_set_app_data(rsa, kc); if (ret != 1) _hx509_abort("RSA_set_app_data"); /* * Set up n and e to please RSA_size() */ c = _hx509_get_cert(cert); spi = &c->tbsCertificate.subjectPublicKeyInfo; ret = decode_RSAPublicKey(spi->subjectPublicKey.data, spi->subjectPublicKey.length / 8, &pk, &size); if (ret) { RSA_free(rsa); return 0; } rsa->n = _hx509_int2BN(&pk.modulus); rsa->e = _hx509_int2BN(&pk.publicExponent); free_RSAPublicKey(&pk); kc->keysize = BN_num_bytes(rsa->n); /* * */ hx509_private_key_assign_rsa(key, rsa); _hx509_cert_set_key(cert, key); hx509_private_key_free(&key); return 0; }