/** * 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; }
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); }