Exemple #1
0
void
pk11_rand_seed_fromfile(const char *randomfile) {
	pk11_context_t ctx;
	FILE *stream = NULL;
	size_t cc = 0;
	isc_result_t ret;

	ret = pk11_get_session(&ctx, OP_RAND, ISC_FALSE, ISC_FALSE,
			       ISC_FALSE, NULL, 0);
	if ((ret != ISC_R_SUCCESS) &&
	    (ret != PK11_R_NODIGESTSERVICE) &&
	    (ret != PK11_R_NOAESSERVICE))
		return;
	RUNTIME_CHECK(ctx.session != CK_INVALID_HANDLE);
	ret = isc_stdio_open(randomfile, "r", &stream);
	if (ret != ISC_R_SUCCESS)
		goto cleanup;
	ret = isc_stdio_read(seed, 1, SEEDSIZE, stream, &cc);
	if (ret!= ISC_R_SUCCESS)
		goto cleanup;
	ret = isc_stdio_close(stream);
	stream = NULL;
	if (ret!= ISC_R_SUCCESS)
		goto cleanup;
	(void) pkcs_C_SeedRandom(ctx.session, seed, (CK_ULONG) cc);

    cleanup:
	if (stream != NULL)
		(void) isc_stdio_close(stream);
	pk11_return_session(&ctx);
}
Exemple #2
0
void
isc_hmacmd5_init(isc_hmacmd5_t *ctx, const unsigned char *key,
		 unsigned int len)
{
	CK_RV rv;
	CK_MECHANISM mech = { CKM_MD5_HMAC, NULL, 0 };
	CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
	CK_KEY_TYPE keyType = CKK_MD5_HMAC;
	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_VALUE, NULL, (CK_ULONG) len }
	};

	DE_CONST(key, keyTemplate[5].pValue);
	RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE,
				       ISC_FALSE, NULL, 0) == ISC_R_SUCCESS);
	ctx->object = CK_INVALID_HANDLE;
	PK11_FATALCHECK(pkcs_C_CreateObject,
			(ctx->session, keyTemplate,
			 (CK_ULONG) 6, &ctx->object));
	INSIST(ctx->object != CK_INVALID_HANDLE);
	PK11_FATALCHECK(pkcs_C_SignInit, (ctx->session, &mech, ctx->object));
}
Exemple #3
0
void
isc_hmacmd5_init(isc_hmacmd5_t *ctx, const unsigned char *key,
		 unsigned int len)
{
	CK_RV rv;
	CK_MECHANISM mech = { CKM_MD5, NULL, 0 };
	unsigned char ipad[PADLEN];
	unsigned int i;

	RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE,
				       ISC_FALSE, NULL, 0) == ISC_R_SUCCESS);
	RUNTIME_CHECK((ctx->key = pk11_mem_get(PADLEN)) != NULL);
	if (len > PADLEN) {
		CK_BYTE_PTR kPart;
		CK_ULONG kl;

		PK11_FATALCHECK(pkcs_C_DigestInit, (ctx->session, &mech));
		DE_CONST(key, kPart);
		PK11_FATALCHECK(pkcs_C_DigestUpdate,
				(ctx->session, kPart, (CK_ULONG) len));
		kl = ISC_MD5_DIGESTLENGTH;
		PK11_FATALCHECK(pkcs_C_DigestFinal,
				(ctx->session, (CK_BYTE_PTR) ctx->key, &kl));
	} else
		memmove(ctx->key, key, len);
	PK11_FATALCHECK(pkcs_C_DigestInit, (ctx->session, &mech));
	memset(ipad, IPAD, PADLEN);
	for (i = 0; i < PADLEN; i++)
		ipad[i] ^= ctx->key[i];
	PK11_FATALCHECK(pkcs_C_DigestUpdate,
			(ctx->session, ipad, (CK_ULONG) PADLEN));
}
Exemple #4
0
isc_result_t
isc_gost_init(isc_gost_t *ctx) {
	CK_RV rv;
	CK_MECHANISM mech = { CKM_GOSTR3411, NULL, 0 };
	int ret = ISC_R_SUCCESS;

	ret = pk11_get_session(ctx, OP_GOST, ISC_FALSE, ISC_FALSE, NULL, 0);
	if (ret != ISC_R_SUCCESS)
		return (ret);
	PK11_CALL(pkcs_C_DigestInit, (ctx->session, &mech), ISC_R_FAILURE);
	return (ret);
}
Exemple #5
0
static void
isc_aes_crypt(const unsigned char *key, CK_ULONG keylen,
	      const unsigned char *in, unsigned char *out)
{
	CK_RV rv;
	CK_MECHANISM mech = { CKM_AES_ECB, NULL, 0 };
	CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
	CK_KEY_TYPE keyType = CKK_AES;
	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_ENCRYPT, &truevalue, (CK_ULONG) sizeof(truevalue) },
		{ CKA_VALUE, NULL, keylen }
	};
	CK_ULONG blocklen;
	CK_BYTE_PTR pData;
	pk11_context_t ctx;

	DE_CONST(key, keyTemplate[5].pValue);
	RUNTIME_CHECK(pk11_get_session(&ctx, OP_AES, ISC_TRUE, ISC_FALSE,
				       ISC_FALSE, NULL, 0) == ISC_R_SUCCESS);
	ctx.object = CK_INVALID_HANDLE;
	PK11_FATALCHECK(pkcs_C_CreateObject,
			(ctx.session, keyTemplate,
			 (CK_ULONG) 6, &ctx.object));
	INSIST(ctx.object != CK_INVALID_HANDLE);
	PK11_FATALCHECK(pkcs_C_EncryptInit,
			(ctx.session, &mech, ctx.object));

	DE_CONST(in, pData);
	blocklen = (CK_ULONG) ISC_AES_BLOCK_LENGTH;
	PK11_FATALCHECK(pkcs_C_Encrypt,
			(ctx.session,
			 pData, (CK_ULONG) ISC_AES_BLOCK_LENGTH,
			 out, &blocklen));
	RUNTIME_CHECK(blocklen == (CK_ULONG) ISC_AES_BLOCK_LENGTH);

	(void) pkcs_C_DestroyObject(ctx.session, ctx.object);
	ctx.object = CK_INVALID_HANDLE;
	pk11_return_session(&ctx);

}
Exemple #6
0
isc_result_t
pk11_rand_bytes(unsigned char *buf, int num) {
	isc_result_t ret;
	CK_RV rv;
	pk11_context_t ctx;

	ret = pk11_get_session(&ctx, OP_RAND, ISC_FALSE, ISC_FALSE, NULL, 0);
	if (ret != ISC_R_SUCCESS)
		return (ret);
	RUNTIME_CHECK(ctx.session != CK_INVALID_HANDLE);
	rv = pkcs_C_GenerateRandom(ctx.session,
				   (CK_BYTE_PTR) buf, (CK_ULONG) num);
	pk11_return_session(&ctx);
	if (rv == CKR_OK)
		return (ISC_R_SUCCESS);
	else
		return (DST_R_CRYPTOFAILURE);
}
Exemple #7
0
static isc_result_t
pkcs11ecdsa_createctx(dst_key_t *key, dst_context_t *dctx) {
	CK_RV rv;
	CK_MECHANISM mech = {0, NULL, 0 };
	CK_SLOT_ID slotid;
	pk11_context_t *pk11_ctx;
	pk11_object_t *ec = key->keydata.pkey;
	isc_result_t ret;

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

	if (dctx->key->key_alg == DST_ALG_ECDSA256)
		mech.mechanism = CKM_SHA256;
	else
		mech.mechanism = CKM_SHA384;

	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 (ec->ontoken && (dctx->use == DO_SIGN))
		slotid = ec->slot;
	else
		slotid = pk11_get_best_token(OP_EC);
	ret = pk11_get_session(pk11_ctx, OP_EC, ISC_TRUE, ISC_FALSE,
			       ec->reqlogon, NULL, slotid);
	if (ret != ISC_R_SUCCESS)
		goto err;

	PK11_RET(pkcs_C_DigestInit, (pk11_ctx->session, &mech), ISC_R_FAILURE);
	dctx->ctxdata.pk11_ctx = pk11_ctx;
	return (ISC_R_SUCCESS);

 err:
	pk11_return_session(pk11_ctx);
	memset(pk11_ctx, 0, sizeof(*pk11_ctx));
	isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx));

	return (ret);
}
Exemple #8
0
static isc_result_t
pkcs11rsa_generate(dst_key_t *key, int exp, void (*callback)(int)) {
	CK_RV rv;
	CK_MECHANISM mech = { CKM_RSA_PKCS_KEY_PAIR_GEN, NULL, 0 };
	CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE;
	CK_ULONG bits = 0;
	CK_BYTE pubexp[5];
	CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY;
	CK_KEY_TYPE  keyType = CKK_RSA;
	CK_ATTRIBUTE pubTemplate[] =
	{
		{ CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) },
		{ 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_BITS, &bits, (CK_ULONG) sizeof(bits) },
		{ CKA_PUBLIC_EXPONENT, &pubexp, (CK_ULONG) sizeof(pubexp) }
	};
	CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE;
	CK_OBJECT_CLASS privClass = CKO_PRIVATE_KEY;
	CK_ATTRIBUTE privTemplate[] =
	{
		{ CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) },
		{ 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_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) },
		{ CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
	};
	CK_ATTRIBUTE *attr;
	pk11_object_t *rsa;
	pk11_context_t *pk11_ctx;
	isc_result_t ret;
	unsigned int i;

	UNUSED(callback);

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

	bits = key->key_size;
	if (exp == 0) {
		/* RSA_F4 0x10001 */
		pubexp[0] = 1;
		pubexp[1] = 0;
		pubexp[2] = 1;
		pubTemplate[6].ulValueLen = 3;
	} else {
		/* F5 0x100000001 */
		pubexp[0] = 1;
		pubexp[1] = 0;
		pubexp[2] = 0;
		pubexp[3] = 0;
		pubexp[4] = 1;
		pubTemplate[6].ulValueLen = 5;
	}

	PK11_RET(pkcs_C_GenerateKeyPair,
		 (pk11_ctx->session, &mech,
		  pubTemplate, (CK_ULONG) 7,
		  privTemplate, (CK_ULONG) 7,
		  &pub, &priv),
		 DST_R_CRYPTOFAILURE);

	rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa));
	if (rsa == NULL)
		DST_RET(ISC_R_NOMEMORY);
	memset(rsa, 0, sizeof(*rsa));
	key->keydata.pkey = rsa;
	rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 8);
	if (rsa->repr == NULL)
		DST_RET(ISC_R_NOMEMORY);
	memset(rsa->repr, 0, sizeof(*attr) * 8);
	rsa->attrcnt = 8;

	attr = rsa->repr;
	attr[0].type = CKA_MODULUS;
	attr[1].type = CKA_PUBLIC_EXPONENT;
	attr[2].type = CKA_PRIVATE_EXPONENT;
	attr[3].type = CKA_PRIME_1;
	attr[4].type = CKA_PRIME_2;
	attr[5].type = CKA_EXPONENT_1;
	attr[6].type = CKA_EXPONENT_2;
	attr[7].type = CKA_COEFFICIENT;

	PK11_RET(pkcs_C_GetAttributeValue,
		 (pk11_ctx->session, pub, attr, 2),
		 DST_R_CRYPTOFAILURE);
	for (i = 0; i <= 1; i++) {
		attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen);
		if (attr[i].pValue == NULL)
			DST_RET(ISC_R_NOMEMORY);
		memset(attr[i].pValue, 0, attr[i].ulValueLen);
	}
	PK11_RET(pkcs_C_GetAttributeValue,
		 (pk11_ctx->session, pub, attr, 2),
		 DST_R_CRYPTOFAILURE);

	attr += 2;
	PK11_RET(pkcs_C_GetAttributeValue,
		 (pk11_ctx->session, priv, attr, 6),
		 DST_R_CRYPTOFAILURE);
	for (i = 0; i <= 5; i++) {
		attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen);
		if (attr[i].pValue == NULL)
			DST_RET(ISC_R_NOMEMORY);
		memset(attr[i].pValue, 0, attr[i].ulValueLen);
	}
	PK11_RET(pkcs_C_GetAttributeValue,
		 (pk11_ctx->session, priv, attr, 6),
		 DST_R_CRYPTOFAILURE);

	(void) pkcs_C_DestroyObject(pk11_ctx->session, priv);
	(void) pkcs_C_DestroyObject(pk11_ctx->session, pub);
	pk11_return_session(pk11_ctx);
	memset(pk11_ctx, 0, sizeof(*pk11_ctx));
	isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));

	return (ISC_R_SUCCESS);

    err:
	pkcs11rsa_destroy(key);
	if (priv != CK_INVALID_HANDLE)
		(void) pkcs_C_DestroyObject(pk11_ctx->session, priv);
	if (pub != CK_INVALID_HANDLE)
		(void) pkcs_C_DestroyObject(pk11_ctx->session, pub);
	pk11_return_session(pk11_ctx);
	memset(pk11_ctx, 0, sizeof(*pk11_ctx));
	isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));

	return (ret);
}
Exemple #9
0
static isc_result_t
pkcs11rsa_fromlabel(dst_key_t *key, const char *engine, const char *label,
		    const char *pin)
{
	CK_RV rv;
	CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
	CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY;
	CK_KEY_TYPE keyType = CKK_RSA;
	CK_ATTRIBUTE searchTemplate[] =
	{
		{ CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
		{ CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
		{ CKA_TOKEN, &truevalue, (CK_ULONG) sizeof(truevalue) },
		{ CKA_LABEL, NULL, 0 }
	};
	CK_ULONG cnt;
	CK_ATTRIBUTE *attr;
	pk11_object_t *rsa;
	pk11_context_t *pk11_ctx = NULL;
	isc_result_t ret;
	unsigned int i;

	UNUSED(pin);

	rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa));
	if (rsa == NULL)
		return (ISC_R_NOMEMORY);
	memset(rsa, 0, sizeof(*rsa));
	rsa->object = CK_INVALID_HANDLE;
	rsa->ontoken = ISC_TRUE;
	rsa->reqlogon = ISC_TRUE;
	key->keydata.pkey = rsa;

	rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2);
	if (rsa->repr == NULL)
		DST_RET(ISC_R_NOMEMORY);
	memset(rsa->repr, 0, sizeof(*attr) * 2);
	rsa->attrcnt = 2;
	attr = rsa->repr;
	attr[0].type = CKA_MODULUS;
	attr[1].type = CKA_PUBLIC_EXPONENT;

	ret = pk11_parse_uri(rsa, label, key->mctx, OP_RSA);
	if (ret != ISC_R_SUCCESS)
		goto err;

	pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx,
						  sizeof(*pk11_ctx));
	if (pk11_ctx == NULL)
		DST_RET(ISC_R_NOMEMORY);
	ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE,
			       rsa->reqlogon, NULL, rsa->slot);
	if (ret != ISC_R_SUCCESS)
		goto err;

	attr = pk11_attribute_bytype(rsa, CKA_LABEL);
	if (attr == NULL) {
		attr = pk11_attribute_bytype(rsa, CKA_ID);
		INSIST(attr != NULL);
		searchTemplate[3].type = CKA_ID;
	}
	searchTemplate[3].pValue = attr->pValue;
	searchTemplate[3].ulValueLen = attr->ulValueLen;

	PK11_RET(pkcs_C_FindObjectsInit,
		 (pk11_ctx->session, searchTemplate, (CK_ULONG) 4),
		 DST_R_CRYPTOFAILURE);
	PK11_RET(pkcs_C_FindObjects,
		 (pk11_ctx->session, &hKey, (CK_ULONG) 1, &cnt),
		 DST_R_CRYPTOFAILURE);
	(void) pkcs_C_FindObjectsFinal(pk11_ctx->session);
	if (cnt == 0)
		DST_RET(ISC_R_NOTFOUND);
	if (cnt > 1)
		DST_RET(ISC_R_EXISTS);

	attr = rsa->repr;
	PK11_RET(pkcs_C_GetAttributeValue,
		 (pk11_ctx->session, hKey, attr, 2),
		 DST_R_CRYPTOFAILURE);
	for (i = 0; i <= 1; i++) {
		attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen);
		if (attr[i].pValue == NULL)
			DST_RET(ISC_R_NOMEMORY);
		memset(attr[i].pValue, 0, attr[i].ulValueLen);
	}
	PK11_RET(pkcs_C_GetAttributeValue,
		 (pk11_ctx->session, hKey, attr, 2),
		 DST_R_CRYPTOFAILURE);

	keyClass = CKO_PRIVATE_KEY;
	PK11_RET(pkcs_C_FindObjectsInit,
		 (pk11_ctx->session, searchTemplate, (CK_ULONG) 4),
		 DST_R_CRYPTOFAILURE);
	PK11_RET(pkcs_C_FindObjects,
		 (pk11_ctx->session, &rsa->object, (CK_ULONG) 1, &cnt),
		 DST_R_CRYPTOFAILURE);
	(void) pkcs_C_FindObjectsFinal(pk11_ctx->session);
	if (cnt == 0)
		DST_RET(ISC_R_NOTFOUND);
	if (cnt > 1)
		DST_RET(ISC_R_EXISTS);

	if (engine != NULL) {
		key->engine = isc_mem_strdup(key->mctx, engine);
		if (key->engine == NULL)
			DST_RET(ISC_R_NOMEMORY);
	}

	key->label = isc_mem_strdup(key->mctx, label);
	if (key->label == NULL)
		DST_RET(ISC_R_NOMEMORY);

	attr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT);
	INSIST(attr != NULL);
	if (pk11_numbits(attr->pValue, attr->ulValueLen) > RSA_MAX_PUBEXP_BITS)
		DST_RET(ISC_R_RANGE);

	attr = pk11_attribute_bytype(rsa, CKA_MODULUS);
	INSIST(attr != NULL);
	key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen);

	pk11_return_session(pk11_ctx);
	memset(pk11_ctx, 0, sizeof(*pk11_ctx));
	isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));

	return (ISC_R_SUCCESS);

    err:
	pkcs11rsa_destroy(key);
	if (pk11_ctx != NULL) {
		pk11_return_session(pk11_ctx);
		memset(pk11_ctx, 0, sizeof(*pk11_ctx));
		isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));
	}

	return (ret);
}
Exemple #10
0
static isc_result_t
pkcs11rsa_fetch(dst_key_t *key, const char *engine, const char *label,
		dst_key_t *pub)
{
	CK_RV rv;
	CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY;
	CK_KEY_TYPE keyType = CKK_RSA;
	CK_ATTRIBUTE searchTemplate[] =
	{
		{ CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
		{ CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
		{ CKA_TOKEN, &truevalue, (CK_ULONG) sizeof(truevalue) },
		{ CKA_LABEL, NULL, 0 }
	};
	CK_ULONG cnt;
	CK_ATTRIBUTE *attr;
	CK_ATTRIBUTE *pubattr;
	pk11_object_t *rsa;
	pk11_object_t *pubrsa;
	pk11_context_t *pk11_ctx = NULL;
	isc_result_t ret;

	if (label == NULL)
		return (DST_R_NOENGINE);

	rsa = key->keydata.pkey;
	pubrsa = pub->keydata.pkey;

	rsa->object = CK_INVALID_HANDLE;
	rsa->ontoken = ISC_TRUE;
	rsa->reqlogon = ISC_TRUE;
	rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2);
	if (rsa->repr == NULL)
		return (ISC_R_NOMEMORY);
	memset(rsa->repr, 0, sizeof(*attr) * 2);
	rsa->attrcnt = 2;
	attr = rsa->repr;

	attr->type = CKA_MODULUS;
	pubattr = pk11_attribute_bytype(pubrsa, CKA_MODULUS);
	attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen);
	if (attr->pValue == NULL)
		DST_RET(ISC_R_NOMEMORY);
	memmove(attr->pValue, pubattr->pValue, pubattr->ulValueLen);
	attr->ulValueLen = pubattr->ulValueLen;
	attr++;

	attr->type = CKA_PUBLIC_EXPONENT;
	pubattr = pk11_attribute_bytype(pubrsa, CKA_PUBLIC_EXPONENT);
	attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen);
	if (attr->pValue == NULL)
		DST_RET(ISC_R_NOMEMORY);
	memmove(attr->pValue, pubattr->pValue, pubattr->ulValueLen);
	attr->ulValueLen = pubattr->ulValueLen;

	ret = pk11_parse_uri(rsa, label, key->mctx, OP_RSA);
	if (ret != ISC_R_SUCCESS)
		goto err;

	pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx,
						  sizeof(*pk11_ctx));
	if (pk11_ctx == NULL)
		DST_RET(ISC_R_NOMEMORY);
	ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE,
			       rsa->reqlogon, NULL, rsa->slot);
	if (ret != ISC_R_SUCCESS)
		goto err;

	attr = pk11_attribute_bytype(rsa, CKA_LABEL);
	if (attr == NULL) {
		attr = pk11_attribute_bytype(rsa, CKA_ID);
		INSIST(attr != NULL);
		searchTemplate[3].type = CKA_ID;
	}
	searchTemplate[3].pValue = attr->pValue;
	searchTemplate[3].ulValueLen = attr->ulValueLen;

	PK11_RET(pkcs_C_FindObjectsInit,
		 (pk11_ctx->session, searchTemplate, (CK_ULONG) 4),
		 DST_R_CRYPTOFAILURE);
	PK11_RET(pkcs_C_FindObjects,
		 (pk11_ctx->session, &rsa->object, (CK_ULONG) 1, &cnt),
		 DST_R_CRYPTOFAILURE);
	(void) pkcs_C_FindObjectsFinal(pk11_ctx->session);
	if (cnt == 0)
		DST_RET(ISC_R_NOTFOUND);
	if (cnt > 1)
		DST_RET(ISC_R_EXISTS);

	if (engine != NULL) {
		key->engine = isc_mem_strdup(key->mctx, engine);
		if (key->engine == NULL)
			DST_RET(ISC_R_NOMEMORY);
	}

	key->label = isc_mem_strdup(key->mctx, label);
	if (key->label == NULL)
		DST_RET(ISC_R_NOMEMORY);

	pk11_return_session(pk11_ctx);
	memset(pk11_ctx, 0, sizeof(*pk11_ctx));
	isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));

	attr = pk11_attribute_bytype(rsa, CKA_MODULUS);
	INSIST(attr != NULL);
	key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen);

	return (ISC_R_SUCCESS);

    err:
	if (pk11_ctx != NULL) {
		pk11_return_session(pk11_ctx);
		memset(pk11_ctx, 0, sizeof(*pk11_ctx));
		isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));
	}

	return (ret);
}
Exemple #11
0
int
main(int argc, char *argv[]) {
	isc_result_t result;
	CK_RV rv;
	CK_SLOT_ID slot = 0;
	CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE;
	CK_MECHANISM mech = { CKM_SHA_1, NULL, 0 };
	CK_ULONG len = sizeof(buf);
	pk11_context_t pctx;
	char *lib_name = NULL;
	int error = 0;
	int c, errflg = 0;
	unsigned int count = 1000;
	unsigned int i;
	struct timespec starttime;
	struct timespec endtime;

	while ((c = isc_commandline_parse(argc, argv, ":m:s:n:")) != -1) {
		switch (c) {
		case 'm':
			lib_name = isc_commandline_argument;
			break;
		case 's':
			slot = atoi(isc_commandline_argument);
			break;
		case 'n':
			count = atoi(isc_commandline_argument);
			break;
		case ':':
			fprintf(stderr,
				"Option -%c requires an operand\n",
				isc_commandline_option);
			errflg++;
			break;
		case '?':
		default:
			fprintf(stderr, "Unrecognised option: -%c\n",
				isc_commandline_option);
			errflg++;
		}
	}

	if (errflg) {
		fprintf(stderr, "Usage:\n");
		fprintf(stderr,
			"\tssha1 [-m module] [-s slot] [-n count]\n");
		exit(1);
	}

	/* Initialize the CRYPTOKI library */
	if (lib_name != NULL)
		pk11_set_lib_name(lib_name);

	result = pk11_get_session(&pctx, OP_ANY, ISC_FALSE, ISC_FALSE,
				  NULL, slot);
	if (result != ISC_R_SUCCESS) {
		fprintf(stderr, "Error initializing PKCS#11: %s\n",
			isc_result_totext(result));
		exit(1);
	}

	hSession = pctx.session;

	/* Randomize the buffer */
	rv = pkcs_C_GenerateRandom(hSession, buf, len);
	if (rv != CKR_OK) {
		fprintf(stderr, "C_GenerateRandom: Error = 0x%.8lX\n", rv);
		goto exit_session;
	}

	if (clock_gettime(CLOCK_REALTIME, &starttime) < 0) {
		perror("clock_gettime(start)");
		goto exit_session;
	}

	/* Initialize Digest */
	rv = pkcs_C_DigestInit(hSession, &mech);
	if (rv != CKR_OK) {
		fprintf(stderr, "C_DigestInit: Error = 0x%.8lX\n", rv);
		goto exit_session;
	}


	for (i = 0; i < count; i++) {
		/* Digest buffer */
		rv = pkcs_C_DigestUpdate(hSession, buf, len);
		if (rv != CKR_OK) {
			fprintf(stderr,
				"C_DigestUpdate[%u]: Error = 0x%.8lX\n",
				i, rv);
			error = 1;
			break;
		}
	}

	/* Finalize Digest (unconditionally) */
	len = 20U;
	rv = pkcs_C_DigestFinal(hSession, buf, &len);
	if ((rv != CKR_OK) && !error)
		fprintf(stderr, "C_DigestFinal: Error = 0x%.8lX\n", rv);

	if (clock_gettime(CLOCK_REALTIME, &endtime) < 0) {
		perror("clock_gettime(end)");
		goto exit_session;
	}

	endtime.tv_sec -= starttime.tv_sec;
	endtime.tv_nsec -= starttime.tv_nsec;
	while (endtime.tv_nsec < 0) {
		endtime.tv_sec -= 1;
		endtime.tv_nsec += 1000000000;
	}
	printf("%uK digested bytes in %ld.%09lds\n", i,
	       endtime.tv_sec, endtime.tv_nsec);
	if (i > 0)
		printf("%g digested bytes/s\n",
		       1024 * i / ((double) endtime.tv_sec +
				   (double) endtime.tv_nsec / 1000000000.));

    exit_session:
	pk11_return_session(&pctx);
	pk11_shutdown();

	exit(error);
}
Exemple #12
0
static isc_result_t
pkcs11gost_generate(dst_key_t *key, int unused, void (*callback)(int)) {
	CK_RV rv;
	CK_MECHANISM mech = { CKM_GOSTR3410_KEY_PAIR_GEN, NULL, 0 };
	CK_KEY_TYPE  keyType = CKK_GOSTR3410;
	CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE;
	CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY;
	CK_ATTRIBUTE pubTemplate[] =
	{
		{ CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) },
		{ 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_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_OBJECT_HANDLE priv = CK_INVALID_HANDLE;
	CK_OBJECT_HANDLE privClass = CKO_PRIVATE_KEY;
	CK_ATTRIBUTE privTemplate[] =
	{
		{ CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) },
		{ 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_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) },
		{ CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
	};
	CK_ATTRIBUTE *attr;
	pk11_object_t *gost;
	pk11_context_t *pk11_ctx;
	isc_result_t ret;

	UNUSED(unused);
	UNUSED(callback);

	pk11_ctx = (pk11_context_t *) isc_mem_get(key->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;

	PK11_RET(pkcs_C_GenerateKeyPair,
		 (pk11_ctx->session, &mech,
		  pubTemplate, (CK_ULONG) 7,
		  privTemplate, (CK_ULONG) 7,
		  &pub, &priv),
		 DST_R_CRYPTOFAILURE);

	gost = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*gost));
	if (gost == NULL)
		DST_RET(ISC_R_NOMEMORY);
	memset(gost, 0, sizeof(*gost));
	key->keydata.pkey = gost;
	gost->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx,
						  sizeof(*attr) * 2);
	if (gost->repr == NULL)
		DST_RET(ISC_R_NOMEMORY);
	memset(gost->repr, 0, sizeof(*attr) * 2);
	gost->attrcnt = 2;

	attr = gost->repr;
	attr[0].type = CKA_VALUE;
	attr[1].type = CKA_VALUE2;

	attr = gost->repr;
	PK11_RET(pkcs_C_GetAttributeValue,
		 (pk11_ctx->session, pub, attr, 1),
		 DST_R_CRYPTOFAILURE);
	attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen);
	if (attr->pValue == NULL)
		DST_RET(ISC_R_NOMEMORY);
	memset(attr->pValue, 0, attr->ulValueLen);
	PK11_RET(pkcs_C_GetAttributeValue,
		 (pk11_ctx->session, pub, attr, 1),
		 DST_R_CRYPTOFAILURE);

	attr++;
	attr->type = CKA_VALUE;
	PK11_RET(pkcs_C_GetAttributeValue,
		 (pk11_ctx->session, priv, attr, 1),
		 DST_R_CRYPTOFAILURE);
	attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen);
	if (attr->pValue == NULL)
		DST_RET(ISC_R_NOMEMORY);
	memset(attr->pValue, 0, attr->ulValueLen);
	PK11_RET(pkcs_C_GetAttributeValue,
		 (pk11_ctx->session, priv, attr, 1),
		 DST_R_CRYPTOFAILURE);
	attr->type = CKA_VALUE2;

	(void) pkcs_C_DestroyObject(pk11_ctx->session, priv);
	(void) pkcs_C_DestroyObject(pk11_ctx->session, pub);
	pk11_return_session(pk11_ctx);
	memset(pk11_ctx, 0, sizeof(*pk11_ctx));
	isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));

	return (ISC_R_SUCCESS);

    err:
	pkcs11gost_destroy(key);
	if (priv != CK_INVALID_HANDLE)
		(void) pkcs_C_DestroyObject(pk11_ctx->session, priv);
	if (pub != CK_INVALID_HANDLE)
		(void) pkcs_C_DestroyObject(pk11_ctx->session, pub);
	pk11_return_session(pk11_ctx);
	memset(pk11_ctx, 0, sizeof(*pk11_ctx));
	isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));

	return (ret);
}
Exemple #13
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_generate(dst_key_t *key, int unused, void (*callback)(int)) {
	CK_RV rv;
	CK_MECHANISM mech = { CKM_DSA_PARAMETER_GEN, NULL, 0 };
	CK_OBJECT_HANDLE dp = CK_INVALID_HANDLE;
	CK_OBJECT_CLASS dpClass = CKO_DOMAIN_PARAMETERS;
	CK_KEY_TYPE  keyType = CKK_DSA;
	CK_ULONG bits = 0;
	CK_ATTRIBUTE dpTemplate[] =
	{
		{ CKA_CLASS, &dpClass, (CK_ULONG) sizeof(dpClass) },
		{ CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
		{ CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
		{ CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
		{ CKA_PRIME_BITS, &bits, (CK_ULONG) sizeof(bits) },
	};
	CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE;
	CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY;
	CK_ATTRIBUTE pubTemplate[] =
	{
		{ CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) },
		{ 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_PRIME, NULL, 0 },
		{ CKA_SUBPRIME, NULL, 0 },
		{ CKA_BASE, NULL, 0 }
	};
	CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE;
	CK_OBJECT_HANDLE privClass = CKO_PRIVATE_KEY;
	CK_ATTRIBUTE privTemplate[] =
	{
		{ CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) },
		{ 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_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) },
		{ CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
	};
	CK_ATTRIBUTE *attr;
	pk11_object_t *dsa;
	pk11_context_t *pk11_ctx;
	isc_result_t ret;
	unsigned int i;

	UNUSED(unused);
	UNUSED(callback);

	pk11_ctx = (pk11_context_t *) isc_mem_get(key->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;

	bits = key->key_size;
	PK11_RET(pkcs_C_GenerateKey,
		 (pk11_ctx->session, &mech, dpTemplate, (CK_ULONG) 5, &dp),
		 DST_R_CRYPTOFAILURE);

	dsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dsa));
	if (dsa == NULL)
		DST_RET(ISC_R_NOMEMORY);
	memset(dsa, 0, sizeof(*dsa));
	key->keydata.pkey = dsa;
	dsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 5);
	if (dsa->repr == NULL)
		DST_RET(ISC_R_NOMEMORY);
	memset(dsa->repr, 0, sizeof(*attr) * 5);
	dsa->attrcnt = 5;

	attr = dsa->repr;
	attr[0].type = CKA_PRIME;
	attr[1].type = CKA_SUBPRIME;
	attr[2].type = CKA_BASE;
	attr[3].type = CKA_VALUE;
	attr[4].type = CKA_VALUE2;

	PK11_RET(pkcs_C_GetAttributeValue,
		 (pk11_ctx->session, dp, attr, 3),
		 DST_R_CRYPTOFAILURE);

	for (i = 0; i <= 2; i++) {
		attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen);
		if (attr[i].pValue == NULL)
			DST_RET(ISC_R_NOMEMORY);
		memset(attr[i].pValue, 0, attr[i].ulValueLen);
	}
	PK11_RET(pkcs_C_GetAttributeValue,
		 (pk11_ctx->session, dp, attr, 3),
		 DST_R_CRYPTOFAILURE);
	pubTemplate[5].pValue = attr[0].pValue;
	pubTemplate[5].ulValueLen = attr[0].ulValueLen;
	pubTemplate[6].pValue = attr[1].pValue;
	pubTemplate[6].ulValueLen = attr[1].ulValueLen;
	pubTemplate[7].pValue = attr[2].pValue;
	pubTemplate[7].ulValueLen = attr[2].ulValueLen;

	mech.mechanism = CKM_DSA_KEY_PAIR_GEN;
	PK11_RET(pkcs_C_GenerateKeyPair,
		 (pk11_ctx->session, &mech,
		  pubTemplate, (CK_ULONG) 8,
		  privTemplate, (CK_ULONG) 7,
		  &pub, &priv),
		 DST_R_CRYPTOFAILURE);

	attr = dsa->repr;
	attr += 3;
	PK11_RET(pkcs_C_GetAttributeValue,
		 (pk11_ctx->session, pub, attr, 1),
		 DST_R_CRYPTOFAILURE);
	attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen);
	if (attr->pValue == NULL)
		DST_RET(ISC_R_NOMEMORY);
	memset(attr->pValue, 0, attr->ulValueLen);
	PK11_RET(pkcs_C_GetAttributeValue,
		 (pk11_ctx->session, pub, attr, 1),
		 DST_R_CRYPTOFAILURE);

	attr++;
	attr->type = CKA_VALUE;
	PK11_RET(pkcs_C_GetAttributeValue,
		 (pk11_ctx->session, priv, attr, 1),
		 DST_R_CRYPTOFAILURE);
	attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen);
	if (attr->pValue == NULL)
		DST_RET(ISC_R_NOMEMORY);
	memset(attr->pValue, 0, attr->ulValueLen);
	PK11_RET(pkcs_C_GetAttributeValue,
		 (pk11_ctx->session, priv, attr, 1),
		 DST_R_CRYPTOFAILURE);
	attr->type = CKA_VALUE2;

	(void) pkcs_C_DestroyObject(pk11_ctx->session, priv);
	(void) pkcs_C_DestroyObject(pk11_ctx->session, pub);
	(void) pkcs_C_DestroyObject(pk11_ctx->session, dp);
	pk11_return_session(pk11_ctx);
	memset(pk11_ctx, 0, sizeof(*pk11_ctx));
	isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));

	return (ISC_R_SUCCESS);

    err:
	pkcs11dsa_destroy(key);
	if (priv != CK_INVALID_HANDLE)
		(void) pkcs_C_DestroyObject(pk11_ctx->session, priv);
	if (pub != CK_INVALID_HANDLE)
		(void) pkcs_C_DestroyObject(pk11_ctx->session, pub);
	if (dp != CK_INVALID_HANDLE)
		(void) pkcs_C_DestroyObject(pk11_ctx->session, dp);
	pk11_return_session(pk11_ctx);
	memset(pk11_ctx, 0, sizeof(*pk11_ctx));
	isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));

	return (ret);
}
Exemple #15
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);
}
Exemple #16
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);
}
Exemple #17
0
static isc_result_t
pkcs11ecdsa_generate(dst_key_t *key, int unused, void (*callback)(int)) {
	CK_RV rv;
	CK_MECHANISM mech = { CKM_EC_KEY_PAIR_GEN, NULL, 0 };
	CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE;
	CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY;
	CK_KEY_TYPE  keyType = CKK_EC;
	CK_ATTRIBUTE pubTemplate[] =
	{
		{ CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) },
		{ 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 }
	};
	CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE;
	CK_OBJECT_HANDLE privClass = CKO_PRIVATE_KEY;
	CK_ATTRIBUTE privTemplate[] =
	{
		{ CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) },
		{ 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_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) },
		{ CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }
	};
	CK_ATTRIBUTE *attr;
	pk11_object_t *ec;
	pk11_context_t *pk11_ctx;
	isc_result_t ret;

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

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

	ec = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*ec));
	if (ec == NULL)
		DST_RET(ISC_R_NOMEMORY);
	memset(ec, 0, sizeof(*ec));
	key->keydata.pkey = ec;
	ec->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 3);
	if (ec->repr == NULL)
		DST_RET(ISC_R_NOMEMORY);
	memset(ec->repr, 0, sizeof(*attr) * 3);
	ec->attrcnt = 3;

	attr = ec->repr;
	attr[0].type = CKA_EC_PARAMS;
	attr[1].type = CKA_EC_POINT;
	attr[2].type = CKA_VALUE;

	attr = &pubTemplate[5];
	SETCURVE();

	PK11_RET(pkcs_C_GenerateKeyPair,
		 (pk11_ctx->session, &mech,
		  pubTemplate, (CK_ULONG) 6,
		  privTemplate, (CK_ULONG) 7,
		  &pub, &priv),
		 DST_R_CRYPTOFAILURE);

	attr = &pubTemplate[5];
	FREECURVE();

	attr = ec->repr;
	SETCURVE();

	attr++;
	PK11_RET(pkcs_C_GetAttributeValue,
		 (pk11_ctx->session, pub, attr, 1),
		 DST_R_CRYPTOFAILURE);
	attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen);
	if (attr->pValue == NULL)
		DST_RET(ISC_R_NOMEMORY);
	memset(attr->pValue, 0, attr->ulValueLen);
	PK11_RET(pkcs_C_GetAttributeValue,
		 (pk11_ctx->session, pub, attr, 1),
		 DST_R_CRYPTOFAILURE);

	attr++;
	PK11_RET(pkcs_C_GetAttributeValue,
		 (pk11_ctx->session, priv, attr, 1),
		 DST_R_CRYPTOFAILURE);
	attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen);
	if (attr->pValue == NULL)
		DST_RET(ISC_R_NOMEMORY);
	memset(attr->pValue, 0, attr->ulValueLen);
	PK11_RET(pkcs_C_GetAttributeValue,
		 (pk11_ctx->session, priv, attr, 1),
		 DST_R_CRYPTOFAILURE);

	(void) pkcs_C_DestroyObject(pk11_ctx->session, priv);
	(void) pkcs_C_DestroyObject(pk11_ctx->session, pub);
	pk11_return_session(pk11_ctx);
	memset(pk11_ctx, 0, sizeof(*pk11_ctx));
	isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));

	if (key->key_alg == DST_ALG_ECDSA256)
		key->key_size = DNS_KEY_ECDSA256SIZE * 4;
	else
		key->key_size = DNS_KEY_ECDSA384SIZE * 4;

	return (ISC_R_SUCCESS);

 err:
	pkcs11ecdsa_destroy(key);
	if (priv != CK_INVALID_HANDLE)
		(void) pkcs_C_DestroyObject(pk11_ctx->session, priv);
	if (pub != CK_INVALID_HANDLE)
		(void) pkcs_C_DestroyObject(pk11_ctx->session, pub);
	pk11_return_session(pk11_ctx);
	memset(pk11_ctx, 0, sizeof(*pk11_ctx));
	isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));

	return (ret);
}
Exemple #18
0
static isc_result_t
pkcs11dh_generate(dst_key_t *key, int generator, void (*callback)(int)) {
	CK_RV rv;
	CK_MECHANISM mech = { CKM_DH_PKCS_PARAMETER_GEN, NULL, 0 };
	CK_OBJECT_HANDLE domainparams = CK_INVALID_HANDLE;
	CK_OBJECT_CLASS dClass = CKO_DOMAIN_PARAMETERS;
	CK_KEY_TYPE keyType = CKK_DH;
	CK_ULONG bits = 0;
	CK_ATTRIBUTE dTemplate[] =
	{
		{ CKA_CLASS, &dClass, (CK_ULONG) sizeof(dClass) },
		{ CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
		{ CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
		{ CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
		{ CKA_PRIME_BITS, &bits, (CK_ULONG) sizeof(bits) }
	};
	CK_ATTRIBUTE pTemplate[] =
	{
		{ CKA_PRIME, NULL, 0 },
		{ CKA_BASE, NULL, 0 }
	};
	CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE;
	CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY;
	CK_ATTRIBUTE pubTemplate[] =
	{
		{ CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) },
		{ CKA_KEY_TYPE,&keyType, (CK_ULONG) sizeof(keyType) },
		{ CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
		{ CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
		{ CKA_PRIME, NULL, 0 },
		{ CKA_BASE, NULL, 0 },
	};
	CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE;
	CK_OBJECT_HANDLE privClass = CKO_PRIVATE_KEY;
	CK_ATTRIBUTE privTemplate[] =
	{
		{ CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) },
		{ 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_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) },
		{ CKA_DERIVE, &truevalue, (CK_ULONG) sizeof(truevalue) },
	};
	CK_ATTRIBUTE *attr;
	pk11_object_t *dh = NULL;
	pk11_context_t *pk11_ctx;
	isc_result_t ret;

	UNUSED(callback);

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

	bits = key->key_size;
	if ((generator == 0) &&
	    ((bits == 768) || (bits == 1024) || (bits == 1536))) {
		if (bits == 768) {
			pubTemplate[4].pValue =
				isc_mem_get(key->mctx, sizeof(pk11_dh_bn768));
			if (pubTemplate[4].pValue == NULL)
				DST_RET(ISC_R_NOMEMORY);
			memmove(pubTemplate[4].pValue,
				pk11_dh_bn768, sizeof(pk11_dh_bn768));
			pubTemplate[4].ulValueLen = sizeof(pk11_dh_bn768);
		} else if (bits == 1024) {
			pubTemplate[4].pValue =
				isc_mem_get(key->mctx, sizeof(pk11_dh_bn1024));
			if (pubTemplate[4].pValue == NULL)
				DST_RET(ISC_R_NOMEMORY);
			memmove(pubTemplate[4].pValue,
				pk11_dh_bn1024, sizeof(pk11_dh_bn1024));
			pubTemplate[4].ulValueLen = sizeof(pk11_dh_bn1024);
		} else {
			pubTemplate[4].pValue =
				isc_mem_get(key->mctx, sizeof(pk11_dh_bn1536));
			if (pubTemplate[4].pValue == NULL)
				DST_RET(ISC_R_NOMEMORY);
			memmove(pubTemplate[4].pValue,
				pk11_dh_bn1536, sizeof(pk11_dh_bn1536));
			pubTemplate[4].ulValueLen = sizeof(pk11_dh_bn1536);
		}
		pubTemplate[5].pValue = isc_mem_get(key->mctx,
						    sizeof(pk11_dh_bn2));
		if (pubTemplate[5].pValue == NULL)
			DST_RET(ISC_R_NOMEMORY);
		memmove(pubTemplate[5].pValue, pk11_dh_bn2,
			sizeof(pk11_dh_bn2));
		pubTemplate[5].ulValueLen = sizeof(pk11_dh_bn2);
	} else {
		PK11_RET(pkcs_C_GenerateKey,
			 (pk11_ctx->session, &mech,
			  dTemplate, (CK_ULONG) 5, &domainparams),
			 DST_R_CRYPTOFAILURE);
		PK11_RET(pkcs_C_GetAttributeValue,
			 (pk11_ctx->session, domainparams,
			  pTemplate, (CK_ULONG) 2),
			 DST_R_CRYPTOFAILURE);
		pTemplate[0].pValue = isc_mem_get(key->mctx,
						  pTemplate[0].ulValueLen);
		if (pTemplate[0].pValue == NULL)
			DST_RET(ISC_R_NOMEMORY);
		memset(pTemplate[0].pValue, 0, pTemplate[0].ulValueLen);
		pTemplate[1].pValue = isc_mem_get(key->mctx,
						  pTemplate[1].ulValueLen);
		if (pTemplate[1].pValue == NULL)
			DST_RET(ISC_R_NOMEMORY);
		memset(pTemplate[1].pValue, 0, pTemplate[1].ulValueLen);
		PK11_RET(pkcs_C_GetAttributeValue,
			 (pk11_ctx->session, domainparams,
			  pTemplate, (CK_ULONG) 2),
			 DST_R_CRYPTOFAILURE);

		pubTemplate[4].pValue = pTemplate[0].pValue;
		pubTemplate[4].ulValueLen = pTemplate[0].ulValueLen;
		pTemplate[0].pValue = NULL;
		pubTemplate[5].pValue = pTemplate[1].pValue;
		pubTemplate[5].ulValueLen = pTemplate[1].ulValueLen;
		pTemplate[1].pValue = NULL;
	}

	mech.mechanism = CKM_DH_PKCS_KEY_PAIR_GEN;
	PK11_RET(pkcs_C_GenerateKeyPair,
		 (pk11_ctx->session, &mech,
		  pubTemplate, (CK_ULONG) 6,
		  privTemplate, (CK_ULONG) 7,
		  &pub, &priv),
		 DST_R_CRYPTOFAILURE);

	dh = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dh));
	if (dh == NULL)
		DST_RET(ISC_R_NOMEMORY);
	memset(dh, 0,  sizeof(*dh));
	key->keydata.pkey = dh;
	dh->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 4);
	if (dh->repr == NULL)
		DST_RET(ISC_R_NOMEMORY);
	memset(dh->repr, 0, sizeof(*attr) * 4);
	dh->attrcnt = 4;

	attr = dh->repr;
	attr[0].type = CKA_PRIME;
	attr[0].pValue = pubTemplate[4].pValue;
	attr[0].ulValueLen = pubTemplate[4].ulValueLen;
	pubTemplate[4].pValue = NULL;

	attr[1].type = CKA_BASE;
	attr[1].pValue = pubTemplate[5].pValue;
	attr[1].ulValueLen = pubTemplate[5].ulValueLen;
	pubTemplate[5].pValue =NULL;

	attr += 2;
	attr->type = CKA_VALUE;
	PK11_RET(pkcs_C_GetAttributeValue,
		 (pk11_ctx->session, pub, attr, 1),
		 DST_R_CRYPTOFAILURE);
	attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen);
	if (attr->pValue == NULL)
		DST_RET(ISC_R_NOMEMORY);
	memset(attr->pValue, 0, attr->ulValueLen);
	PK11_RET(pkcs_C_GetAttributeValue,
		 (pk11_ctx->session, pub, attr, 1),
		 DST_R_CRYPTOFAILURE);

	attr++;
	attr->type = CKA_VALUE;
	PK11_RET(pkcs_C_GetAttributeValue,
		 (pk11_ctx->session, priv, attr, 1),
		 DST_R_CRYPTOFAILURE);
	attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen);
	if (attr->pValue == NULL)
		DST_RET(ISC_R_NOMEMORY);
	memset(attr->pValue, 0, attr->ulValueLen);
	PK11_RET(pkcs_C_GetAttributeValue,
		 (pk11_ctx->session, priv, attr, 1),
		 DST_R_CRYPTOFAILURE);
	attr->type = CKA_VALUE2;

	(void) pkcs_C_DestroyObject(pk11_ctx->session, priv);
	(void) pkcs_C_DestroyObject(pk11_ctx->session, pub);
	(void) pkcs_C_DestroyObject(pk11_ctx->session, domainparams);
	pk11_return_session(pk11_ctx);
	memset(pk11_ctx, 0, sizeof(*pk11_ctx));
	isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));

	return (ISC_R_SUCCESS);

    err:
	pkcs11dh_destroy(key);
	if (priv != CK_INVALID_HANDLE)
		(void) pkcs_C_DestroyObject(pk11_ctx->session, priv);
	if (pub != CK_INVALID_HANDLE)
		(void) pkcs_C_DestroyObject(pk11_ctx->session, pub);
	if (domainparams != CK_INVALID_HANDLE)
		(void) pkcs_C_DestroyObject(pk11_ctx->session, domainparams);

	if (pubTemplate[4].pValue != NULL) {
		memset(pubTemplate[4].pValue, 0, pubTemplate[4].ulValueLen);
		isc_mem_put(key->mctx,
			    pubTemplate[4].pValue,
			    pubTemplate[4].ulValueLen);
	}
	if (pubTemplate[5].pValue != NULL) {
		memset(pubTemplate[5].pValue, 0, pubTemplate[5].ulValueLen);
		isc_mem_put(key->mctx,
			    pubTemplate[5].pValue,
			    pubTemplate[5].ulValueLen);
	}
	if (pTemplate[0].pValue != NULL) {
		memset(pTemplate[0].pValue, 0, pTemplate[0].ulValueLen);
		isc_mem_put(key->mctx,
			    pTemplate[0].pValue,
			    pTemplate[0].ulValueLen);
	}
	if (pTemplate[1].pValue != NULL) {
		memset(pTemplate[1].pValue, 0, pTemplate[1].ulValueLen);
		isc_mem_put(key->mctx,
			    pTemplate[1].pValue,
			    pTemplate[1].ulValueLen);
	}

	pk11_return_session(pk11_ctx);
	memset(pk11_ctx, 0, sizeof(*pk11_ctx));
	isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));

	return (ret);
}
Exemple #19
0
static isc_result_t
pkcs11dh_computesecret(const dst_key_t *pub, const dst_key_t *priv,
		       isc_buffer_t *secret)
{
	CK_RV rv;
	CK_MECHANISM mech = { CKM_DH_PKCS_DERIVE, NULL, 0 };
	CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
	CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
	CK_OBJECT_HANDLE hDerived = CK_INVALID_HANDLE;
	CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
	CK_ATTRIBUTE *attr;
	CK_ULONG secLen;
	CK_ATTRIBUTE keyTemplate[] =
	{
		{ CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
		{ CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
		{ CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
		{ CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
		{ CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) },
		{ CKA_VALUE_LEN, &secLen, (CK_ULONG) sizeof(secLen) }
	};
	CK_ATTRIBUTE valTemplate[] =
	{
		{ CKA_VALUE, NULL, 0 }
	};
	CK_BYTE *secValue;
	pk11_context_t ctx;
	isc_result_t ret;
	unsigned int i;
	isc_region_t r;

	REQUIRE(pub->keydata.pkey != NULL);
	REQUIRE(priv->keydata.pkey != NULL);
	REQUIRE(priv->keydata.pkey->repr != NULL);
	attr = pk11_attribute_bytype(pub->keydata.pkey, CKA_PRIME);
	if (attr == NULL)
		return (DST_R_INVALIDPUBLICKEY);
	REQUIRE(attr != NULL);
	secLen = attr->ulValueLen;
	attr = pk11_attribute_bytype(pub->keydata.pkey, CKA_VALUE);
	if (attr == NULL)
		return (DST_R_INVALIDPUBLICKEY);

	ret = pk11_get_session(&ctx, OP_DH, ISC_TRUE, ISC_FALSE, ISC_FALSE,
			       NULL, pk11_get_best_token(OP_DH));
	if (ret != ISC_R_SUCCESS)
		return (ret);

	mech.ulParameterLen = attr->ulValueLen;
	mech.pParameter = isc_mem_get(pub->mctx, mech.ulParameterLen);
	if (mech.pParameter == NULL)
		DST_RET(ISC_R_NOMEMORY);
	memmove(mech.pParameter, attr->pValue, mech.ulParameterLen);

	ret = pkcs11dh_loadpriv(priv, ctx.session, &hKey);
	if (ret != ISC_R_SUCCESS)
		goto err;

	PK11_RET(pkcs_C_DeriveKey,
		 (ctx.session, &mech, hKey,
		  keyTemplate, (CK_ULONG) 6, &hDerived),
		 DST_R_COMPUTESECRETFAILURE);

	attr = valTemplate;
	PK11_RET(pkcs_C_GetAttributeValue,
		 (ctx.session, hDerived, attr, (CK_ULONG) 1),
		 DST_R_CRYPTOFAILURE);
	attr->pValue = isc_mem_get(pub->mctx, attr->ulValueLen);
	if (attr->pValue == NULL)
		DST_RET(ISC_R_NOMEMORY);
	memset(attr->pValue, 0, attr->ulValueLen);
	PK11_RET(pkcs_C_GetAttributeValue,
		 (ctx.session, hDerived, attr, (CK_ULONG) 1),
		 DST_R_CRYPTOFAILURE);

	/* strip leading zeros */
	secValue = (CK_BYTE_PTR) attr->pValue;
	for (i = 0; i < attr->ulValueLen; i++)
		if (secValue[i] != 0)
			break;
	isc_buffer_availableregion(secret, &r);
	if (r.length < attr->ulValueLen - i)
		DST_RET(ISC_R_NOSPACE);
	memmove(r.base, secValue + i, attr->ulValueLen - i);
	isc_buffer_add(secret, attr->ulValueLen - i);
	ret = ISC_R_SUCCESS;

    err:
	if (hDerived != CK_INVALID_HANDLE)
		(void) pkcs_C_DestroyObject(ctx.session, hDerived);
	if (valTemplate[0].pValue != NULL) {
		memset(valTemplate[0].pValue, 0, valTemplate[0].ulValueLen);
		isc_mem_put(pub->mctx,
			    valTemplate[0].pValue,
			    valTemplate[0].ulValueLen);
	}
	if ((hKey != CK_INVALID_HANDLE) && !priv->keydata.pkey->ontoken)
		(void) pkcs_C_DestroyObject(ctx.session, hKey);
	if (mech.pParameter != NULL) {
		memset(mech.pParameter, 0, mech.ulParameterLen);
		isc_mem_put(pub->mctx, mech.pParameter, mech.ulParameterLen);
	}
	pk11_return_session(&ctx);
	return (ret);
}
Exemple #20
0
int
main(int argc, char *argv[]) {
	isc_result_t result;
	CK_RV rv;
	CK_SLOT_ID slot = 0;
	CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE;
	CK_ATTRIBUTE sTemplate[] =
	{
		{ CKA_LABEL, label, (CK_ULONG) sizeof(label) },
	};
	CK_OBJECT_HANDLE sKey = CK_INVALID_HANDLE;
	CK_ULONG found = 0;
	pk11_context_t pctx;
	char *lib_name = NULL;
	char *pin = NULL;
	int error = 0;
	int c, errflg = 0;
	unsigned int count = 1000;
	unsigned int i;
	struct timespec starttime;
	struct timespec endtime;

	while ((c = isc_commandline_parse(argc, argv, ":m:s:p:n:")) != -1) {
		switch (c) {
		case 'm':
			lib_name = isc_commandline_argument;
			break;
		case 's':
			slot = atoi(isc_commandline_argument);
			break;
		case 'p':
			pin = isc_commandline_argument;
			break;
		case 'n':
			count = atoi(isc_commandline_argument);
			break;
		case ':':
			fprintf(stderr,
				"Option -%c requires an operand\n",
				isc_commandline_option);
			errflg++;
			break;
		case '?':
		default:
			fprintf(stderr, "Unrecognised option: -%c\n",
				isc_commandline_option);
			errflg++;
		}
	}

	if (errflg) {
		fprintf(stderr, "Usage:\n");
		fprintf(stderr,
			"\tfind [-m module] [-s slot] [-p pin] [-n count]\n");
		exit(1);
	}

	/* Initialize the CRYPTOKI library */
	if (lib_name != NULL)
		pk11_set_lib_name(lib_name);

	if (pin == NULL)
		pin = getpassphrase("Enter Pin: ");

	result = pk11_get_session(&pctx, OP_ANY, ISC_FALSE, ISC_TRUE,
				  (const char *) pin, slot);
	if (result != ISC_R_SUCCESS) {
		fprintf(stderr, "Error initializing PKCS#11: %s\n",
			isc_result_totext(result));
		exit(1);
	}

	if (pin != NULL)
		memset(pin, 0, strlen((char *)pin));

	hSession = pctx.session;

	if (clock_gettime(CLOCK_REALTIME, &starttime) < 0) {
		perror("clock_gettime(start)");
		goto exit_objects;
	}

	for (i = 0; !error && (i < count); i++) {
		rv = pkcs_C_FindObjectsInit(hSession, sTemplate, 1);
		if (rv != CKR_OK) {
			fprintf(stderr,
				"C_FindObjectsInit[%u]: Error = 0x%.8lX\n",
				i, rv);
			error = 1;
			break;
		}

		rv = pkcs_C_FindObjects(hSession, &sKey, 1, &found);
		if (rv != CKR_OK) {
			fprintf(stderr,
				"C_FindObjects[%u]: Error = 0x%.8lX\n",
				i, rv);
			error = 1;
			/* no break here! */
		}

		rv = pkcs_C_FindObjectsFinal(hSession);
		if (rv != CKR_OK) {
			fprintf(stderr,
				"C_FindObjectsFinal[%u]: Error = 0x%.8lX\n",
				i, rv);
			error = 1;
			break;
		}
	}

	if (clock_gettime(CLOCK_REALTIME, &endtime) < 0) {
		perror("clock_gettime(end)");
		goto exit_objects;
	}

	endtime.tv_sec -= starttime.tv_sec;
	endtime.tv_nsec -= starttime.tv_nsec;
	while (endtime.tv_nsec < 0) {
		endtime.tv_sec -= 1;
		endtime.tv_nsec += 1000000000;
	}
	printf("%u object searches in %ld.%09lds\n", i,
	       endtime.tv_sec, endtime.tv_nsec);
	if (i > 0)
		printf("%g object searches/s\n",
		       1024 * i / ((double) endtime.tv_sec +
				   (double) endtime.tv_nsec / 1000000000.));

    exit_objects:
	pk11_return_session(&pctx);
	pk11_shutdown();

	exit(error);
}
Exemple #21
0
int
main(int argc, char *argv[]) {
	isc_result_t result;
	CK_RV rv;
	CK_SLOT_ID slot = 0;
	CK_SESSION_HANDLE hSession;
	CK_MECHANISM mech = { CKM_MD5, NULL, 0 };
	CK_ULONG len;
	pk11_context_t pctx;
	pk11_optype_t op_type = OP_DIGEST;
	char *lib_name = NULL;
	char *pin = NULL;
	int error = 0;
	isc_boolean_t logon = ISC_TRUE;
	int c, errflg = 0;
	size_t sum = 0;
	unsigned int i;

	while ((c = isc_commandline_parse(argc, argv, ":m:s:np:")) != -1) {
		switch (c) {
		case 'm':
			lib_name = isc_commandline_argument;
			break;
		case 's':
			slot = atoi(isc_commandline_argument);
			op_type = OP_ANY;
			break;
		case 'n':
			logon = ISC_FALSE;
			break;
		case 'p':
			pin = isc_commandline_argument;
			break;
		case ':':
			fprintf(stderr,
				"Option -%c requires an operand\n",
				isc_commandline_option);
			errflg++;
			break;
		case '?':
		default:
			fprintf(stderr, "Unrecognised option: -%c\n",
				isc_commandline_option);
			errflg++;
		}
	}

	if (errflg) {
		fprintf(stderr, "Usage:\n");
		fprintf(stderr,
			"\tpkcs11-md5sum [-m module] [-s slot] [-n|-p pin]\n");
		exit(1);
	}

	pk11_result_register();

	/* Initialize the CRYPTOKI library */
	if (lib_name != NULL)
		pk11_set_lib_name(lib_name);

	if (logon && pin == NULL)
		pin = getpassphrase("Enter Pin: ");

	result = pk11_get_session(&pctx, op_type, ISC_FALSE, ISC_FALSE, logon,
				  (const char *) pin, slot);
	if ((result != ISC_R_SUCCESS) &&
	    (result != PK11_R_NORANDOMSERVICE) &&
	    (result != PK11_R_NOAESSERVICE)) {
		fprintf(stderr, "Error initializing PKCS#11: %s\n",
			isc_result_totext(result));
		exit(1);
	}

	if (pin != NULL)
		memset(pin, 0, strlen((char *)pin));

	hSession = pctx.session;

	rv = pkcs_C_DigestInit(hSession, &mech);
	if (rv != CKR_OK) {
		fprintf(stderr, "C_DigestInit: Error = 0x%.8lX\n", rv);
		error = 1;
		goto exit_session;
	}

	for (;;) {
		size_t n;

		for (;;) {
			n = fread(buffer + sum, 1, BLOCKSIZE - sum, stdin);
			sum += n;
			if (sum == BLOCKSIZE)
				break;
			if (n == 0) {
				if (ferror(stdin)) {
					fprintf(stderr, "fread failed\n");
					error = 1;
					goto exit_session;
				}
				goto partial_block;
			}
			if (feof(stdin))
				goto partial_block;
		}

		rv = pkcs_C_DigestUpdate(hSession, (CK_BYTE_PTR) buffer,
					 (CK_ULONG) BLOCKSIZE);
		if (rv != CKR_OK) {
			fprintf(stderr,
				"C_DigestUpdate: Error = 0x%.8lX\n",
				rv);
			error = 1;
			goto exit_session;
		}
	}

partial_block:
	if (sum > 0) {
		rv = pkcs_C_DigestUpdate(hSession, (CK_BYTE_PTR) buffer,
					 (CK_ULONG) sum);
		if (rv != CKR_OK) {
			fprintf(stderr,
				"C_DigestUpdate: Error = 0x%.8lX\n",
				rv);
			error = 1;
			goto exit_session;
		}
	}

	len = 16;
	rv = pkcs_C_DigestFinal(hSession, (CK_BYTE_PTR) digest, &len);
	if (rv != CKR_OK) {
		fprintf(stderr, "C_DigestFinal: Error = 0x%.8lX\n", rv);
		error = 1;
		goto exit_session;
	}
	if (len != 16) {
		fprintf(stderr, "C_DigestFinal: bad length = %lu\n", len);
		error = 1;
	}

	for (i = 0; i < 16; i++)
		printf("%02x", digest[i] & 0xff);
	printf("\n");

    exit_session:
	pk11_return_session(&pctx);
	(void) pk11_finalize();

	exit(error);
}
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);
}
Exemple #23
0
int
main(int argc, char *argv[]) {
	isc_result_t result;
	CK_RV rv;
	CK_SLOT_ID slot = 0;
	CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE;
	CK_OBJECT_HANDLE *hKey;
	CK_OBJECT_CLASS kClass = CKO_PUBLIC_KEY;
	CK_KEY_TYPE kType = CKK_RSA;
	CK_ATTRIBUTE kTemplate[] =
	{
		{ CKA_CLASS, &kClass, (CK_ULONG) sizeof(kClass) },
		{ CKA_KEY_TYPE, &kType, (CK_ULONG) sizeof(kType) },
		{ CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
		{ CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
		{ CKA_LABEL, (CK_BYTE_PTR) label, (CK_ULONG) sizeof(label) },
		{ CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) },
		{ CKA_MODULUS, modulus, (CK_ULONG) sizeof(modulus) },
		{ CKA_PUBLIC_EXPONENT, exponent, (CK_ULONG) sizeof(exponent) }
	};
	pk11_context_t pctx;
	char *lib_name = NULL;
	char *pin = NULL;
	int error = 0;
	int c, errflg = 0;
	int ontoken  = 0;
	unsigned int count = 1000;
	unsigned int i;
	struct timespec starttime;
	struct timespec endtime;

	while ((c = isc_commandline_parse(argc, argv, ":m:s:p:tn:")) != -1) {
		switch (c) {
		case 'm':
			lib_name = isc_commandline_argument;
			break;
		case 's':
			slot = atoi(isc_commandline_argument);
			break;
		case 'p':
			pin = isc_commandline_argument;
			break;
		case 't':
			ontoken = 1;
			break;
		case 'n':
			count = atoi(isc_commandline_argument);
			break;
		case ':':
			fprintf(stderr,
				"Option -%c requires an operand\n",
				isc_commandline_option);
			errflg++;
			break;
		case '?':
		default:
			fprintf(stderr, "Unrecognised option: -%c\n",
				isc_commandline_option);
			errflg++;
		}
	}

	if (errflg) {
		fprintf(stderr, "Usage:\n");
		fprintf(stderr,
			"\tpubrsa [-m module] [-s slot] [-p pin] "
			"[-t] [-n count]\n");
		exit(1);
	}

	/* Allocate hanles */
	hKey = (CK_SESSION_HANDLE *)
		malloc(count * sizeof(CK_SESSION_HANDLE));
	if (hKey == NULL) {
		perror("malloc");
		exit(1);
	}
	for (i = 0; i < count; i++)
		hKey[i] = CK_INVALID_HANDLE;

	/* Initialize the CRYPTOKI library */
	if (lib_name != NULL)
		pk11_set_lib_name(lib_name);

	if (pin == NULL)
		pin = getpassphrase("Enter Pin: ");

	result = pk11_get_session(&pctx, OP_ANY, ISC_TRUE, ISC_TRUE,
				  (const char *) pin, slot);
	if (result != ISC_R_SUCCESS) {
		fprintf(stderr, "Error initializing PKCS#11: %s\n",
			isc_result_totext(result));
		free(hKey);
		exit(1);
	}

	if (pin != NULL)
		memset(pin, 0, strlen((char *)pin));

	hSession = pctx.session;

	if (ontoken)
		kTemplate[2].pValue = &truevalue;

	if (clock_gettime(CLOCK_REALTIME, &starttime) < 0) {
		perror("clock_gettime(start)");
		goto exit_objects;
	}

	for (i = 0; i < count; i++) {
		(void) snprintf(label, sizeof(label), "obj%u", i);
		kTemplate[4].ulValueLen = strlen(label);
		rv = pkcs_C_CreateObject(hSession, kTemplate, 8, &hKey[i]);
		if (rv != CKR_OK) {
			fprintf(stderr,
				"C_CreateObject[%u]: Error = 0x%.8lX\n",
				i, rv);
			error = 1;
			if (i == 0)
				goto exit_objects;
			break;
		}
	}

	if (clock_gettime(CLOCK_REALTIME, &endtime) < 0) {
		perror("clock_gettime(end)");
		goto exit_objects;
	}

	endtime.tv_sec -= starttime.tv_sec;
	endtime.tv_nsec -= starttime.tv_nsec;
	while (endtime.tv_nsec < 0) {
		endtime.tv_sec -= 1;
		endtime.tv_nsec += 1000000000;
	}
	printf("%u public RSA keys in %ld.%09lds\n", i,
	       endtime.tv_sec, endtime.tv_nsec);
	if (i > 0)
		printf("%g public RSA keys/s\n",
		       1024 * i / ((double) endtime.tv_sec +
				   (double) endtime.tv_nsec / 1000000000.));

    exit_objects:
	for (i = 0; i < count; i++) {
		/* Destroy objects */
		if (hKey[i] == CK_INVALID_HANDLE)
			continue;
		rv = pkcs_C_DestroyObject(hSession, hKey[i]);
		if ((rv != CKR_OK) && !errflg) {
			fprintf(stderr,
				"C_DestroyObject[%u]: Error = 0x%.8lX\n",
				i, rv);
			errflg = 1;
		}
	}

	free(hKey);

	pk11_return_session(&pctx);
	pk11_shutdown();

	exit(error);
}
Exemple #24
0
int
main(int argc, char *argv[]) {
	isc_result_t result;
	CK_RV rv;
	CK_SLOT_ID slot = 0;
	CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE;
	CK_ULONG len = sizeof(buf);
	pk11_context_t pctx;
	pk11_optype_t op_type = OP_RAND;
	char *lib_name = NULL;
	int error = 0;
	int c, errflg = 0;
	unsigned int count = 1000;
	unsigned int i;
	struct timespec starttime;
	struct timespec endtime;

	while ((c = isc_commandline_parse(argc, argv, ":m:s:n:")) != -1) {
		switch (c) {
		case 'm':
			lib_name = isc_commandline_argument;
			break;
		case 's':
			slot = atoi(isc_commandline_argument);
			op_type = OP_ANY;
			break;
		case 'n':
			count = atoi(isc_commandline_argument);
			break;
		case ':':
			fprintf(stderr,
				"Option -%c requires an operand\n",
				isc_commandline_option);
			errflg++;
			break;
		case '?':
		default:
			fprintf(stderr, "Unrecognised option: -%c\n",
				isc_commandline_option);
			errflg++;
		}
	}

	if (errflg) {
		fprintf(stderr, "Usage:\n");
		fprintf(stderr,
			"\trandom [-m module] [-s slot] [-n count]\n");
		exit(1);
	}

	pk11_result_register();

	/* Initialize the CRYPTOKI library */
	if (lib_name != NULL)
		pk11_set_lib_name(lib_name);

	result = pk11_get_session(&pctx, op_type, ISC_FALSE, ISC_FALSE,
				  ISC_FALSE, NULL, slot);
	if ((result != ISC_R_SUCCESS) &&
	    (result != PK11_R_NODIGESTSERVICE) &&
	    (result != PK11_R_NOAESSERVICE)) {
		fprintf(stderr, "Error initializing PKCS#11: %s\n",
			isc_result_totext(result));
		exit(1);
	}

	hSession = pctx.session;

	if (clock_gettime(CLOCK_REALTIME, &starttime) < 0) {
		perror("clock_gettime(start)");
		goto exit_session;
	}

	for (i = 0; i < count; i++) {
		/* Get random bytes */
		rv = pkcs_C_GenerateRandom(hSession, buf, len);
		if (rv != CKR_OK) {
			fprintf(stderr,
				"C_GenerateRandom[%u]: Error = 0x%.8lX\n",
				i, rv);
			error = 1;
			break;
		}
	}

	if (clock_gettime(CLOCK_REALTIME, &endtime) < 0) {
		perror("clock_gettime(end)");
		goto exit_session;
	}

	endtime.tv_sec -= starttime.tv_sec;
	endtime.tv_nsec -= starttime.tv_nsec;
	while (endtime.tv_nsec < 0) {
		endtime.tv_sec -= 1;
		endtime.tv_nsec += 1000000000;
	}
	printf("%uK random bytes in %ld.%09lds\n", i,
	       endtime.tv_sec, endtime.tv_nsec);
	if (i > 0)
		printf("%g random bytes/s\n",
		       1024 * i / ((double) endtime.tv_sec +
				   (double) endtime.tv_nsec / 1000000000.));

    exit_session:
	pk11_return_session(&pctx);
	(void) pk11_finalize();

	exit(error);
}
Exemple #25
0
int
main(int argc, char *argv[]) {
	isc_result_t result;
	CK_RV rv;
	CK_SLOT_ID slot = 0;
	CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE;
	CK_ULONG len;
	CK_ULONG slen;
	CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
	CK_OBJECT_CLASS kClass = CKO_PUBLIC_KEY;
	CK_KEY_TYPE kType = CKK_RSA;
	CK_ATTRIBUTE kTemplate[] =
	{
		{ CKA_CLASS, &kClass, (CK_ULONG) sizeof(kClass) },
		{ CKA_KEY_TYPE, &kType, (CK_ULONG) sizeof(kType) },
		{ CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
		{ CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
		{ CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) },
		{ CKA_MODULUS, modulus, (CK_ULONG) sizeof(modulus) },
		{ CKA_PUBLIC_EXPONENT, exponent, (CK_ULONG) sizeof(exponent) }
	};
	CK_MECHANISM mech = { CKM_SHA1_RSA_PKCS, NULL, 0 };
	pk11_context_t pctx;
	pk11_optype_t op_type = OP_RSA;
	char *lib_name = NULL;
	char *pin = NULL;
	int error = 0;
	int c, errflg = 0;
	int ontoken  = 0;
	unsigned int count = 1000;
	unsigned int i;
	struct timespec starttime;
	struct timespec endtime;

	while ((c = isc_commandline_parse(argc, argv, ":m:s:p:tn:")) != -1) {
		switch (c) {
		case 'm':
			lib_name = isc_commandline_argument;
			break;
		case 's':
			slot = atoi(isc_commandline_argument);
			op_type = OP_ANY;
			break;
		case 'p':
			pin = isc_commandline_argument;
			break;
		case 't':
			ontoken = 1;
			break;
		case 'n':
			count = atoi(isc_commandline_argument);
			break;
		case ':':
			fprintf(stderr,
				"Option -%c requires an operand\n",
				isc_commandline_option);
			errflg++;
			break;
		case '?':
		default:
			fprintf(stderr, "Unrecognised option: -%c\n",
				isc_commandline_option);
			errflg++;
		}
	}

	if (errflg) {
		fprintf(stderr, "Usage:\n");
		fprintf(stderr,
			"\tverify [-m module] [-s slot] [-p pin] "
			"[-t] [-n count]\n");
		exit(1);
	}

	pk11_result_register();

	/* Initialize the CRYPTOKI library */
	if (lib_name != NULL)
		pk11_set_lib_name(lib_name);

	if (pin == NULL)
		pin = getpassphrase("Enter Pin: ");

	result = pk11_get_session(&pctx, op_type, ISC_FALSE, ISC_TRUE,
				  ISC_TRUE, (const char *) pin, slot);
	if ((result != ISC_R_SUCCESS) &&
	    (result != PK11_R_NORANDOMSERVICE) &&
	    (result != PK11_R_NODIGESTSERVICE) &&
	    (result != PK11_R_NOAESSERVICE)) {
		fprintf(stderr, "Error initializing PKCS#11: %s\n",
			isc_result_totext(result));
		exit(1);
	}

	if (pin != NULL)
		memset(pin, 0, strlen((char *)pin));

	hSession = pctx.session;

	/* Create the private RSA key */
	if (ontoken)
		kTemplate[2].pValue = &truevalue;

	rv = pkcs_C_CreateObject(hSession, kTemplate, 7, &hKey);
	if (rv != CKR_OK) {
		fprintf(stderr, "C_CreateObject: Error = 0x%.8lX\n", rv);
		error = 1;
		goto exit_key;
	}

	/* Randomize the buffer */
	len = (CK_ULONG) sizeof(buf);
	rv = pkcs_C_GenerateRandom(hSession, buf, len);
	if (rv != CKR_OK) {
		fprintf(stderr, "C_GenerateRandom: Error = 0x%.8lX\n", rv);
		goto exit_key;
	}

	if (clock_gettime(CLOCK_REALTIME, &starttime) < 0) {
		perror("clock_gettime(start)");
		goto exit_key;
	}

	for (i = 0; i < count; i++) {
		/* Initialize Verify */
		rv = pkcs_C_VerifyInit(hSession, &mech, hKey);
		if (rv != CKR_OK) {
			fprintf(stderr,
				"C_VerifyInit[%u]: Error = 0x%.8lX\n",
				i, rv);
			error = 1;
			break;
		}

		/* Perform Verify */
		slen = (CK_ULONG) sizeof(sig);
		rv = pkcs_C_Verify(hSession, buf, len, sig, slen);
		if ((rv != CKR_OK) && (rv != CKR_SIGNATURE_INVALID)) {
			fprintf(stderr,
				"C_Verify[%u]: Error = 0x%.8lX\n",
				i, rv);
			error = 1;
			break;
		}
	}

	if (clock_gettime(CLOCK_REALTIME, &endtime) < 0) {
		perror("clock_gettime(end)");
		goto exit_key;
	}

	endtime.tv_sec -= starttime.tv_sec;
	endtime.tv_nsec -= starttime.tv_nsec;
	while (endtime.tv_nsec < 0) {
		endtime.tv_sec -= 1;
		endtime.tv_nsec += 1000000000;
	}
	printf("%u RSA verify in %ld.%09lds\n", i,
	       endtime.tv_sec, endtime.tv_nsec);
	if (i > 0)
		printf("%g RSA verify/s\n",
		       1024 * i / ((double) endtime.tv_sec +
				   (double) endtime.tv_nsec / 1000000000.));

    exit_key:
	if (hKey != CK_INVALID_HANDLE) {
		rv = pkcs_C_DestroyObject(hSession, hKey);
		if (rv != CKR_OK) {
			fprintf(stderr,
				"C_DestroyObject: Error = 0x%.8lX\n",
				rv);
			errflg = 1;
		}
	}

	pk11_return_session(&pctx);
	(void) pk11_finalize();

	exit(error);
}
ATF_TC_BODY(isc_gost_private, tc) {
	isc_result_t result;
	unsigned char privraw[31] = {
		0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
		0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
		0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
		0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e
	};
#ifdef HAVE_OPENSSL_GOST
	unsigned char rbuf[32];
	unsigned char privasn1[70] = {
		0x30, 0x44, 0x02, 0x01, 0x00, 0x30, 0x1c, 0x06,
		0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x13, 0x30,
		0x12, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02,
		0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02,
		0x02, 0x1e, 0x01, 0x04, 0x21, 0x02, 0x1f, 0x01,
		0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
		0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
		0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
		0x1a, 0x1b, 0x1c, 0x1d, 0x1e
	};
	unsigned char abuf[71];
	unsigned char gost_dummy_key[71] = {
		0x30, 0x45, 0x02, 0x01, 0x00, 0x30, 0x1c, 0x06,
		0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x13, 0x30,
		0x12, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02,
		0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02,
		0x02, 0x1e, 0x01, 0x04, 0x22, 0x02, 0x20, 0x1b,
		0x3f, 0x94, 0xf7, 0x1a, 0x5f, 0x2f, 0xe7, 0xe5,
		0x74, 0x0b, 0x8c, 0xd4, 0xb7, 0x18, 0xdd, 0x65,
		0x68, 0x26, 0xd1, 0x54, 0xfb, 0x77, 0xba, 0x63,
		0x72, 0xd9, 0xf0, 0x63, 0x87, 0xe0, 0xd6
	};
	EVP_PKEY *pkey;
	EC_KEY *eckey;
	BIGNUM *privkey;
	const BIGNUM *privkey1;
	const unsigned char *p;
	int len;
	unsigned char *q;

	result = dns_test_begin(NULL, ISC_FALSE);
	ATF_REQUIRE(result == ISC_R_SUCCESS);

	/* raw parse */
	privkey = BN_bin2bn(privraw, (int) sizeof(privraw), NULL);
	ATF_REQUIRE(privkey != NULL);
	p = gost_dummy_key;
	pkey = NULL;
	ATF_REQUIRE(d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p,
				   (long) sizeof(gost_dummy_key)) != NULL);
	ATF_REQUIRE(pkey != NULL);
	ATF_REQUIRE(EVP_PKEY_bits(pkey) == 256);
	eckey = EVP_PKEY_get0(pkey);
	ATF_REQUIRE(eckey != NULL);
	ATF_REQUIRE(EC_KEY_set_private_key(eckey, privkey) == 1);
	BN_clear_free(privkey);

	/* asn1 tofile */
	len = i2d_PrivateKey(pkey, NULL);
	ATF_REQUIRE(len == 70);
	q = abuf;
	ATF_REQUIRE(i2d_PrivateKey(pkey, &q) == len);
	ATF_REQUIRE(memcmp(abuf, privasn1, len) == 0);
	EVP_PKEY_free(pkey);

	/* asn1 parse */
	p = privasn1;
	pkey = NULL;
	ATF_REQUIRE(d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p,
				   (long) len) != NULL);
	ATF_REQUIRE(pkey != NULL);
	eckey = EVP_PKEY_get0(pkey);
	ATF_REQUIRE(eckey != NULL);
	privkey1 = EC_KEY_get0_private_key(eckey);
	len = BN_num_bytes(privkey1);
	ATF_REQUIRE(len == 31);
	ATF_REQUIRE(BN_bn2bin(privkey1, rbuf) == len);
	ATF_REQUIRE(memcmp(rbuf, privraw, len) == 0);

	dns_test_end();
#else
	CK_BBOOL truevalue = TRUE;
	CK_BBOOL falsevalue = FALSE;
	CK_OBJECT_CLASS keyClass = CKO_PRIVATE_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_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
		{ CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
		{ CKA_VALUE, privraw, sizeof(privraw) },
		{ 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_MECHANISM mech = { CKM_GOSTR3410_WITH_GOSTR3411, NULL, 0 };
	CK_BYTE sig[64];
	CK_ULONG siglen;
	pk11_context_t pk11_ctx;

	result = dns_test_begin(NULL, ISC_FALSE);
	ATF_REQUIRE(result == ISC_R_SUCCESS);

	/* create the private key */
	memset(&pk11_ctx, 0, sizeof(pk11_ctx));
	ATF_REQUIRE(pk11_get_session(&pk11_ctx, OP_GOST, ISC_TRUE,
				     ISC_FALSE, ISC_FALSE, NULL,
				     pk11_get_best_token(OP_GOST)) ==
		    ISC_R_SUCCESS);
	pk11_ctx.object = CK_INVALID_HANDLE;
	pk11_ctx.ontoken = ISC_FALSE;
	ATF_REQUIRE(pkcs_C_CreateObject(pk11_ctx.session, keyTemplate,
					(CK_ULONG) 9, &pk11_ctx.object) ==
		    CKR_OK);
	ATF_REQUIRE(pk11_ctx.object != CK_INVALID_HANDLE);

	/* sign something */
	ATF_REQUIRE(pkcs_C_SignInit(pk11_ctx.session, &mech,
				    pk11_ctx.object) == CKR_OK);
	siglen = 0;
	ATF_REQUIRE(pkcs_C_Sign(pk11_ctx.session, sig, 64,
				NULL, &siglen) == CKR_OK);
	ATF_REQUIRE(siglen == 64);
	ATF_REQUIRE(pkcs_C_Sign(pk11_ctx.session, sig, 64,
				sig, &siglen) == CKR_OK);
	ATF_REQUIRE(siglen == 64);

	dns_test_end();
#endif
};