diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 7f74ab4a..1f0673d5 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -1406,6 +1406,38 @@ static int pgp_delete_file(sc_card_t *card, const sc_path_t *path) return r; } +/* ABI: Update binary */ +static int pgp_update_binary(sc_card_t *card, unsigned int idx, + const u8 *buf, size_t count, unsigned long flags) +{ + struct pgp_priv_data *priv = DRVDATA(card); + struct blob *affected_blob = priv->current; + u8 *alldata; + size_t allength; + int r; + + /* We will use PUT DATA to write to DO. + * This command does not support index, so we will write the overall data, + * in which the part before idx is get from old content of DO */ + allength = idx + count; + alldata = malloc(allength); + if (alldata == NULL) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + + memset(alldata, 0, allength); + /* Copy the part before idx */ + memcpy(alldata, affected_blob->data, MIN(idx, affected_blob->len)); + /* Copy data need to be written */ + memcpy(alldata, buf, count); + + r = pgp_put_data(card, affected_blob->id, alldata, allength); + if (r < 0) { + sc_log(card->ctx, "Failed to update binary. %s", sc_strerror(r)); + } + free(alldata); + return r; +} + /* ABI: driver binding stuff */ static struct sc_card_driver * sc_get_driver(void) @@ -1430,6 +1462,7 @@ sc_get_driver(void) pgp_ops.decipher = pgp_decipher; pgp_ops.card_ctl = pgp_card_ctl; pgp_ops.delete_file = pgp_delete_file; + pgp_ops.update_binary = pgp_update_binary; return &pgp_drv; }