Exemple #1
0
int sc_pkcs15_encode_dodf_entry(sc_context_t *ctx,
			       const struct sc_pkcs15_object *obj,
			       u8 **buf, size_t *bufsize)
{
	struct sc_asn1_entry	asn1_com_data_attr[4],
				asn1_type_data_attr[2],
				asn1_data[2];
	struct sc_pkcs15_data_info *info;
	struct sc_asn1_pkcs15_object data_obj = { (struct sc_pkcs15_object *) obj,
							asn1_com_data_attr, NULL,
							asn1_type_data_attr };
	size_t label_len;

	info = (struct sc_pkcs15_data_info *) obj->data;
	label_len = strlen(info->app_label);

	sc_copy_asn1_entry(c_asn1_com_data_attr, asn1_com_data_attr);
	sc_copy_asn1_entry(c_asn1_type_data_attr, asn1_type_data_attr);
	sc_copy_asn1_entry(c_asn1_data, asn1_data);

	if (label_len)
		sc_format_asn1_entry(asn1_com_data_attr + 0, &info->app_label, &label_len, 1);

	if (sc_valid_oid(&info->app_oid))
		sc_format_asn1_entry(asn1_com_data_attr + 1, &info->app_oid, NULL, 1);

	sc_format_asn1_entry(asn1_type_data_attr + 0, &info->path, NULL, 1);
	sc_format_asn1_entry(asn1_data + 0, &data_obj, NULL, 1);

	return sc_asn1_encode(ctx, asn1_data, buf, bufsize);
}
Exemple #2
0
int
sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_pkcs15_ec_parameters *ecparams)
{
	int rv, ii;

	LOG_FUNC_CALLED(ctx);

	/* In PKCS#11 EC parameters arrives in DER encoded form */
	if (ecparams->der.value && ecparams->der.len)   {
		for (ii=0; ec_curve_infos[ii].name; ii++)   {
			struct sc_object_id id;
			unsigned char *buf = NULL;
			size_t len = 0;

			sc_format_oid(&id, ec_curve_infos[ii].oid_str);
			sc_encode_oid (ctx, &id, &buf, &len);

			if (ecparams->der.len == len && !memcmp(ecparams->der.value, buf, len))   {
				free(buf);
				break;
			}

			free(buf);
		}

		/* TODO: support of explicit EC parameters form */
		if (!ec_curve_infos[ii].name)
			LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Unsupported named curve");

		sc_log(ctx, "Found known curve '%s'", ec_curve_infos[ii].name);
		if (!ecparams->named_curve)   {
			ecparams->named_curve = strdup(ec_curve_infos[ii].name);
			if (!ecparams->named_curve)
				LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);

			sc_log(ctx, "Curve name: '%s'", ecparams->named_curve);
		}

		if (!sc_valid_oid(&ecparams->id))
			sc_format_oid(&ecparams->id, ec_curve_infos[ii].oid_str);

		ecparams->field_length = ec_curve_infos[ii].size;
		sc_log(ctx, "Curve length %i", ecparams->field_length);
	}
	else if (ecparams->named_curve)   {	/* it can be name of curve or OID in ASCII form */
		for (ii=0; ec_curve_infos[ii].name; ii++)   {
			if (!strcmp(ec_curve_infos[ii].name, ecparams->named_curve))
				break;
			if (!strcmp(ec_curve_infos[ii].oid_str, ecparams->named_curve))
				break;
		}
		if (!ec_curve_infos[ii].name)
			LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Unsupported named curve");

		rv = sc_format_oid(&ecparams->id, ec_curve_infos[ii].oid_str);
		LOG_TEST_RET(ctx, rv, "Invalid OID format");

		ecparams->field_length = ec_curve_infos[ii].size;

		if (!ecparams->der.value || !ecparams->der.len)   {
			rv = sc_encode_oid (ctx, &ecparams->id, &ecparams->der.value, &ecparams->der.len);
			LOG_TEST_RET(ctx, rv, "Cannot encode object ID");
		}
	}
	else if (sc_valid_oid(&ecparams->id))  {
		LOG_TEST_RET(ctx, SC_ERROR_NOT_IMPLEMENTED, "EC parameters has to be presented as a named curve or explicit data");
	}

	LOG_FUNC_RETURN(ctx, SC_SUCCESS);
}
Exemple #3
0
/*
 * Store a private key
 */
