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 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; p->refcount++; if (p->refcount == 0) _hx509_abort("pkcs11 refcount to high"); 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; }