Example #1
0
static void
pkcs11ecdsa_destroy(dst_key_t *key) {
	pk11_object_t *ec = key->keydata.pkey;
	CK_ATTRIBUTE *attr;

	if (ec == NULL)
		return;

	INSIST((ec->object == CK_INVALID_HANDLE) || ec->ontoken);

	for (attr = pk11_attribute_first(ec);
	     attr != NULL;
	     attr = pk11_attribute_next(ec, attr))
		switch (attr->type) {
		case CKA_LABEL:
		case CKA_ID:
		case CKA_EC_PARAMS:
		case CKA_EC_POINT:
		case CKA_VALUE:
			FREECURVE();
			break;
		}
	if (ec->repr != NULL) {
		memset(ec->repr, 0, ec->attrcnt * sizeof(*attr));
		isc_mem_put(key->mctx,
			    ec->repr,
			    ec->attrcnt * sizeof(*attr));
	}
	memset(ec, 0, sizeof(*ec));
	isc_mem_put(key->mctx, ec, sizeof(*ec));
	key->keydata.pkey = NULL;
}
Example #2
0
static void
pkcs11gost_destroy(dst_key_t *key) {
	pk11_object_t *gost = key->keydata.pkey;
	CK_ATTRIBUTE *attr;

	if (gost == NULL)
		return;

	INSIST((gost->object == CK_INVALID_HANDLE) || gost->ontoken);

	for (attr = pk11_attribute_first(gost);
	     attr != NULL;
	     attr = pk11_attribute_next(gost, attr))
		switch (attr->type) {
		case CKA_VALUE:
		case CKA_VALUE2:
			if (attr->pValue != NULL) {
				memset(attr->pValue, 0, attr->ulValueLen);
				isc_mem_put(key->mctx,
					    attr->pValue,
					    attr->ulValueLen);
			}
			break;
		}
	if (gost->repr != NULL) {
		memset(gost->repr, 0, gost->attrcnt * sizeof(*attr));
		isc_mem_put(key->mctx,
			    gost->repr,
			    gost->attrcnt * sizeof(*attr));
	}
	memset(gost, 0, sizeof(*gost));
	isc_mem_put(key->mctx, gost, sizeof(*gost));
	key->keydata.pkey = NULL;
}
Example #3
0
static isc_result_t
pkcs11gost_fromdns(dst_key_t *key, isc_buffer_t *data) {
    pk11_object_t *gost;
    isc_region_t r;
    CK_ATTRIBUTE *attr;

    isc_buffer_remainingregion(data, &r);
    if (r.length == 0)
        return (ISC_R_SUCCESS);
    if (r.length != ISC_GOST_PUBKEYLENGTH)
        return (DST_R_INVALIDPUBLICKEY);

    gost = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*gost));
    if (gost == NULL)
        return (ISC_R_NOMEMORY);
    memset(gost, 0, sizeof(*gost));
    gost->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr));
    if (gost->repr == NULL)
        goto nomemory;
    gost->attrcnt = 1;

    attr = gost->repr;
    attr->type = CKA_VALUE;
    attr->pValue = isc_mem_get(key->mctx, ISC_GOST_PUBKEYLENGTH);
    if (attr->pValue == NULL)
        goto nomemory;
    memmove((CK_BYTE_PTR) attr->pValue, r.base, ISC_GOST_PUBKEYLENGTH);
    attr->ulValueLen = ISC_GOST_PUBKEYLENGTH;

    isc_buffer_forward(data, ISC_GOST_PUBKEYLENGTH);
    key->keydata.pkey = gost;
    key->key_size = ISC_GOST_KEYSIZE;
    return (ISC_R_SUCCESS);

