[pkg-opensc-commit] [opensc] 268/295: pkcs11-tool: add GOSTR3410 keypair generation (#997)

Eric Dorland eric at moszumanska.debian.org
Sat Jun 24 21:11:39 UTC 2017


This is an automated email from the git hooks/post-receive script.

eric pushed a commit to branch master
in repository opensc.

commit 083cec8fdae83a39a5a51157af36cfeeb88475f6
Author: konstantinpersidskiy <konstantin.persidskiy at gmail.com>
Date:   Fri Jun 9 11:30:40 2017 +0300

    pkcs11-tool: add GOSTR3410 keypair generation (#997)
    
    * pkcs11-tool: add GOSTR3410 keypair generation
    * Refactor gost3410 generation
---
 src/pkcs11/framework-pkcs15.c | 150 +++++++++++++++++++++++++++++++++---------
 src/pkcs11/mechanism.c        |   2 +-
 src/pkcs11/misc.c             |  12 ++++
 src/pkcs11/sc-pkcs11.h        |   2 +
 src/pkcs15init/pkcs15-lib.c   |  18 +++++
 src/tools/pkcs11-tool.c       |  67 ++++++++++++++++++-
 6 files changed, 217 insertions(+), 34 deletions(-)

diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c
index 8ada624..f9cb25c 100644
--- a/src/pkcs11/framework-pkcs15.c
+++ b/src/pkcs11/framework-pkcs15.c
@@ -140,19 +140,52 @@ extern struct sc_pkcs11_object_ops pkcs15_pubkey_ops;
 extern struct sc_pkcs11_object_ops pkcs15_dobj_ops;
 extern struct sc_pkcs11_object_ops pkcs15_skey_ops;
 
-#define GOST_PARAMS_OID_SIZE 9
+const CK_BYTE gostr3410_paramset_A_encoded_oid[] = { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01 };
+const unsigned int gostr3410_paramset_A_oid[] = {1, 2, 643, 2, 2, 35, 1, (unsigned int)-1};
+const CK_BYTE gostr3410_paramset_B_encoded_oid[] = { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x02 };
+const unsigned int gostr3410_paramset_B_oid[] = {1, 2, 643, 2, 2, 35, 2, (unsigned int)-1};
+const CK_BYTE gostr3410_paramset_C_encoded_oid[] = { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x03 };
+const unsigned int gostr3410_paramset_C_oid[] = {1, 2, 643, 2, 2, 35, 3, (unsigned int)-1};
+
 static const struct {
-	const CK_BYTE oid[GOST_PARAMS_OID_SIZE];
-	unsigned char param;
+	const CK_BYTE *encoded_oid;
+	const unsigned int encoded_oid_size;
+	const unsigned int *oid;
+	const unsigned int oid_size;
+	unsigned char oid_id;
 } gostr3410_param_oid [] = {
-	{ { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01 },
+	{ &gostr3410_paramset_A_encoded_oid[0],
+		sizeof(gostr3410_paramset_A_encoded_oid),
+		&gostr3410_paramset_A_oid[0],
+		sizeof(gostr3410_paramset_A_oid),
 		SC_PKCS15_PARAMSET_GOSTR3410_A },
-	{ { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x02 },
+	{ &gostr3410_paramset_B_encoded_oid[0],
+		sizeof(gostr3410_paramset_B_encoded_oid),
+		&gostr3410_paramset_B_oid[0],
+		sizeof(gostr3410_paramset_B_oid),
 		SC_PKCS15_PARAMSET_GOSTR3410_B },
-	{ { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x03 },
+	{ &gostr3410_paramset_C_encoded_oid[0],
+		sizeof(gostr3410_paramset_C_encoded_oid),
+		&gostr3410_paramset_C_oid[0],
+		sizeof(gostr3410_paramset_C_oid),
 		SC_PKCS15_PARAMSET_GOSTR3410_C }
 };
 
+const CK_BYTE gostr3411_94_cryptopro_paramset_encoded_oid[] = { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01 };
+const unsigned int gostr3411_94_cryptopro_paramset_oid[] = {1, 2, 643, 2, 2, 30, 1, (unsigned int)-1};
+
+static const struct {
+	const CK_BYTE *encoded_oid;
+	const unsigned int encoded_oid_size;
+	const unsigned int *oid;
+	const unsigned int oid_size;
+} gostr3410_hash_param_oid [] = {
+	{ &gostr3411_94_cryptopro_paramset_encoded_oid[0],
+		sizeof(gostr3411_94_cryptopro_paramset_encoded_oid),
+		&gostr3411_94_cryptopro_paramset_oid[0],
+		sizeof(gostr3411_94_cryptopro_paramset_oid)}
+};
+
 static int	__pkcs15_release_object(struct pkcs15_any_object *);
 static CK_RV	register_mechanisms(struct sc_pkcs11_card *p11card);
 static CK_RV	get_public_exponent(struct sc_pkcs15_pubkey *,
@@ -170,8 +203,8 @@ static int	unlock_card(struct pkcs15_fw_data *);
 static int	reselect_app_df(sc_pkcs15_card_t *p15card);
 
 #ifdef USE_PKCS15_INIT
-static CK_RV	set_gost_params(struct sc_pkcs15init_keyarg_gost_params *,
-			struct sc_pkcs15init_keyarg_gost_params *,
+static CK_RV	set_gost3410_params(struct sc_pkcs15init_prkeyargs *,
+			struct sc_pkcs15init_pubkeyargs *,
 			CK_ATTRIBUTE_PTR, CK_ULONG, CK_ATTRIBUTE_PTR, CK_ULONG);
 static CK_RV	pkcs15_create_slot(struct sc_pkcs11_card *p11card, struct pkcs15_fw_data *fw_data,
 			struct sc_pkcs15_object *auth, struct sc_app_info *app,
@@ -682,7 +715,10 @@ __pkcs15_create_pubkey_object(struct pkcs15_fw_data *fw_data,
 	} else if (pubkey->emulated && (fw_data->p15_card->flags & SC_PKCS15_CARD_FLAG_EMULATED)) {
 		sc_pkcs15_free_pubkey(p15_key);
 	}
-
+	if (object->pub_data) {
+		if ((object->pub_data->alg_id)&&(object->pub_data->algorithm == SC_ALGORITHM_GOSTR3410))
+			object->pub_data->alg_id->params = &((object->pub_data->u).gostr3410.params);
+	}
 	if (pubkey_object != NULL)
 		*pubkey_object = (struct pkcs15_any_object *) object;
 
@@ -1987,7 +2023,7 @@ pkcs15_create_private_key(struct sc_pkcs11_slot *slot, struct sc_profile *profil
 			rsa = &args.key.u.rsa;
 			break;
 		case CKK_GOSTR3410:
-			set_gost_params(&args.params.gost, NULL, pTemplate, ulCount, NULL, 0);
+			set_gost3410_params(&args, NULL, pTemplate, ulCount, NULL, 0);
 			args.key.algorithm = SC_ALGORITHM_GOSTR3410;
 			gost = &args.key.u.gostr3410;
 			break;
@@ -2684,39 +2720,89 @@ get_X509_usage_pubk(CK_ATTRIBUTE_PTR pTempl, CK_ULONG ulCount, unsigned long *x5
 
 
 static CK_RV
-set_gost_params(struct sc_pkcs15init_keyarg_gost_params *first_params,
-		struct sc_pkcs15init_keyarg_gost_params *second_params,
+set_gost3410_params(struct sc_pkcs15init_prkeyargs *prkey_args,
+		struct sc_pkcs15init_pubkeyargs *pubkey_args,
 		CK_ATTRIBUTE_PTR pPubTpl, CK_ULONG ulPubCnt,
 		CK_ATTRIBUTE_PTR pPrivTpl, CK_ULONG ulPrivCnt)
 {
-	CK_BYTE gost_params_oid[GOST_PARAMS_OID_SIZE];
-	size_t len, i;
+	const CK_BYTE * gost_params_encoded_oid_from_template;
+	const CK_BYTE * gost_hash_params_encoded_oid_from_template;
+	size_t len, param_index, hash_index;
 	CK_RV rv;
 
-	len = GOST_PARAMS_OID_SIZE;
+	/* If template has CKA_GOSTR3410_PARAMS attribute, set param_index to
+	 * corresponding item's index in gostr3410_param_oid[] */
 	if (pPrivTpl && ulPrivCnt)
-		rv = attr_find2(pPubTpl, ulPubCnt, pPrivTpl, ulPrivCnt, CKA_GOSTR3410_PARAMS, &gost_params_oid, &len);
+		rv = attr_find_ptr2(pPubTpl, ulPubCnt, pPrivTpl, ulPrivCnt, CKA_GOSTR3410_PARAMS, (void **)&gost_params_encoded_oid_from_template, &len);
 	else
-		rv = attr_find(pPubTpl, ulPubCnt, CKA_GOSTR3410_PARAMS, &gost_params_oid, &len);
+		rv = attr_find_ptr(pPubTpl, ulPubCnt, CKA_GOSTR3410_PARAMS, (void **)&gost_params_encoded_oid_from_template, &len);
+
 	if (rv == CKR_OK) {
 		size_t nn = sizeof(gostr3410_param_oid)/sizeof(gostr3410_param_oid[0]);
 
-		if (len != GOST_PARAMS_OID_SIZE)
+		for (param_index = 0; param_index < nn; ++param_index) {
+			if (len != gostr3410_param_oid[param_index].encoded_oid_size)
+				continue;
+			if (!memcmp(gost_params_encoded_oid_from_template, gostr3410_param_oid[param_index].encoded_oid, len))
+				break;
+		}
+
+		if (param_index == nn)
 			return CKR_ATTRIBUTE_VALUE_INVALID;
+	}
+	else if (rv == CKR_TEMPLATE_INCOMPLETE)
+		/* Default used parameters' index */
+		param_index = 0;
+	else
+		return rv;
 
-		for (i = 0; i < nn; ++i) {
-			if (!memcmp(gost_params_oid, gostr3410_param_oid[i].oid, len)) {
-				if (first_params)
-					first_params->gostr3410 = gostr3410_param_oid[i].param;
-				if (second_params)
-					second_params->gostr3410 = gostr3410_param_oid[i].param;
+	/* If template has CKA_GOSTR3411_PARAMS attribute, set hash_index to
+	 * corresponding item's index in gostr3410_hash_param_oid[] */
+	if (pPrivTpl && ulPrivCnt)
+		rv = attr_find_ptr2(pPubTpl, ulPubCnt, pPrivTpl, ulPrivCnt, CKA_GOSTR3411_PARAMS, (void **)&gost_hash_params_encoded_oid_from_template, &len);
+	else
+		rv = attr_find_ptr(pPubTpl, ulPubCnt, CKA_GOSTR3411_PARAMS, (void **)&gost_hash_params_encoded_oid_from_template, &len);
+
+	if (rv == CKR_OK) {
+		size_t nn = sizeof(gostr3410_hash_param_oid)/sizeof(gostr3410_hash_param_oid[0]);
+
+		for (hash_index = 0; hash_index < nn; ++hash_index) {
+			if (len != gostr3410_hash_param_oid[hash_index].encoded_oid_size)
+				continue;
+			if (!memcmp(gost_hash_params_encoded_oid_from_template, gostr3410_hash_param_oid[hash_index].encoded_oid, len))
 				break;
-			}
 		}
 
-		if (i == nn)
+		if (hash_index == nn)
 			return CKR_ATTRIBUTE_VALUE_INVALID;
 	}
+	else if (rv == CKR_TEMPLATE_INCOMPLETE)
+		/* Default used hash parameters' index */
+		hash_index = 0;
+	else
+		return rv;
+
+	/* Set params and hash oids in priv and pub keys' gostr3410 params
+	 * and set params oid_id in priv key */
+	if (prkey_args) {
+		(prkey_args->params).gost.gostr3410 = gostr3410_param_oid[param_index].oid_id;
+		memcpy(&(prkey_args->key).u.gostr3410.params.key,
+			gostr3410_param_oid[param_index].oid,
+			gostr3410_param_oid[param_index].oid_size);
+		memcpy(&(prkey_args->key).u.gostr3410.params.hash,
+			gostr3410_hash_param_oid[hash_index].oid,
+			gostr3410_hash_param_oid[hash_index].oid_size);
+	}
+	if (pubkey_args) {
+		(pubkey_args->params).gost.gostr3410 = gostr3410_param_oid[param_index].oid_id;
+		memcpy(&(pubkey_args->key).u.gostr3410.params.key,
+			gostr3410_param_oid[param_index].oid,
+			gostr3410_param_oid[param_index].oid_size);
+		memcpy(&(pubkey_args->key).u.gostr3410.params.hash,
+			gostr3410_hash_param_oid[hash_index].oid,
+			gostr3410_hash_param_oid[hash_index].oid_size);
+	}
+
 	return CKR_OK;
 }
 
@@ -2798,8 +2884,10 @@ pkcs15_gen_keypair(struct sc_pkcs11_slot *slot, CK_MECHANISM_PTR pMechanism,
 	if (keytype == CKK_GOSTR3410)   {
 		keygen_args.prkey_args.key.algorithm = SC_ALGORITHM_GOSTR3410;
 		pub_args.key.algorithm               = SC_ALGORITHM_GOSTR3410;
-		set_gost_params(&keygen_args.prkey_args.params.gost, &pub_args.params.gost,
+		rv = set_gost3410_params(&keygen_args.prkey_args, &pub_args,
 				pPubTpl, ulPubCnt, pPrivTpl, ulPrivCnt);
+		if (rv != CKR_OK)
+			goto kpgen_done;
 		keybits = SC_PKCS15_GOSTR3410_KEYSIZE;
 	}
 	else if (keytype == CKK_RSA)   {
@@ -4529,10 +4617,10 @@ get_gostr3410_params(const u8 *params, size_t params_len, CK_ATTRIBUTE_PTR attr)
 		return CKR_ATTRIBUTE_TYPE_INVALID;
 
 	for (i = 0; i < sizeof(gostr3410_param_oid)/sizeof(gostr3410_param_oid[0]); ++i) {
-		if (gostr3410_param_oid[i].param == ((int*)params)[0]) {
-			check_attribute_buffer(attr, sizeof(gostr3410_param_oid[i].oid));
-			memcpy(attr->pValue, gostr3410_param_oid[i].oid,
-					sizeof(gostr3410_param_oid[i].oid));
+		if (gostr3410_param_oid[i].oid_id == ((int*)params)[0]) {
+			check_attribute_buffer(attr, gostr3410_param_oid[i].encoded_oid_size);
+			memcpy(attr->pValue, gostr3410_param_oid[i].encoded_oid,
+					gostr3410_param_oid[i].encoded_oid_size);
 			return CKR_OK;
 		}
 	}
diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c
index 8b1d18f..b64d052 100644
--- a/src/pkcs11/mechanism.c
+++ b/src/pkcs11/mechanism.c
@@ -688,7 +688,7 @@ sc_pkcs11_verify_final(sc_pkcs11_operation_t *operation,
 	struct sc_pkcs11_object *key;
 	unsigned char *pubkey_value = NULL;
 	CK_KEY_TYPE key_type;
-	CK_BYTE params[9 /* GOST_PARAMS_OID_SIZE */] = { 0 };
+	CK_BYTE params[9 /* GOST_PARAMS_ENCODED_OID_SIZE */] = { 0 };
 	CK_ATTRIBUTE attr = {CKA_VALUE, NULL, 0};
 	CK_ATTRIBUTE attr_key_type = {CKA_KEY_TYPE, &key_type, sizeof(key_type)};
 	CK_ATTRIBUTE attr_key_params = {CKA_GOSTR3410_PARAMS, &params, sizeof(params)};
diff --git a/src/pkcs11/misc.c b/src/pkcs11/misc.c
index 44fab3c..3847885 100644
--- a/src/pkcs11/misc.c
+++ b/src/pkcs11/misc.c
@@ -412,6 +412,18 @@ CK_RV attr_find_ptr(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_ULONG type,
 	return CKR_OK;
 }
 
+CK_RV attr_find_ptr2(CK_ATTRIBUTE_PTR pTemp1, CK_ULONG ulCount1,
+		 CK_ATTRIBUTE_PTR pTemp2, CK_ULONG ulCount2, CK_ULONG type, void **ptr, size_t * sizep)
+{
+	CK_RV rv;
+
+	rv = attr_find_ptr(pTemp1, ulCount1, type, ptr, sizep);
+	if (rv != CKR_OK)
+		rv = attr_find_ptr(pTemp2, ulCount2, type, ptr, sizep);
+
+	return rv;
+}
+
 CK_RV attr_find_var(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_ULONG type, void *ptr, size_t * sizep)
 {
 	unsigned int n;
diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h
index 5b51234..834573b 100644
--- a/src/pkcs11/sc-pkcs11.h
+++ b/src/pkcs11/sc-pkcs11.h
@@ -391,6 +391,8 @@ CK_RV attr_find(CK_ATTRIBUTE_PTR, CK_ULONG, CK_ULONG, void *, size_t *);
 CK_RV attr_find2(CK_ATTRIBUTE_PTR, CK_ULONG, CK_ATTRIBUTE_PTR, CK_ULONG,
 		CK_ULONG, void *, size_t *);
 CK_RV attr_find_ptr(CK_ATTRIBUTE_PTR, CK_ULONG, CK_ULONG, void **, size_t *);
+CK_RV attr_find_ptr2(CK_ATTRIBUTE_PTR pTemp1, CK_ULONG ulCount1,
+		CK_ATTRIBUTE_PTR pTemp2, CK_ULONG ulCount2, CK_ULONG type, void **ptr, size_t * sizep);
 CK_RV attr_find_and_allocate_ptr(CK_ATTRIBUTE_PTR, CK_ULONG, CK_ULONG, void **, size_t *);
 CK_RV attr_find_var(CK_ATTRIBUTE_PTR, CK_ULONG, CK_ULONG, void *, size_t *);
 CK_RV attr_extract(CK_ATTRIBUTE_PTR, void *, size_t *);
diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c
index a69e43b..e001e72 100644
--- a/src/pkcs15init/pkcs15-lib.c
+++ b/src/pkcs15init/pkcs15-lib.c
@@ -1316,6 +1316,22 @@ _pkcd15init_set_aux_md_data(struct sc_pkcs15_card *p15card, struct sc_auxiliary_
 }
 
 /*
+ * Copy gost3410 parameters (e.g. from prkey to pubkey)
+ */
+static int
+sc_copy_gost_params(struct sc_pkcs15_gost_parameters *dst, struct sc_pkcs15_gost_parameters *src)
+{
+	if (!dst || !src)
+		return SC_ERROR_INVALID_ARGUMENTS;
+
+	memcpy((dst->key).value, (src->key).value, sizeof((src->key).value));
+	memcpy((dst->hash).value, (src->hash).value, sizeof((src->hash).value));
+	memcpy((dst->cipher).value, (src->cipher).value, sizeof((src->cipher).value));
+
+	return SC_SUCCESS;
+}
+
+/*
  * Generate a new private key
  */
 int
@@ -1375,6 +1391,8 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr
 
 	if (keygen_args->prkey_args.key.algorithm == SC_ALGORITHM_GOSTR3410)   {
 		pubkey_args.params.gost = keygen_args->prkey_args.params.gost;
+		r = sc_copy_gost_params(&(pubkey_args.key.u.gostr3410.params), &(keygen_args->prkey_args.key.u.gostr3410.params));
+		LOG_TEST_RET(ctx, r, "Cannot allocate GOST parameters");
 	}
 	else if (keygen_args->prkey_args.key.algorithm == SC_ALGORITHM_EC)   {
 		pubkey_args.key.u.ec.params = keygen_args->prkey_args.key.u.ec.params;
diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c
index 5037382..5311db4 100644
--- a/src/tools/pkcs11-tool.c
+++ b/src/tools/pkcs11-tool.c
@@ -239,7 +239,7 @@ static const char *option_help[] = {
 	"Unlock User PIN (without '--login' unlock in logged in session; otherwise '--login-type' has to be 'context-specific')",
 	"Key pair generation",
 	"Key generation",
-	"Specify the type and length of the key to create, for example rsa:1024 or EC:prime256v1",
+	"Specify the type and length of the key to create, for example rsa:1024 or EC:prime256v1 or GOSTR3410:A",
 	"Specify 'sign' key usage flag (sets SIGN in privkey, sets VERIFY in pubkey)",
 	"Specify 'decrypt' key usage flag (RSA only, set DECRYPT privkey, ENCRYPT in pubkey)",
 	"Specify 'derive' key usage flag (EC only)",
@@ -1825,11 +1825,74 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session,
 			FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_EC_PARAMS, ecparams, ecparams_size);
 			n_pubkey_attr++;
 		}
+		else if (strncmp(type, "GOSTR3410:", strlen("GOSTR3410:")) == 0 || strncmp(type, "gostr3410:", strlen("gostr3410:")) == 0) {
+			CK_BYTE key_paramset_encoded_oid[9];
+			CK_BYTE hash_paramset_encoded_oid[9];
+			const CK_BYTE GOST_PARAMSET_A_OID[] = {0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01};
+			const CK_BYTE GOST_PARAMSET_B_OID[] = {0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x02};
+			const CK_BYTE GOST_PARAMSET_C_OID[] = {0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x03};
+			const CK_BYTE GOST_HASH_PARAMSET_OID[] = {0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01};
+			unsigned long int  gost_key_type = CKK_GOSTR3410;
+			CK_MECHANISM_TYPE mtypes[] = {CKM_GOSTR3410_KEY_PAIR_GEN};
+			size_t mtypes_num = sizeof(mtypes)/sizeof(mtypes[0]);
+			const char *p_param_set = type + strlen("GOSTR3410:");
+
+			if (!opt_mechanism_used) {
+				if (!find_mechanism(slot, CKF_GENERATE_KEY_PAIR, mtypes, mtypes_num, &opt_mechanism))
+					util_fatal("Generate GOSTR3410 mechanism not supported");
+			}
+
+			if (p_param_set == NULL)
+				util_fatal("Unknown key type %s", type);
+
+			if (!strcmp("A", p_param_set)) {
+				memcpy(key_paramset_encoded_oid, GOST_PARAMSET_A_OID, sizeof(GOST_PARAMSET_A_OID));
+				memcpy(hash_paramset_encoded_oid, GOST_HASH_PARAMSET_OID, sizeof(GOST_HASH_PARAMSET_OID));
+			}
+			else if (!strcmp("B", p_param_set)) {
+				memcpy(key_paramset_encoded_oid, GOST_PARAMSET_B_OID, sizeof(GOST_PARAMSET_B_OID));
+				memcpy(hash_paramset_encoded_oid, GOST_HASH_PARAMSET_OID, sizeof(GOST_HASH_PARAMSET_OID));
+			}
+			else if (!strcmp("C", p_param_set)) {
+				memcpy(key_paramset_encoded_oid, GOST_PARAMSET_C_OID, sizeof(GOST_PARAMSET_C_OID));
+				memcpy(hash_paramset_encoded_oid, GOST_HASH_PARAMSET_OID, sizeof(GOST_HASH_PARAMSET_OID));
+			}
+			else
+				util_fatal("Unknown key type %s, valid key types for mechanism GOSTR3410 are GOSTR3410:A, GOSTR3410:B, GOSTR3410:C", type);
+
+			FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_GOSTR3410_PARAMS, key_paramset_encoded_oid, sizeof(key_paramset_encoded_oid));
+			n_pubkey_attr++;
+			FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_GOSTR3410_PARAMS, key_paramset_encoded_oid, sizeof(key_paramset_encoded_oid));
+			n_privkey_attr++;
+
+			FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_GOSTR3411_PARAMS, hash_paramset_encoded_oid, sizeof(hash_paramset_encoded_oid));
+			n_pubkey_attr++;
+			FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_GOSTR3411_PARAMS, hash_paramset_encoded_oid, sizeof(hash_paramset_encoded_oid));
+			n_privkey_attr++;
+
+			FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_KEY_TYPE, &gost_key_type, sizeof(gost_key_type));
+			n_pubkey_attr++;
+			FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_KEY_TYPE, &gost_key_type, sizeof(gost_key_type));
+			n_privkey_attr++;
+
+			if (opt_key_usage_default || opt_key_usage_sign) {
+				FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_VERIFY, &_true, sizeof(_true));
+				n_pubkey_attr++;
+				FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_SIGN, &_true, sizeof(_true));
+				n_privkey_attr++;
+			}
+
+			/* do not set 'derive' attribute unless it is specified directly */
+			if (opt_key_usage_derive) {
+				FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_DERIVE, &_true, sizeof(_true));
+				n_privkey_attr++;
+			}
+		}
 		else {
 			util_fatal("Unknown key type %s", type);
 		}
 
-        mechanism.mechanism = opt_mechanism;
+		mechanism.mechanism = opt_mechanism;
 	}
 
 	if (opt_object_label != NULL) {

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-opensc/opensc.git



More information about the pkg-opensc-commit mailing list