static int
myeid_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
		struct sc_pkcs15_object *object,
		struct sc_pkcs15_prkey *prkey) {
	struct sc_context *ctx = p15card->card->ctx;
	struct sc_card *card = p15card->card;
	struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *) object->data;
	struct sc_cardctl_myeid_gen_store_key_info args;
	struct sc_file *file = NULL;
	int r, keybits = key_info->modulus_length;

	LOG_FUNC_CALLED(ctx);

	switch (object->type) {
		case SC_PKCS15_TYPE_PRKEY_RSA:
			if (sc_card_find_rsa_alg(p15card->card, keybits) == NULL)
				LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Unsupported RSA key size");
			break;
		case SC_PKCS15_TYPE_PRKEY_EC:
			if (!sc_valid_oid(&prkey->u.ec.params.id))
                                if (sc_pkcs15_fix_ec_parameters(ctx, &prkey->u.ec.params))
                                        LOG_FUNC_RETURN(ctx, SC_ERROR_OBJECT_NOT_VALID);
			if (sc_card_find_ec_alg(p15card->card, keybits, &prkey->u.ec.params.id) == NULL)
				LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Unsupported algorithm or key size");
			if(key_info->field_length != 0)
				keybits = key_info->field_length;
			else
				key_info->field_length = keybits;
			break;
		default:
			LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Store key failed: Unsupported key type");
			break;
	}

	sc_log(ctx, "store MyEID key with ID:%s and path:%s",
			sc_pkcs15_print_id(&key_info->id), sc_print_path(&key_info->path));

	r = sc_select_file(card, &key_info->path, &file);
	LOG_TEST_RET(ctx, r, "Cannot store MyEID key: select key file failed");

	r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE);
	LOG_TEST_RET(ctx, r, "No authorisation to store MyEID private key");

	if (file)
		sc_file_free(file);

	/* Fill in data structure */
	memset(&args, 0, sizeof (args));

	args.op_type = OP_TYPE_STORE;
	if(object->type == SC_PKCS15_TYPE_PRKEY_RSA) {
		//args.key_len_bits = keybits;
		args.key_type = SC_CARDCTL_MYEID_KEY_RSA;
		args.pubexp_len = prkey->u.rsa.exponent.len;
		args.pubexp = prkey->u.rsa.exponent.data;
		args.primep_len = prkey->u.rsa.p.len;
		args.primep = prkey->u.rsa.p.data;
		args.primeq_len = prkey->u.rsa.q.len;
		args.primeq = prkey->u.rsa.q.data;

		args.dp1_len = prkey->u.rsa.dmp1.len;
		args.dp1 = prkey->u.rsa.dmp1.data;
		args.dq1_len = prkey->u.rsa.dmq1.len;
		args.dq1 = prkey->u.rsa.dmq1.data;
		args.invq_len = prkey->u.rsa.iqmp.len;
		args.invq = prkey->u.rsa.iqmp.data;

		args.key_len_bits = prkey->u.rsa.modulus.len;
		args.mod = prkey->u.rsa.modulus.data;
	}
	else {
		args.key_type = SC_CARDCTL_MYEID_KEY_EC;
		args.d = prkey->u.ec.privateD.data;
		args.d_len = prkey->u.ec.privateD.len;
		args.ecpublic_point = prkey->u.ec.ecpointQ.value;
		args.ecpublic_point_len = prkey->u.ec.ecpointQ.len;
		args.key_len_bits = prkey->u.ec.params.field_length;
	}
	/* Store RSA key  */
	r = sc_card_ctl(card, SC_CARDCTL_MYEID_GENERATE_STORE_KEY, &args);
	LOG_TEST_RET(ctx, r, "Card control 'MYEID_GENERATE_STORE_KEY' failed");

	LOG_FUNC_RETURN(ctx, r);
}
Exemple #4
0
int
sc_asn1_encode_algorithm_id(struct sc_context *ctx, u8 **buf, size_t *len,
			    const struct sc_algorithm_id *id,
			    int depth)
{
	struct sc_asn1_pkcs15_algorithm_info *alg_info;
	struct sc_algorithm_id temp_id;
	struct sc_asn1_entry asn1_alg_id[3];
	u8 *obj = NULL;
	size_t obj_len = 0;
	int r;
	u8 *tmp;

	LOG_FUNC_CALLED(ctx);
        sc_log(ctx, "type of algorithm to encode: %i", id->algorithm);
	alg_info = sc_asn1_get_algorithm_info(id);
	if (alg_info == NULL) {
		sc_log(ctx, "Cannot encode unknown algorithm %u", id->algorithm);
		LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
	}

	/* Set the oid if not yet given */
	if (!sc_valid_oid(&id->oid)) {
		temp_id = *id;
		temp_id.oid = alg_info->oid;
		id = &temp_id;
	}

        sc_log(ctx, "encode algo %s", sc_dump_oid(&(id->oid)));
	sc_copy_asn1_entry(c_asn1_alg_id, asn1_alg_id);
	sc_format_asn1_entry(asn1_alg_id + 0, (void *) &id->oid, NULL, 1);

	/* no parameters, write NULL tag */
	if (!id->params || !alg_info->encode)
		asn1_alg_id[1].flags |= SC_ASN1_PRESENT;

	r = _sc_asn1_encode(ctx, asn1_alg_id, buf, len, depth + 1);
	LOG_TEST_RET(ctx, r, "ASN.1 encode of algorithm failed");

	/* Encode any parameters */
	if (id->params && alg_info->encode) {
		r = alg_info->encode(ctx, id->params, &obj, &obj_len, depth+1);
		if (r < 0) {
			if (obj)
				free(obj);
			LOG_FUNC_RETURN(ctx, r);
		}
	}

	if (obj_len) {
		tmp = (u8 *) realloc(*buf, *len + obj_len);
		if (!tmp) {
			free(*buf);
			*buf = NULL;
			free(obj);
			LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
		}
		*buf = tmp;
		memcpy(*buf + *len, obj, obj_len);
		*len += obj_len;
		free(obj);
	}

	sc_log(ctx, "return encoded algorithm ID: %s", sc_dump_hex(*buf, *len));
	LOG_FUNC_RETURN(ctx, SC_SUCCESS);
}