nomemory:
    for (attr = pk11_attribute_first(gost);
            attr != NULL;
            attr = pk11_attribute_next(gost, attr))
        switch (attr->type) {
        case CKA_VALUE:
            if (attr->pValue != NULL) {
                memset(attr->pValue, 0, attr->ulValueLen);
                isc_mem_put(key->mctx,
                            attr->pValue,
                            attr->ulValueLen);
            }
            break;
        }
    if (gost->repr != NULL) {
        memset(gost->repr, 0, gost->attrcnt * sizeof(*attr));
        isc_mem_put(key->mctx,
                    gost->repr,
                    gost->attrcnt * sizeof(*attr));
    }
    memset(gost, 0, sizeof(*gost));
    isc_mem_put(key->mctx, gost, sizeof(*gost));
    return (ISC_R_NOMEMORY);
}
Example #4
0
CK_ATTRIBUTE *
pk11_attribute_bytype(const pk11_object_t *obj, CK_ATTRIBUTE_TYPE type) {
	CK_ATTRIBUTE *attr;

	for(attr = pk11_attribute_first(obj);
	    attr != NULL;
	    attr = pk11_attribute_next(obj, attr))
		if (attr->type == type)
			return (attr);
	return (NULL);
}
Example #5
0
static isc_result_t
pkcs11rsa_todns(const dst_key_t *key, isc_buffer_t *data) {
	pk11_object_t *rsa;
	CK_ATTRIBUTE *attr;
	isc_region_t r;
	unsigned int e_bytes = 0, mod_bytes = 0;
	CK_BYTE *exponent = NULL, *modulus = NULL;

	REQUIRE(key->keydata.pkey != NULL);

	rsa = key->keydata.pkey;

	for (attr = pk11_attribute_first(rsa);
	     attr != NULL;
	     attr = pk11_attribute_next(rsa, attr))
		switch (attr->type) {
		case CKA_PUBLIC_EXPONENT:
			exponent = (CK_BYTE *) attr->pValue;
			e_bytes = (unsigned int) attr->ulValueLen;
			break;
		case CKA_MODULUS:
			modulus = (CK_BYTE *) attr->pValue;
			mod_bytes = (unsigned int) attr->ulValueLen;
			break;
		}
	REQUIRE((exponent != NULL) && (modulus != NULL));

	isc_buffer_availableregion(data, &r);

	if (e_bytes < 256) {	/*%< key exponent is <= 2040 bits */
		if (r.length < 1)
			return (ISC_R_NOSPACE);
		isc_buffer_putuint8(data, (isc_uint8_t) e_bytes);
		isc_region_consume(&r, 1);
	} else {
		if (r.length < 3)
			return (ISC_R_NOSPACE);
		isc_buffer_putuint8(data, 0);
		isc_buffer_putuint16(data, (isc_uint16_t) e_bytes);
		isc_region_consume(&r, 3);
	}

	if (r.length < e_bytes + mod_bytes)
		return (ISC_R_NOSPACE);

	memmove(r.base, exponent, e_bytes);
	isc_region_consume(&r, e_bytes);
	memmove(r.base, modulus, mod_bytes);

	isc_buffer_add(data, e_bytes + mod_bytes);

	return (ISC_R_SUCCESS);
}
Example #6
0
static void
pkcs11rsa_destroy(dst_key_t *key) {
	pk11_object_t *rsa = key->keydata.pkey;
	CK_ATTRIBUTE *attr;

	if (rsa == NULL)
		return;

	INSIST((rsa->object == CK_INVALID_HANDLE) || rsa->ontoken);

	for (attr = pk11_attribute_first(rsa);
	     attr != NULL;
	     attr = pk11_attribute_next(rsa, attr))
		switch (attr->type) {
		case CKA_LABEL:
		case CKA_ID:
		case CKA_MODULUS:
		case CKA_PUBLIC_EXPONENT:
		case CKA_PRIVATE_EXPONENT:
		case CKA_PRIME_1:
		case CKA_PRIME_2:
		case CKA_EXPONENT_1:
		case CKA_EXPONENT_2:
		case CKA_COEFFICIENT:
			if (attr->pValue != NULL) {
				memset(attr->pValue, 0, attr->ulValueLen);
				isc_mem_put(key->mctx,
					    attr->pValue,
					    attr->ulValueLen);
			}
			break;
		}
	if (rsa->repr != NULL) {
		memset(rsa->repr, 0, rsa->attrcnt * sizeof(*attr));
		isc_mem_put(key->mctx,
			    rsa->repr,
			    rsa->attrcnt * sizeof(*attr));
	}
	memset(rsa, 0, sizeof(*rsa));
	isc_mem_put(key->mctx, rsa, sizeof(*rsa));
	key->keydata.pkey = NULL;
}
Example #7
0
static isc_result_t
pkcs11rsa_createctx_sign(dst_key_t *key, dst_context_t *dctx) {
	CK_RV rv;
	CK_MECHANISM mech = { 0, NULL, 0 };
	CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY;
	CK_KEY_TYPE keyType = CKK_RSA;
	CK_ATTRIBUTE keyTemplate[] =
	{
		{ CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
		{ CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
		{ CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
		{ CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
		{ CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
		{ CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
		{ CKA_MODULUS, NULL, 0 },
		{ CKA_PUBLIC_EXPONENT, NULL, 0 },
		{ CKA_PRIVATE_EXPONENT, NULL, 0 },
		{ CKA_PRIME_1, NULL, 0 },
		{ CKA_PRIME_2, NULL, 0 },
		{ CKA_EXPONENT_1, NULL, 0 },
		{ CKA_EXPONENT_2, NULL, 0 },
		{ CKA_COEFFICIENT, NULL, 0 }
	};
	CK_ATTRIBUTE *attr;
	CK_SLOT_ID slotid;
	pk11_object_t *rsa;
	pk11_context_t *pk11_ctx;
	isc_result_t ret;
	unsigned int i;

	REQUIRE(key->key_alg == DST_ALG_RSAMD5 ||
		key->key_alg == DST_ALG_RSASHA1 ||
		key->key_alg == DST_ALG_NSEC3RSASHA1 ||
		key->key_alg == DST_ALG_RSASHA256 ||
		key->key_alg == DST_ALG_RSASHA512);

	rsa = key->keydata.pkey;

	pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx,
						  sizeof(*pk11_ctx));
	if (pk11_ctx == NULL)
		return (ISC_R_NOMEMORY);
	memset(pk11_ctx, 0, sizeof(*pk11_ctx));
	if (rsa->ontoken)
		slotid = rsa->slot;
	else
		slotid = pk11_get_best_token(OP_RSA);
	ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE,
			       rsa->reqlogon, NULL, slotid);
	if (ret != ISC_R_SUCCESS)
		goto err;

	if (rsa->ontoken && (rsa->object != CK_INVALID_HANDLE)) {
		pk11_ctx->ontoken = rsa->ontoken;
		pk11_ctx->object = rsa->object;
		goto token_key;
	}

	for (attr = pk11_attribute_first(rsa);
	     attr != NULL;
	     attr = pk11_attribute_next(rsa, attr))
		switch (attr->type) {
		case CKA_MODULUS:
			INSIST(keyTemplate[6].type == attr->type);
			keyTemplate[6].pValue = isc_mem_get(dctx->mctx,
							    attr->ulValueLen);
			if (keyTemplate[6].pValue == NULL)
				DST_RET(ISC_R_NOMEMORY);
			memmove(keyTemplate[6].pValue, attr->pValue,
				attr->ulValueLen);
			keyTemplate[6].ulValueLen = attr->ulValueLen;
			break;
		case CKA_PUBLIC_EXPONENT:
			INSIST(keyTemplate[7].type == attr->type);
			keyTemplate[7].pValue = isc_mem_get(dctx->mctx,
							    attr->ulValueLen);
			if (keyTemplate[7].pValue == NULL)
				DST_RET(ISC_R_NOMEMORY);
			memmove(keyTemplate[7].pValue, attr->pValue,
				attr->ulValueLen);
			keyTemplate[7].ulValueLen = attr->ulValueLen;
			break;
		case CKA_PRIVATE_EXPONENT:
			INSIST(keyTemplate[8].type == attr->type);
			keyTemplate[8].pValue = isc_mem_get(dctx->mctx,
							    attr->ulValueLen);
			if (keyTemplate[8].pValue == NULL)
				DST_RET(ISC_R_NOMEMORY);
			memmove(keyTemplate[8].pValue, attr->pValue,
				attr->ulValueLen);
			keyTemplate[8].ulValueLen = attr->ulValueLen;
			break;
		case CKA_PRIME_1:
			INSIST(keyTemplate[9].type == attr->type);
			keyTemplate[9].pValue = isc_mem_get(dctx->mctx,
							    attr->ulValueLen);
			if (keyTemplate[9].pValue == NULL)
				DST_RET(ISC_R_NOMEMORY);
			memmove(keyTemplate[9].pValue, attr->pValue,
				attr->ulValueLen);
			keyTemplate[9].ulValueLen = attr->ulValueLen;
			break;
		case CKA_PRIME_2:
			INSIST(keyTemplate[10].type == attr->type);
			keyTemplate[10].pValue = isc_mem_get(dctx->mctx,
							    attr->ulValueLen);
			if (keyTemplate[10].pValue == NULL)
				DST_RET(ISC_R_NOMEMORY);
			memmove(keyTemplate[10].pValue, attr->pValue,
				attr->ulValueLen);
			keyTemplate[10].ulValueLen = attr->ulValueLen;
			break;
		case CKA_EXPONENT_1:
			INSIST(keyTemplate[11].type == attr->type);
			keyTemplate[11].pValue = isc_mem_get(dctx->mctx,
							     attr->ulValueLen);
			if (keyTemplate[11].pValue == NULL)
				DST_RET(ISC_R_NOMEMORY);
			memmove(keyTemplate[11].pValue, attr->pValue,
				attr->ulValueLen);
			keyTemplate[11].ulValueLen = attr->ulValueLen;
			break;
		case CKA_EXPONENT_2:
			INSIST(keyTemplate[12].type == attr->type);
			keyTemplate[12].pValue = isc_mem_get(dctx->mctx,
							     attr->ulValueLen);
			if (keyTemplate[12].pValue == NULL)
				DST_RET(ISC_R_NOMEMORY);
			memmove(keyTemplate[12].pValue, attr->pValue,
				attr->ulValueLen);
			keyTemplate[12].ulValueLen = attr->ulValueLen;
			break;
		case CKA_COEFFICIENT:
			INSIST(keyTemplate[13].type == attr->type);
			keyTemplate[13].pValue = isc_mem_get(dctx->mctx,
							     attr->ulValueLen);
			if (keyTemplate[13].pValue == NULL)
				DST_RET(ISC_R_NOMEMORY);
			memmove(keyTemplate[13].pValue, attr->pValue,
				attr->ulValueLen);
			keyTemplate[13].ulValueLen = attr->ulValueLen;
			break;
		}
	pk11_ctx->object = CK_INVALID_HANDLE;
	pk11_ctx->ontoken = ISC_FALSE;
	PK11_RET(pkcs_C_CreateObject,
		 (pk11_ctx->session,
		  keyTemplate, (CK_ULONG) 14,
		  &pk11_ctx->object),
		 ISC_R_FAILURE);

    token_key:

	switch (dctx->key->key_alg) {
	case DST_ALG_RSAMD5:
		mech.mechanism = CKM_MD5_RSA_PKCS;
		break;
	case DST_ALG_RSASHA1:
	case DST_ALG_NSEC3RSASHA1:
		mech.mechanism = CKM_SHA1_RSA_PKCS;
		break;
	case DST_ALG_RSASHA256:
		mech.mechanism = CKM_SHA256_RSA_PKCS;
		break;
	case DST_ALG_RSASHA512:
		mech.mechanism = CKM_SHA512_RSA_PKCS;
		break;
	default:
		INSIST(0);
	}

	PK11_RET(pkcs_C_SignInit,
		 (pk11_ctx->session, &mech, pk11_ctx->object),
		 ISC_R_FAILURE);

	dctx->ctxdata.pk11_ctx = pk11_ctx;

	for (i = 6; i <= 13; i++)
		if (keyTemplate[i].pValue != NULL) {
			memset(keyTemplate[i].pValue, 0,
			       keyTemplate[i].ulValueLen);
			isc_mem_put(dctx->mctx,
				    keyTemplate[i].pValue,
				    keyTemplate[i].ulValueLen);
		}

	return (ISC_R_SUCCESS);

    err:
	if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE))
		(void) pkcs_C_DestroyObject(pk11_ctx->session,
					    pk11_ctx->object);
	for (i = 6; i <= 13; i++)
		if (keyTemplate[i].pValue != NULL) {
			memset(keyTemplate[i].pValue, 0,
			       keyTemplate[i].ulValueLen);
			isc_mem_put(dctx->mctx,
				    keyTemplate[i].pValue,
				    keyTemplate[i].ulValueLen);
		}
	pk11_return_session(pk11_ctx);
	memset(pk11_ctx, 0, sizeof(*pk11_ctx));
	isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx));

	return (ret);
}
Example #8
0
static isc_result_t
pkcs11gost_createctx_verify(dst_key_t *key, dst_context_t *dctx) {
	CK_RV rv;
	CK_MECHANISM mech = { CKM_GOSTR3410_WITH_GOSTR3411, NULL, 0 };
	CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY;
	CK_KEY_TYPE keyType = CKK_GOSTR3410;
	CK_ATTRIBUTE keyTemplate[] =
	{
		{ CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
		{ CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
		{ CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
		{ CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
		{ CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) },
		{ CKA_VALUE, NULL, 0 },
		{ CKA_GOSTR3410_PARAMS, pk11_gost_a_paramset,
		  (CK_ULONG) sizeof(pk11_gost_a_paramset) },
		{ CKA_GOSTR3411_PARAMS, pk11_gost_paramset,
		  (CK_ULONG) sizeof(pk11_gost_paramset) }
	};
	CK_ATTRIBUTE *attr;
	pk11_object_t *gost;
	pk11_context_t *pk11_ctx;
	isc_result_t ret;
	unsigned int i;

	pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx,
						  sizeof(*pk11_ctx));
	if (pk11_ctx == NULL)
		return (ISC_R_NOMEMORY);
	ret = pk11_get_session(pk11_ctx, OP_GOST, ISC_FALSE, ISC_FALSE, NULL,
			       pk11_get_best_token(OP_GOST));
	if (ret != ISC_R_SUCCESS)
		goto err;

	gost = key->keydata.pkey;
	if (gost->ontoken && (gost->object != CK_INVALID_HANDLE)) {
		pk11_ctx->ontoken = gost->ontoken;
		pk11_ctx->object = gost->object;
		goto token_key;
	}

	for (attr = pk11_attribute_first(gost);
	     attr != NULL;
	     attr = pk11_attribute_next(gost, attr))
		switch (attr->type) {
		case CKA_VALUE:
			INSIST(keyTemplate[5].type == attr->type);
			keyTemplate[5].pValue = isc_mem_get(dctx->mctx,
							    attr->ulValueLen);
			if (keyTemplate[5].pValue == NULL)
				DST_RET(ISC_R_NOMEMORY);
			memmove(keyTemplate[5].pValue, attr->pValue,
				attr->ulValueLen);
			keyTemplate[5].ulValueLen = attr->ulValueLen;
			break;
		}
	pk11_ctx->object = CK_INVALID_HANDLE;
	pk11_ctx->ontoken = ISC_FALSE;
	PK11_RET(pkcs_C_CreateObject,
		 (pk11_ctx->session,
		  keyTemplate, (CK_ULONG) 8,
		  &pk11_ctx->object),
		 ISC_R_FAILURE);

    token_key:

	PK11_RET(pkcs_C_VerifyInit,
		 (pk11_ctx->session, &mech, pk11_ctx->object),
		 ISC_R_FAILURE);

	dctx->ctxdata.pk11_ctx = pk11_ctx;

	for (i = 5; i <= 5; i++)
		if (keyTemplate[i].pValue != NULL) {
			memset(keyTemplate[i].pValue, 0,
			       keyTemplate[i].ulValueLen);
			isc_mem_put(dctx->mctx,
				    keyTemplate[i].pValue,
				    keyTemplate[i].ulValueLen);
		}

	return (ISC_R_SUCCESS);

    err:
	if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE))
		(void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object);
	for (i = 5; i <= 5; i++)
		if (keyTemplate[i].pValue != NULL) {
			memset(keyTemplate[i].pValue, 0,
			       keyTemplate[i].ulValueLen);
			isc_mem_put(dctx->mctx,
				    keyTemplate[i].pValue,
				    keyTemplate[i].ulValueLen);
		}
	pk11_return_session(pk11_ctx);
	memset(pk11_ctx, 0, sizeof(*pk11_ctx));
	isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx));

	return (ret);
}
static isc_result_t
pkcs11dsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
	pk11_object_t *dsa;
	isc_region_t r;
	unsigned int t, p_bytes;
	CK_BYTE *prime, *subprime, *base, *pub_key;
	CK_ATTRIBUTE *attr;

	isc_buffer_remainingregion(data, &r);
	if (r.length == 0)
		return (ISC_R_SUCCESS);

	dsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dsa));
	if (dsa == NULL)
		return (ISC_R_NOMEMORY);
	memset(dsa, 0, sizeof(*dsa));

	t = (unsigned int) *r.base;
	isc_region_consume(&r, 1);
	if (t > 8) {
		memset(dsa, 0, sizeof(*dsa));
		isc_mem_put(key->mctx, dsa, sizeof(*dsa));
		return (DST_R_INVALIDPUBLICKEY);
	}
	p_bytes = 64 + 8 * t;

	if (r.length < ISC_SHA1_DIGESTLENGTH + 3 * p_bytes) {
		memset(dsa, 0, sizeof(*dsa));
		isc_mem_put(key->mctx, dsa, sizeof(*dsa));
		return (DST_R_INVALIDPUBLICKEY);
	}

	subprime = r.base;
	isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH);

	prime = r.base;
	isc_region_consume(&r, p_bytes);

	base = r.base;
	isc_region_consume(&r, p_bytes);

	pub_key = r.base;
	isc_region_consume(&r, p_bytes);

	key->key_size = p_bytes * 8;

	isc_buffer_forward(data, 1 + ISC_SHA1_DIGESTLENGTH + 3 * p_bytes);

	dsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 4);
	if (dsa->repr == NULL)
		goto nomemory;
	memset(dsa->repr, 0, sizeof(*attr) * 4);
	dsa->attrcnt = 4;

	attr = dsa->repr;
	attr[0].type = CKA_PRIME;
	attr[0].pValue = isc_mem_get(key->mctx, p_bytes);
	if (attr[0].pValue == NULL)
		goto nomemory;
	memmove(attr[0].pValue, prime, p_bytes);
	attr[0].ulValueLen = p_bytes;

	attr[1].type = CKA_SUBPRIME;
	attr[1].pValue = isc_mem_get(key->mctx, ISC_SHA1_DIGESTLENGTH);
	if (attr[1].pValue == NULL)
		goto nomemory;
	memmove(attr[1].pValue, subprime, ISC_SHA1_DIGESTLENGTH);
	attr[1].ulValueLen = ISC_SHA1_DIGESTLENGTH;

	attr[2].type = CKA_BASE;
	attr[2].pValue = isc_mem_get(key->mctx, p_bytes);
	if (attr[2].pValue == NULL)
		goto nomemory;
	memmove(attr[2].pValue, base, p_bytes);
	attr[2].ulValueLen = p_bytes;

	attr[3].type = CKA_VALUE;
	attr[3].pValue = isc_mem_get(key->mctx, p_bytes);
	if (attr[3].pValue == NULL)
		goto nomemory;
	memmove(attr[3].pValue, pub_key, p_bytes);
	attr[3].ulValueLen = p_bytes;

	key->keydata.pkey = dsa;

	return (ISC_R_SUCCESS);

    nomemory:
	for (attr = pk11_attribute_first(dsa);
	     attr != NULL;
	     attr = pk11_attribute_next(dsa, attr))
		switch (attr->type) {
		case CKA_PRIME:
		case CKA_SUBPRIME:
		case CKA_BASE:
		case CKA_VALUE:
			if (attr->pValue != NULL) {
				memset(attr->pValue, 0, attr->ulValueLen);
				isc_mem_put(key->mctx,
					    attr->pValue,
					    attr->ulValueLen);
			}
			break;
		}
	if (dsa->repr != NULL) {
		memset(dsa->repr, 0, dsa->attrcnt * sizeof(*attr));
		isc_mem_put(key->mctx,
			    dsa->repr,
			    dsa->attrcnt * sizeof(*attr));
	}
	memset(dsa, 0, sizeof(*dsa));
	isc_mem_put(key->mctx, dsa, sizeof(*dsa));
	return (ISC_R_NOMEMORY);
}
Example #10
0
static isc_result_t
pkcs11ecdsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
	CK_RV rv;
	CK_MECHANISM mech = { CKM_ECDSA, NULL, 0 };
	CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
	CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY;
	CK_KEY_TYPE keyType = CKK_EC;
	CK_ATTRIBUTE keyTemplate[] =
	{
		{ CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
		{ CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
		{ CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
		{ CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
		{ CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) },
		{ CKA_EC_PARAMS, NULL, 0 },
		{ CKA_EC_POINT, NULL, 0 }
	};
	CK_ATTRIBUTE *attr;
	CK_BYTE digest[ISC_SHA384_DIGESTLENGTH];
	CK_ULONG dgstlen;
	pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx;
	dst_key_t *key = dctx->key;
	pk11_object_t *ec = key->keydata.pkey;
	isc_result_t ret = ISC_R_SUCCESS;
	unsigned int i;

	REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
		key->key_alg == DST_ALG_ECDSA384);
	REQUIRE(ec != NULL);

	if (key->key_alg == DST_ALG_ECDSA256)
		dgstlen = ISC_SHA256_DIGESTLENGTH;
	else
		dgstlen = ISC_SHA384_DIGESTLENGTH;

	PK11_RET(pkcs_C_DigestFinal,
		 (pk11_ctx->session, digest, &dgstlen),
		 ISC_R_FAILURE);

	for (attr = pk11_attribute_first(ec);
	     attr != NULL;
	     attr = pk11_attribute_next(ec, attr))
		switch (attr->type) {
		case CKA_EC_PARAMS:
			INSIST(keyTemplate[5].type == attr->type);
			keyTemplate[5].pValue = isc_mem_get(dctx->mctx,
							    attr->ulValueLen);
			if (keyTemplate[5].pValue == NULL)
				DST_RET(ISC_R_NOMEMORY);
			memmove(keyTemplate[5].pValue, attr->pValue,
				attr->ulValueLen);
			keyTemplate[5].ulValueLen = attr->ulValueLen;
			break;
		case CKA_EC_POINT:
			INSIST(keyTemplate[6].type == attr->type);
			keyTemplate[6].pValue = isc_mem_get(dctx->mctx,
							    attr->ulValueLen);
			if (keyTemplate[6].pValue == NULL)
				DST_RET(ISC_R_NOMEMORY);
			memmove(keyTemplate[6].pValue, attr->pValue,
				attr->ulValueLen);
			keyTemplate[6].ulValueLen = attr->ulValueLen;
			break;
		}
	pk11_ctx->object = CK_INVALID_HANDLE;
	pk11_ctx->ontoken = ISC_FALSE;
	PK11_RET(pkcs_C_CreateObject,
		 (pk11_ctx->session,
		  keyTemplate, (CK_ULONG) 7,
		  &hKey),
		 ISC_R_FAILURE);

	PK11_RET(pkcs_C_VerifyInit,
		 (pk11_ctx->session, &mech, hKey),
		 ISC_R_FAILURE);

	PK11_RET(pkcs_C_Verify,
		 (pk11_ctx->session,
		  digest, dgstlen,
		  (CK_BYTE_PTR) sig->base, (CK_ULONG) sig->length),
		 DST_R_VERIFYFAILURE);

 err:

	if (hKey != CK_INVALID_HANDLE)
		(void) pkcs_C_DestroyObject(pk11_ctx->session, hKey);
	for (i = 5; i <= 6; i++)
		if (keyTemplate[i].pValue != NULL) {
			memset(keyTemplate[i].pValue, 0,
			       keyTemplate[i].ulValueLen);
			isc_mem_put(dctx->mctx,
				    keyTemplate[i].pValue,
				    keyTemplate[i].ulValueLen);
		}
	pk11_return_session(pk11_ctx);
	memset(pk11_ctx, 0, sizeof(*pk11_ctx));
	isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx));
	dctx->ctxdata.pk11_ctx = NULL;

	return (ret);
}
Example #11
0
static isc_result_t
pkcs11ecdsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
	CK_RV rv;
	CK_MECHANISM mech = { CKM_ECDSA, NULL, 0 };
	CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
	CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY;
	CK_KEY_TYPE keyType = CKK_EC;
	CK_ATTRIBUTE keyTemplate[] =
	{
		{ CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
		{ CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
		{ CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
		{ CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
		{ CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
		{ CKA_EC_PARAMS, NULL, 0 },
		{ CKA_VALUE, NULL, 0 }
	};
	CK_ATTRIBUTE *attr;
	CK_BYTE digest[ISC_SHA384_DIGESTLENGTH];
	CK_ULONG dgstlen;
	CK_ULONG siglen;
	pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx;
	dst_key_t *key = dctx->key;
	pk11_object_t *ec = key->keydata.pkey;
	isc_region_t r;
	isc_result_t ret = ISC_R_SUCCESS;
	unsigned int i;

	REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
		key->key_alg == DST_ALG_ECDSA384);
	REQUIRE(ec != NULL);

	if (key->key_alg == DST_ALG_ECDSA256) {
		dgstlen = ISC_SHA256_DIGESTLENGTH;
		siglen = DNS_SIG_ECDSA256SIZE;
	} else {
		siglen = DNS_SIG_ECDSA384SIZE;
		dgstlen = ISC_SHA384_DIGESTLENGTH;
	}

	PK11_RET(pkcs_C_DigestFinal,
		 (pk11_ctx->session, digest, &dgstlen),
		 ISC_R_FAILURE);

	isc_buffer_availableregion(sig, &r);
	if (r.length < siglen)
		DST_RET(ISC_R_NOSPACE);

	if (ec->ontoken && (ec->object != CK_INVALID_HANDLE)) {
		pk11_ctx->ontoken = ec->ontoken;
		pk11_ctx->object = ec->object;
		goto token_key;
	}

	for (attr = pk11_attribute_first(ec);
	     attr != NULL;
	     attr = pk11_attribute_next(ec, attr))
		switch (attr->type) {
		case CKA_EC_PARAMS:
			INSIST(keyTemplate[5].type == attr->type);
			keyTemplate[5].pValue = isc_mem_get(dctx->mctx,
							    attr->ulValueLen);
			if (keyTemplate[5].pValue == NULL)
				DST_RET(ISC_R_NOMEMORY);
			memmove(keyTemplate[5].pValue, attr->pValue,
				attr->ulValueLen);
			keyTemplate[5].ulValueLen = attr->ulValueLen;
			break;
		case CKA_VALUE:
			INSIST(keyTemplate[6].type == attr->type);
			keyTemplate[6].pValue = isc_mem_get(dctx->mctx,
							    attr->ulValueLen);
			if (keyTemplate[6].pValue == NULL)
				DST_RET(ISC_R_NOMEMORY);
			memmove(keyTemplate[6].pValue, attr->pValue,
				attr->ulValueLen);
			keyTemplate[6].ulValueLen = attr->ulValueLen;
			break;
		}
	pk11_ctx->object = CK_INVALID_HANDLE;
	pk11_ctx->ontoken = ISC_FALSE;
	PK11_RET(pkcs_C_CreateObject,
		 (pk11_ctx->session,
		  keyTemplate, (CK_ULONG) 7,
		  &hKey),
		 ISC_R_FAILURE);

 token_key:

	PK11_RET(pkcs_C_SignInit,
		 (pk11_ctx->session, &mech,
		  pk11_ctx->ontoken ? pk11_ctx->object : hKey),
		 ISC_R_FAILURE);

	PK11_RET(pkcs_C_Sign,
		 (pk11_ctx->session,
		  digest, dgstlen,
		  (CK_BYTE_PTR) r.base, &siglen),
		 DST_R_SIGNFAILURE);

	isc_buffer_add(sig, (unsigned int) siglen);

 err:

	if (hKey != CK_INVALID_HANDLE)
		(void) pkcs_C_DestroyObject(pk11_ctx->session, hKey);
	for (i = 5; i <= 6; i++)
		if (keyTemplate[i].pValue != NULL) {
			memset(keyTemplate[i].pValue, 0,
			       keyTemplate[i].ulValueLen);
			isc_mem_put(dctx->mctx,
				    keyTemplate[i].pValue,
				    keyTemplate[i].ulValueLen);
		}
	pk11_return_session(pk11_ctx);
	memset(pk11_ctx, 0, sizeof(*pk11_ctx));
	isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx));
	dctx->ctxdata.pk11_ctx = NULL;

	return (ret);
}
Example #12
0
static isc_result_t
pkcs11rsa_createctx_verify(dst_key_t *key, unsigned int maxbits,
			   dst_context_t *dctx) {
	CK_RV rv;
	CK_MECHANISM mech = { 0, NULL, 0 };
	CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY;
	CK_KEY_TYPE keyType = CKK_RSA;
	CK_ATTRIBUTE keyTemplate[] =
	{
		{ CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
		{ CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
		{ CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
		{ CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
		{ CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) },
		{ CKA_MODULUS, NULL, 0 },
		{ CKA_PUBLIC_EXPONENT, NULL, 0 },
	};
	CK_ATTRIBUTE *attr;
	pk11_object_t *rsa;
	pk11_context_t *pk11_ctx;
	isc_result_t ret;
	unsigned int i;

	REQUIRE(key->key_alg == DST_ALG_RSAMD5 ||
		key->key_alg == DST_ALG_RSASHA1 ||
		key->key_alg == DST_ALG_NSEC3RSASHA1 ||
		key->key_alg == DST_ALG_RSASHA256 ||
		key->key_alg == DST_ALG_RSASHA512);

	rsa = key->keydata.pkey;

	pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx,
						  sizeof(*pk11_ctx));
	if (pk11_ctx == NULL)
		return (ISC_R_NOMEMORY);
	ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_FALSE,
			       rsa->reqlogon, NULL,
			       pk11_get_best_token(OP_RSA));
	if (ret != ISC_R_SUCCESS)
		goto err;

	for (attr = pk11_attribute_first(rsa);
	     attr != NULL;
	     attr = pk11_attribute_next(rsa, attr))
		switch (attr->type) {
		case CKA_MODULUS:
			INSIST(keyTemplate[5].type == attr->type);
			keyTemplate[5].pValue = isc_mem_get(dctx->mctx,
							    attr->ulValueLen);
			if (keyTemplate[5].pValue == NULL)
				DST_RET(ISC_R_NOMEMORY);
			memmove(keyTemplate[5].pValue, attr->pValue,
				attr->ulValueLen);
			keyTemplate[5].ulValueLen = attr->ulValueLen;
			break;
		case CKA_PUBLIC_EXPONENT:
			INSIST(keyTemplate[6].type == attr->type);
			keyTemplate[6].pValue = isc_mem_get(dctx->mctx,
							    attr->ulValueLen);
			if (keyTemplate[6].pValue == NULL)
				DST_RET(ISC_R_NOMEMORY);
			memmove(keyTemplate[6].pValue, attr->pValue,
				attr->ulValueLen);
			keyTemplate[6].ulValueLen = attr->ulValueLen;
			if (pk11_numbits(attr->pValue,
					 attr->ulValueLen) > maxbits &&
			    maxbits != 0)
				DST_RET(DST_R_VERIFYFAILURE);
			break;
		}
	pk11_ctx->object = CK_INVALID_HANDLE;
	pk11_ctx->ontoken = ISC_FALSE;
	PK11_RET(pkcs_C_CreateObject,
		 (pk11_ctx->session,
		  keyTemplate, (CK_ULONG) 7,
		  &pk11_ctx->object),
		 ISC_R_FAILURE);

	switch (dctx->key->key_alg) {
	case DST_ALG_RSAMD5:
		mech.mechanism = CKM_MD5_RSA_PKCS;
		break;
	case DST_ALG_RSASHA1:
	case DST_ALG_NSEC3RSASHA1:
		mech.mechanism = CKM_SHA1_RSA_PKCS;
		break;
	case DST_ALG_RSASHA256:
		mech.mechanism = CKM_SHA256_RSA_PKCS;
		break;
	case DST_ALG_RSASHA512:
		mech.mechanism = CKM_SHA512_RSA_PKCS;
		break;
	default:
		INSIST(0);
	}

	PK11_RET(pkcs_C_VerifyInit,
		 (pk11_ctx->session, &mech, pk11_ctx->object),
		 ISC_R_FAILURE);

	dctx->ctxdata.pk11_ctx = pk11_ctx;

	for (i = 5; i <= 6; i++)
		if (keyTemplate[i].pValue != NULL) {
			memset(keyTemplate[i].pValue, 0,
			       keyTemplate[i].ulValueLen);
			isc_mem_put(dctx->mctx,
				    keyTemplate[i].pValue,
				    keyTemplate[i].ulValueLen);
		}

	return (ISC_R_SUCCESS);

    err:
	if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE))
		(void) pkcs_C_DestroyObject(pk11_ctx->session,
					    pk11_ctx->object);
	for (i = 5; i <= 6; i++)
		if (keyTemplate[i].pValue != NULL) {
			memset(keyTemplate[i].pValue, 0,
			       keyTemplate[i].ulValueLen);
			isc_mem_put(dctx->mctx,
				    keyTemplate[i].pValue,
				    keyTemplate[i].ulValueLen);
		}
	pk11_return_session(pk11_ctx);
	memset(pk11_ctx, 0, sizeof(*pk11_ctx));
	isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx));

	return (ret);
}
static isc_result_t
pkcs11dsa_tofile(const dst_key_t *key, const char *directory) {
	int cnt = 0;
	pk11_object_t *dsa;
	CK_ATTRIBUTE *attr;
	CK_ATTRIBUTE *prime = NULL, *subprime = NULL, *base = NULL;
	CK_ATTRIBUTE *pub_key = NULL, *priv_key = NULL;
	dst_private_t priv;
	unsigned char bufs[5][128];

	if (key->keydata.pkey == NULL)
		return (DST_R_NULLKEY);

	if (key->external) {
		priv.nelements = 0;
		return (dst__privstruct_writefile(key, &priv, directory));
	}

	dsa = key->keydata.pkey;

	for (attr = pk11_attribute_first(dsa);
	     attr != NULL;
	     attr = pk11_attribute_next(dsa, attr))
		switch (attr->type) {
		case CKA_PRIME:
			prime = attr;
			break;
		case CKA_SUBPRIME:
			subprime = attr;
			break;
		case CKA_BASE:
			base = attr;
			break;
		case CKA_VALUE:
			pub_key = attr;
			break;
		case CKA_VALUE2:
			priv_key = attr;
			break;
		}
	if ((prime == NULL) || (subprime == NULL) || (base == NULL) ||
	    (pub_key == NULL) || (priv_key ==NULL))
		return (DST_R_NULLKEY);

	priv.elements[cnt].tag = TAG_DSA_PRIME;
	priv.elements[cnt].length = (unsigned short) prime->ulValueLen;
	memmove(bufs[cnt], prime->pValue, prime->ulValueLen);
	priv.elements[cnt].data = bufs[cnt];
	cnt++;

	priv.elements[cnt].tag = TAG_DSA_SUBPRIME;
	priv.elements[cnt].length = (unsigned short) subprime->ulValueLen;
	memmove(bufs[cnt], subprime->pValue, subprime->ulValueLen);
	priv.elements[cnt].data = bufs[cnt];
	cnt++;

	priv.elements[cnt].tag = TAG_DSA_BASE;
	priv.elements[cnt].length = (unsigned short) base->ulValueLen;
	memmove(bufs[cnt], base->pValue, base->ulValueLen);
	priv.elements[cnt].data = bufs[cnt];
	cnt++;

	priv.elements[cnt].tag = TAG_DSA_PRIVATE;
	priv.elements[cnt].length = (unsigned short) priv_key->ulValueLen;
	memmove(bufs[cnt], priv_key->pValue, priv_key->ulValueLen);
	priv.elements[cnt].data = bufs[cnt];
	cnt++;

	priv.elements[cnt].tag = TAG_DSA_PUBLIC;
	priv.elements[cnt].length = (unsigned short) pub_key->ulValueLen;
	memmove(bufs[cnt], pub_key->pValue, pub_key->ulValueLen);
	priv.elements[cnt].data = bufs[cnt];
	cnt++;

	priv.nelements = cnt;
	return (dst__privstruct_writefile(key, &priv, directory));
}
static isc_result_t
pkcs11dsa_createctx_sign(dst_key_t *key, dst_context_t *dctx) {
	CK_RV rv;
	CK_MECHANISM mech = { CKM_DSA_SHA1, NULL, 0 };
	CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY;
	CK_KEY_TYPE keyType = CKK_DSA;
	CK_ATTRIBUTE keyTemplate[] =
	{
		{ CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
		{ CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
		{ CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
		{ CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
		{ CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
		{ CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
		{ CKA_PRIME, NULL, 0 },
		{ CKA_SUBPRIME, NULL, 0 },
		{ CKA_BASE, NULL, 0 },
		{ CKA_VALUE, NULL, 0 }
	};
	CK_ATTRIBUTE *attr;
	pk11_object_t *dsa;
	pk11_context_t *pk11_ctx;
	isc_result_t ret;
	unsigned int i;

	pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx,
						  sizeof(*pk11_ctx));
	if (pk11_ctx == NULL)
		return (ISC_R_NOMEMORY);
	ret = pk11_get_session(pk11_ctx, OP_DSA, ISC_TRUE, ISC_FALSE,
			       ISC_FALSE, NULL, pk11_get_best_token(OP_DSA));
	if (ret != ISC_R_SUCCESS)
		goto err;

	dsa = key->keydata.pkey;
	if (dsa->ontoken && (dsa->object != CK_INVALID_HANDLE)) {
		pk11_ctx->ontoken = dsa->ontoken;
		pk11_ctx->object = dsa->object;
		goto token_key;
	}

	for (attr = pk11_attribute_first(dsa);
	     attr != NULL;
	     attr = pk11_attribute_next(dsa, attr))
		switch (attr->type) {
		case CKA_PRIME:
			INSIST(keyTemplate[6].type == attr->type);
			keyTemplate[6].pValue = isc_mem_get(dctx->mctx,
							    attr->ulValueLen);
			if (keyTemplate[6].pValue == NULL)
				DST_RET(ISC_R_NOMEMORY);
			memmove(keyTemplate[6].pValue, attr->pValue,
				attr->ulValueLen);
			keyTemplate[6].ulValueLen = attr->ulValueLen;
			break;
		case CKA_SUBPRIME:
			INSIST(keyTemplate[7].type == attr->type);
			keyTemplate[7].pValue = isc_mem_get(dctx->mctx,
							    attr->ulValueLen);
			if (keyTemplate[7].pValue == NULL)
				DST_RET(ISC_R_NOMEMORY);
			memmove(keyTemplate[7].pValue, attr->pValue,
				attr->ulValueLen);
			keyTemplate[7].ulValueLen = attr->ulValueLen;
			break;
		case CKA_BASE:
			INSIST(keyTemplate[8].type == attr->type);
			keyTemplate[8].pValue = isc_mem_get(dctx->mctx,
							    attr->ulValueLen);
			if (keyTemplate[8].pValue == NULL)
				DST_RET(ISC_R_NOMEMORY);
			memmove(keyTemplate[8].pValue, attr->pValue,
				attr->ulValueLen);
			keyTemplate[8].ulValueLen = attr->ulValueLen;
			break;
		case CKA_VALUE2:
			INSIST(keyTemplate[9].type == CKA_VALUE);
			keyTemplate[9].pValue = isc_mem_get(dctx->mctx,
							    attr->ulValueLen);
			if (keyTemplate[9].pValue == NULL)
				DST_RET(ISC_R_NOMEMORY);
			memmove(keyTemplate[9].pValue, attr->pValue,
				attr->ulValueLen);
			keyTemplate[9].ulValueLen = attr->ulValueLen;
			break;
		}
	pk11_ctx->object = CK_INVALID_HANDLE;
	pk11_ctx->ontoken = ISC_FALSE;
	PK11_RET(pkcs_C_CreateObject,
		 (pk11_ctx->session,
		  keyTemplate, (CK_ULONG) 10,
		  &pk11_ctx->object),
		 ISC_R_FAILURE);

    token_key:

	PK11_RET(pkcs_C_SignInit,
		 (pk11_ctx->session, &mech, pk11_ctx->object),
		 ISC_R_FAILURE);

	dctx->ctxdata.pk11_ctx = pk11_ctx;

	for (i = 6; i <= 9; i++)
		if (keyTemplate[i].pValue != NULL) {
			memset(keyTemplate[i].pValue, 0,
			       keyTemplate[i].ulValueLen);
			isc_mem_put(dctx->mctx,
				    keyTemplate[i].pValue,
				    keyTemplate[i].ulValueLen);
		}

	return (ISC_R_SUCCESS);

    err:
	if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE))
		(void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object);
	for (i = 6; i <= 9; i++)
		if (keyTemplate[i].pValue != NULL) {
			memset(keyTemplate[i].pValue, 0,
			       keyTemplate[i].ulValueLen);
			isc_mem_put(dctx->mctx,
				    keyTemplate[i].pValue,
				    keyTemplate[i].ulValueLen);
		}
	pk11_return_session(pk11_ctx);
	memset(pk11_ctx, 0, sizeof(*pk11_ctx));
	isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx));

	return (ret);
}
Example #15
0
static isc_result_t
pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
	pk11_object_t *rsa;
	isc_region_t r;
	unsigned int e_bytes, mod_bytes;
	CK_BYTE *exponent = NULL, *modulus = NULL;
	CK_ATTRIBUTE *attr;

	isc_buffer_remainingregion(data, &r);
	if (r.length == 0)
		return (ISC_R_SUCCESS);

	rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa));
	if (rsa == NULL)
		return (ISC_R_NOMEMORY);
	memset(rsa, 0, sizeof(*rsa));

	if (r.length < 1) {
		memset(rsa, 0, sizeof(*rsa));
		isc_mem_put(key->mctx, rsa, sizeof(*rsa));
		return (DST_R_INVALIDPUBLICKEY);
	}
	e_bytes = *r.base++;
	r.length--;

	if (e_bytes == 0) {
		if (r.length < 2) {
			memset(rsa, 0, sizeof(*rsa));
			isc_mem_put(key->mctx, rsa, sizeof(*rsa));
			return (DST_R_INVALIDPUBLICKEY);
		}
		e_bytes = ((*r.base++) << 8);
		e_bytes += *r.base++;
		r.length -= 2;
	}

	if (r.length < e_bytes) {
		memset(rsa, 0, sizeof(*rsa));
		isc_mem_put(key->mctx, rsa, sizeof(*rsa));
		return (DST_R_INVALIDPUBLICKEY);
	}
	exponent = r.base;
	r.base += e_bytes;
	r.length -= e_bytes;
	modulus = r.base;
	mod_bytes = r.length;

	key->key_size = pk11_numbits(modulus, mod_bytes);

	isc_buffer_forward(data, r.length);

	rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2);
	if (rsa->repr == NULL)
		goto nomemory;
	memset(rsa->repr, 0, sizeof(*attr) * 2);
	rsa->attrcnt = 2;
	attr = rsa->repr;
	attr[0].type = CKA_MODULUS;
	attr[0].pValue = isc_mem_get(key->mctx, mod_bytes);
	if (attr[0].pValue == NULL)
		goto nomemory;
	memmove(attr[0].pValue, modulus, mod_bytes);
	attr[0].ulValueLen = (CK_ULONG) mod_bytes;
	attr[1].type = CKA_PUBLIC_EXPONENT;
	attr[1].pValue = isc_mem_get(key->mctx, e_bytes);
	if (attr[1].pValue == NULL)
		goto nomemory;
	memmove(attr[1].pValue, exponent, e_bytes);
	attr[1].ulValueLen = (CK_ULONG) e_bytes;

	key->keydata.pkey = rsa;

	return (ISC_R_SUCCESS);

    nomemory:
	for (attr = pk11_attribute_first(rsa);
	     attr != NULL;
	     attr = pk11_attribute_next(rsa, attr))
		switch (attr->type) {
		case CKA_MODULUS:
		case CKA_PUBLIC_EXPONENT:
			if (attr->pValue != NULL) {
				memset(attr->pValue, 0, attr->ulValueLen);
				isc_mem_put(key->mctx,
					    attr->pValue,
					    attr->ulValueLen);
			}
			break;
		}
	if (rsa->repr != NULL) {
		memset(rsa->repr, 0, rsa->attrcnt * sizeof(*attr));
		isc_mem_put(key->mctx,
			    rsa->repr,
			    rsa->attrcnt * sizeof(*attr));
	}
	memset(rsa, 0, sizeof(*rsa));
	isc_mem_put(key->mctx, rsa, sizeof(*rsa));
	return (ISC_R_NOMEMORY);
}
Example #16
0
static isc_result_t
pkcs11ecdsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
	pk11_object_t *ec;
	isc_region_t r;
	unsigned int len;
	CK_ATTRIBUTE *attr;

	REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
		key->key_alg == DST_ALG_ECDSA384);

	if (key->key_alg == DST_ALG_ECDSA256)
		len = DNS_KEY_ECDSA256SIZE;
	else
		len = DNS_KEY_ECDSA384SIZE;

	isc_buffer_remainingregion(data, &r);
	if (r.length == 0)
		return (ISC_R_SUCCESS);
	if (r.length != len)
		return (DST_R_INVALIDPUBLICKEY);

	ec = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*ec));
	if (ec == NULL)
		return (ISC_R_NOMEMORY);
	memset(ec, 0, sizeof(*ec));
	ec->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2);
	if (ec->repr == NULL)
		goto nomemory;
	ec->attrcnt = 2;

	attr = ec->repr;
	attr->type = CKA_EC_PARAMS;
	if (key->key_alg == DST_ALG_ECDSA256) {
		attr->pValue =
			isc_mem_get(key->mctx, sizeof(pk11_ecc_prime256v1));
		if (attr->pValue == NULL)
			goto nomemory;
		memmove(attr->pValue,
			pk11_ecc_prime256v1, sizeof(pk11_ecc_prime256v1));
		attr->ulValueLen = sizeof(pk11_ecc_prime256v1);
	} else {
		attr->pValue =
			isc_mem_get(key->mctx, sizeof(pk11_ecc_secp384r1));
		if (attr->pValue == NULL)
			goto nomemory;
		memmove(attr->pValue,
			pk11_ecc_secp384r1, sizeof(pk11_ecc_secp384r1));
		attr->ulValueLen = sizeof(pk11_ecc_secp384r1);
	}

	attr++;
	attr->type = CKA_EC_POINT;
	attr->pValue = isc_mem_get(key->mctx, len + 3);
	if (attr->pValue == NULL)
		goto nomemory;
	((CK_BYTE_PTR) attr->pValue)[0] = TAG_OCTECT_STRING;
	((CK_BYTE_PTR) attr->pValue)[1] = len + 1;
	((CK_BYTE_PTR) attr->pValue)[2] = UNCOMPRESSED;
	memmove((CK_BYTE_PTR) attr->pValue + 3, r.base, len);
	attr->ulValueLen = len + 3;

	isc_buffer_forward(data, len);
	key->keydata.pkey = ec;
	key->key_size = len * 4;
	return (ISC_R_SUCCESS);

 nomemory:
	for (attr = pk11_attribute_first(ec);
	     attr != NULL;
	     attr = pk11_attribute_next(ec, attr))
		switch (attr->type) {
		case CKA_EC_PARAMS:
		case CKA_EC_POINT:
			FREECURVE();
			break;
		}
	if (ec->repr != NULL) {
		memset(ec->repr, 0, ec->attrcnt * sizeof(*attr));
		isc_mem_put(key->mctx,
			    ec->repr,
			    ec->attrcnt * sizeof(*attr));
	}
	memset(ec, 0, sizeof(*ec));
	isc_mem_put(key->mctx, ec, sizeof(*ec));
	return (ISC_R_NOMEMORY);
}
Example #17
0
static isc_result_t
pkcs11rsa_tofile(const dst_key_t *key, const char *directory) {
	int i;
	pk11_object_t *rsa;
	CK_ATTRIBUTE *attr;
	CK_ATTRIBUTE *modulus = NULL, *exponent = NULL;
	CK_ATTRIBUTE  *d = NULL, *p = NULL, *q = NULL;
	CK_ATTRIBUTE *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL;
	dst_private_t priv;
	unsigned char *bufs[10];
	isc_result_t result;

	if (key->keydata.pkey == NULL)
		return (DST_R_NULLKEY);

	if (key->external) {
		priv.nelements = 0;
		return (dst__privstruct_writefile(key, &priv, directory));
	}

	rsa = key->keydata.pkey;

	for (attr = pk11_attribute_first(rsa);
	     attr != NULL;
	     attr = pk11_attribute_next(rsa, attr))
		switch (attr->type) {
		case CKA_MODULUS:
			modulus = attr;
			break;
		case CKA_PUBLIC_EXPONENT:
			exponent = attr;
			break;
		case CKA_PRIVATE_EXPONENT:
			d = attr;
			break;
		case CKA_PRIME_1:
			p = attr;
			break;
		case CKA_PRIME_2:
			q = attr;
			break;
		case CKA_EXPONENT_1:
			dmp1 = attr;
			break;
		case CKA_EXPONENT_2:
			dmq1 = attr;
			break;
		case CKA_COEFFICIENT:
			iqmp = attr;
			break;
		}
	if ((modulus == NULL) || (exponent == NULL))
		return (DST_R_NULLKEY);

	memset(bufs, 0, sizeof(bufs));

	for (i = 0; i < 10; i++) {
		bufs[i] = isc_mem_get(key->mctx, modulus->ulValueLen);
		if (bufs[i] == NULL) {
			result = ISC_R_NOMEMORY;
			goto fail;
		}
		memset(bufs[i], 0, modulus->ulValueLen);
	}

	i = 0;

	priv.elements[i].tag = TAG_RSA_MODULUS;
	priv.elements[i].length = (unsigned short) modulus->ulValueLen;
	memmove(bufs[i], modulus->pValue, modulus->ulValueLen);
	priv.elements[i].data = bufs[i];
	i++;

	priv.elements[i].tag = TAG_RSA_PUBLICEXPONENT;
	priv.elements[i].length = (unsigned short) exponent->ulValueLen;
	memmove(bufs[i], exponent->pValue, exponent->ulValueLen);
	priv.elements[i].data = bufs[i];
	i++;

	if (d != NULL) {
		priv.elements[i].tag = TAG_RSA_PRIVATEEXPONENT;
		priv.elements[i].length = (unsigned short) d->ulValueLen;
		memmove(bufs[i], d->pValue, d->ulValueLen);
		priv.elements[i].data = bufs[i];
		i++;
	}

	if (p != NULL) {
		priv.elements[i].tag = TAG_RSA_PRIME1;
		priv.elements[i].length = (unsigned short) p->ulValueLen;
		memmove(bufs[i], p->pValue, p->ulValueLen);
		priv.elements[i].data = bufs[i];
		i++;
	}

	if (q != NULL) {
		priv.elements[i].tag = TAG_RSA_PRIME2;
		priv.elements[i].length = (unsigned short) q->ulValueLen;
		memmove(bufs[i], q->pValue, q->ulValueLen);
		priv.elements[i].data = bufs[i];
		i++;
	}

	if (dmp1 != NULL) {
		priv.elements[i].tag = TAG_RSA_EXPONENT1;
		priv.elements[i].length = (unsigned short) dmp1->ulValueLen;
		memmove(bufs[i], dmp1->pValue, dmp1->ulValueLen);
		priv.elements[i].data = bufs[i];
		i++;
	}

	if (dmq1 != NULL) {
		priv.elements[i].tag = TAG_RSA_EXPONENT2;
		priv.elements[i].length = (unsigned short) dmq1->ulValueLen;
		memmove(bufs[i], dmq1->pValue, dmq1->ulValueLen);
		priv.elements[i].data = bufs[i];
		i++;
	}

	if (iqmp != NULL) {
		priv.elements[i].tag = TAG_RSA_COEFFICIENT;
		priv.elements[i].length = (unsigned short) iqmp->ulValueLen;
		memmove(bufs[i], iqmp->pValue, iqmp->ulValueLen);
		priv.elements[i].data = bufs[i];
		i++;
	}

	if (key->engine != NULL) {
		priv.elements[i].tag = TAG_RSA_ENGINE;
		priv.elements[i].length = strlen(key->engine) + 1;
		priv.elements[i].data = (unsigned char *)key->engine;
		i++;
	}

	if (key->label != NULL) {
		priv.elements[i].tag = TAG_RSA_LABEL;
		priv.elements[i].length = strlen(key->label) + 1;
		priv.elements[i].data = (unsigned char *)key->label;
		i++;
	}

	priv.nelements = i;
	result = dst__privstruct_writefile(key, &priv, directory);
 fail:
	for (i = 0; i < 10; i++) {
		if (bufs[i] == NULL)
			break;
		memset(bufs[i], 0, modulus->ulValueLen);
		isc_mem_put(key->mctx, bufs[i], modulus->ulValueLen);
	}
	return (result);
}
static isc_result_t
pkcs11dsa_todns(const dst_key_t *key, isc_buffer_t *data) {
	pk11_object_t *dsa;
	CK_ATTRIBUTE *attr;
	isc_region_t r;
	int dnslen;
	unsigned int t, p_bytes;
	CK_ATTRIBUTE *prime = NULL, *subprime = NULL;
	CK_ATTRIBUTE *base = NULL, *pub_key = NULL;
	CK_BYTE *cp;

	REQUIRE(key->keydata.pkey != NULL);

	dsa = key->keydata.pkey;

	for (attr = pk11_attribute_first(dsa);
	     attr != NULL;
	     attr = pk11_attribute_next(dsa, attr))
		switch (attr->type) {
		case CKA_PRIME:
			prime = attr;
			break;
		case CKA_SUBPRIME:
			subprime = attr;
			break;
		case CKA_BASE:
			base = attr;
			break;
		case CKA_VALUE:
			pub_key = attr;
			break;
		}
	REQUIRE((prime != NULL) && (subprime != NULL) &&
		(base != NULL) && (pub_key != NULL));

	isc_buffer_availableregion(data, &r);

	t = (prime->ulValueLen - 64) / 8;
	if (t > 8)
		return (DST_R_INVALIDPUBLICKEY);
	p_bytes = 64 + 8 * t;

	dnslen = 1 + (key->key_size * 3)/8 + ISC_SHA1_DIGESTLENGTH;
	if (r.length < (unsigned int) dnslen)
		return (ISC_R_NOSPACE);

	memset(r.base, 0, dnslen);
	*r.base = t;
	isc_region_consume(&r, 1);

	cp = (CK_BYTE *) subprime->pValue;
	memmove(r.base + ISC_SHA1_DIGESTLENGTH - subprime->ulValueLen,
		cp, subprime->ulValueLen);
	isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH);
	cp = (CK_BYTE *) prime->pValue;
	memmove(r.base + key->key_size/8 - prime->ulValueLen,
		cp, prime->ulValueLen);
	isc_region_consume(&r, p_bytes);
	cp = (CK_BYTE *) base->pValue;
	memmove(r.base + key->key_size/8 - base->ulValueLen,
		cp, base->ulValueLen);
	isc_region_consume(&r, p_bytes);
	cp = (CK_BYTE *) pub_key->pValue;
	memmove(r.base + key->key_size/8 - pub_key->ulValueLen,
		cp, pub_key->ulValueLen);
	isc_region_consume(&r, p_bytes);

	isc_buffer_add(data, dnslen);

	return (ISC_R_SUCCESS);
}