예제 #1
0
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;
}
예제 #2
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;
}