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; 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; }