Exemplo n.º 1
0
int sc_pkcs15_decode_dodf_entry(struct sc_pkcs15_card *p15card,
			       struct sc_pkcs15_object *obj,
			       const u8 ** buf, size_t *buflen)
{
        sc_context_t *ctx = p15card->card->ctx;
	struct sc_pkcs15_data_info info;
	struct sc_asn1_entry	asn1_com_data_attr[3],
				asn1_type_data_attr[2],
				asn1_data[2];
	struct sc_asn1_pkcs15_object data_obj = { obj, asn1_com_data_attr, NULL,
					     asn1_type_data_attr };
	size_t label_len = sizeof(info.app_label);
	int r;

	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);

	sc_format_asn1_entry(asn1_com_data_attr + 0, &info.app_label, &label_len, 0);
	sc_format_asn1_entry(asn1_com_data_attr + 1, &info.app_oid, NULL, 0);
	sc_format_asn1_entry(asn1_type_data_attr + 0, &info.path, NULL, 0);
	sc_format_asn1_entry(asn1_data + 0, &data_obj, NULL, 0);

	/* Fill in defaults */
	memset(&info, 0, sizeof(info));
	sc_init_oid(&info.app_oid);

	r = sc_asn1_decode(ctx, asn1_data, *buf, *buflen, buf, buflen);
	if (r == SC_ERROR_ASN1_END_OF_CONTENTS)
		return r;
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "ASN.1 decoding failed");

	if (!p15card->app || !p15card->app->ddo.aid.len)   {
		r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &info.path);
		if (r < 0)
			return r;
	}
	else   {
		info.path.aid = p15card->app->ddo.aid;
	}

	obj->type = SC_PKCS15_TYPE_DATA_OBJECT;
	obj->data = malloc(sizeof(info));
	if (obj->data == NULL)
		SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY);
	memcpy(obj->data, &info, sizeof(info));

	return SC_SUCCESS;
}
Exemplo n.º 2
0
int  _sc_card_add_ec_alg(sc_card_t *card, unsigned int key_length,
			unsigned long flags, unsigned long ext_flags,
			struct sc_object_id *curve_oid)
{
	sc_algorithm_info_t info;

	memset(&info, 0, sizeof(info));
	sc_init_oid(&info.u._ec.params.id);

	info.algorithm = SC_ALGORITHM_EC;
	info.key_length = key_length;
	info.flags = flags;

	info.u._ec.ext_flags = ext_flags;
	if (curve_oid)
		info.u._ec.params.id = *curve_oid;

	return _sc_card_add_algorithm(card, &info);
}
Exemplo n.º 3
0
/*
 * Encode a pubkey as a SPKI, useful for pkcs15-tool, and for PKCS#15 files.
 */
int
sc_pkcs15_encode_pubkey_as_spki(sc_context_t *ctx, struct sc_pkcs15_pubkey *pubkey,
		u8 **buf, size_t *len)
{
	int r;
	struct sc_asn1_entry  asn1_spki_key[2],
	asn1_spki_key_items[3];
	struct sc_pkcs15_u8 pkey;
	size_t key_len;

	LOG_FUNC_CALLED(ctx);
	pkey.value =  NULL;
	pkey.len = 0;

	sc_log(ctx, "Encoding public key with algorithm %i", pubkey->algorithm);
	if (!pubkey->alg_id)   {
		pubkey->alg_id = calloc(1, sizeof(struct sc_algorithm_id));
		if (!pubkey->alg_id)
			LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);

		sc_init_oid(&pubkey->alg_id->oid);
		pubkey->alg_id->algorithm = pubkey->algorithm;
	}

	/* make sure we have a der encoded value first */
	if (pubkey->data.value == NULL){
	    r = sc_pkcs15_encode_pubkey(ctx, pubkey, &pubkey->data.value, &pubkey->data.len);
	    LOG_TEST_RET(ctx, r, "public key encoding failed");
	}

	switch (pubkey->algorithm) {
	case SC_ALGORITHM_EC:
		/*
		 * most keys, but not EC have only one encoding.
		 * For a SPKI, the ecpoint is placed directly in the
		 * BIT STRING
		 */
		key_len = pubkey->u.ec.ecpointQ.len * 8;
		pkey.value = pubkey->u.ec.ecpointQ.value;
		pkey.len = 0; /* flag as do not delete */
		/* TODO make sure algorithm params are available*/
		/* if not can we copy them from the u.ec */
		r = 0;
		break;
	case SC_ALGORITHM_GOSTR3410:
		/* TODO is this needed?  does it cause mem leak? */
		pubkey->alg_id->params = &pubkey->u.gostr3410.params;
		r = sc_pkcs15_encode_pubkey(ctx, pubkey, &pkey.value, &pkey.len);
		key_len = pkey.len * 8;
		break;
	default:
		r = sc_pkcs15_encode_pubkey(ctx, pubkey, &pkey.value, &pkey.len);
		key_len = pkey.len * 8;
		break;
	}

	if (r == 0) {
		sc_copy_asn1_entry(c_asn1_spki_key, asn1_spki_key);
		sc_copy_asn1_entry(c_asn1_spki_key_items, asn1_spki_key_items);
		sc_format_asn1_entry(asn1_spki_key + 0, asn1_spki_key_items, NULL, 1);
		sc_format_asn1_entry(asn1_spki_key_items + 0, pubkey->alg_id, NULL, 1);
		sc_format_asn1_entry(asn1_spki_key_items + 1, pkey.value, &key_len, 1);

		r =  sc_asn1_encode(ctx, asn1_spki_key, buf, len);
	}

	if (pkey.len && pkey.value)
		free(pkey.value);

	LOG_FUNC_RETURN(ctx, r);
}