示例#1
0
/**
 * Use PUT DATA command to write to Data Object.
 **/
static int do_put_data(int argc, char **argv)
{
	unsigned int tag;
	u8 buf[8192];
	size_t buflen = sizeof(buf);
	int r;

	if (argc != 2)
		return usage(do_put_data);

	/* Extract DO's tag */
	tag = strtoul(argv[0], NULL, 16);

	/* Extract the new content */
	/* buflen is the max length of reception buffer */
	r = parse_string_or_hexdata(argv[1], buf, &buflen);
	if (r < 0) {
		printf("unable to parse data\n");
		return -1;
	}

	/* Call OpenSC to do put data */
	r = sc_put_data(card, tag, buf, buflen);
	if (r < 0) {
		printf("Cannot put data to %04X; return %i\n", tag, r);
		return -1;
	}

	printf("Total of %d bytes written.\n", r);

	return 0;
}
示例#2
0
static int openpgp_store_data(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
                              struct sc_pkcs15_object *obj, struct sc_pkcs15_der *content,
                              struct sc_path *path)
{
	sc_card_t *card = p15card->card;
	sc_context_t *ctx = card->ctx;
	sc_file_t *file;
	sc_pkcs15_cert_info_t *cinfo;
	sc_pkcs15_id_t *cid;
	sc_pkcs15_data_info_t *dinfo;
	u8 buf[254];
	int r;

	LOG_FUNC_CALLED(card->ctx);

	switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) {
	case SC_PKCS15_TYPE_PRKEY:
	case SC_PKCS15_TYPE_PUBKEY:
		/* For these two type, store_data just don't need to do anything.
		 * All have been done already before this function is called */
		r = SC_SUCCESS;
		break;

	case SC_PKCS15_TYPE_CERT:
		cinfo = (sc_pkcs15_cert_info_t *) obj->data;
		cid = &(cinfo->id);

		if (cid->len != 1) {
			sc_log(card->ctx, "ID=%s is not valid.", sc_dump_hex(cid->value, cid->len));
			LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
		}

		/* OpenPGP card v.2 contains only 1 certificate */
		if (cid->value[0] != 3) {
			sc_log(card->ctx,
			       "This version does not support certificate ID = %d (only ID=3 is supported).",
			       cid->value[0]);
			LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
		}
		/* Just update the certificate DO */
		sc_format_path("7F21", path);
		r = sc_select_file(card, path, &file);
		LOG_TEST_RET(card->ctx, r, "Cannot select cert file");
		r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE);
		sc_log(card->ctx, "Data to write is %d long", content->len);
		if (r >= 0 && content->len)
			r = sc_put_data(p15card->card, 0x7F21, (const unsigned char *) content->value, content->len);
		break;

	case SC_PKCS15_TYPE_DATA_OBJECT:
		dinfo = (sc_pkcs15_data_info_t *) obj->data;
		/* dinfo->app_label contains filename */
		sc_log(ctx, "===== App label %s", dinfo->app_label);
		/* Currently, we only support DO 0101. The reason is that when initializing this
		 * pkcs15 emulation, PIN authentication is not applied and we can expose only this DO,
		 * which is "read always".
		 * If we support other DOs, they will not be exposed, and not helpful to user.
		 * I haven't found a way to refresh the list of exposed DOs after verifying PIN yet.
		 * http://sourceforge.net/mailarchive/message.php?msg_id=30646373
		 **/
		sc_log(ctx, "About to write to DO 0101");
		sc_format_path("0101", path);
		r = sc_select_file(card, path, &file);
		LOG_TEST_RET(card->ctx, r, "Cannot select private DO");
		r = sc_read_binary(card, 0, buf, sizeof(buf), 0);
		if (r < 0) {
			sc_log(ctx, "Cannot read DO 0101");
			break;
		}
		if (r > 0) {
			sc_log(ctx, "DO 0101 is full.");
			r = SC_ERROR_TOO_MANY_OBJECTS;
			break;
		}
		r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE);
		if (r >= 0 && content->len) {
			r = sc_update_binary(p15card->card, 0,
			                     (const unsigned char *) content->value,
			                     content->len, 0);
		}
		break;

	default:
		r = SC_ERROR_NOT_IMPLEMENTED;
	}

	LOG_FUNC_RETURN(card->ctx, r);
}