diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 0ce2b46d..a9bebc43 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -829,6 +829,27 @@ pgp_seek_blob(sc_card_t *card, struct blob *root, unsigned int id, return SC_ERROR_FILE_NOT_FOUND; } +/* internal: find a blob by tag - pgp_seek_blob with optimizations */ +static struct blob * +pgp_find_blob(sc_card_t *card, unsigned int tag) +{ + struct pgp_priv_data *priv = DRVDATA(card); + struct blob *blob = NULL; + int r; + + /* Check if current selected blob is which we want to test*/ + if (priv->current->id == tag) { + return priv->current; + } + /* Look for the blob representing the DO */ + r = pgp_seek_blob(card, priv->mf, tag, &blob); + if (r < 0) { + sc_log(card->ctx, "Failed to seek the blob representing the tag %04X. Error %d.", tag, r); + return NULL; + } + return blob; +} + /** * Strip out the parts of PKCS15 file layout in the path. Get the reduced version * which is understood by the OpenPGP card driver. @@ -1065,37 +1086,6 @@ pgp_get_data(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len) LOG_FUNC_RETURN(card->ctx, apdu.resplen); } -/* Internal: Check if a blob is writable */ -static u8 -pgp_blob_iswritable(sc_card_t *card, struct blob *tested_blob) -{ - return ((tested_blob->info->access & WRITE_MASK) != WRITE_NEVER); -} - -/** - * Internal: Check if a DO is writable - * @param[out] ref_blob Pointer to the blob corresponding to the DO. - **/ -static u8 -pgp_do_iswritable(sc_card_t *card, unsigned int tag, struct blob **ref_blob) -{ - struct pgp_priv_data *priv = DRVDATA(card); - int r; - - /* Check if current selected blob is which we want to test*/ - if (priv->current->id == tag) { - *ref_blob = priv->current; - return pgp_blob_iswritable(card, priv->current); - } - /* Look for the blob representing the DO */ - r = pgp_seek_blob(card, priv->mf, tag, ref_blob); - if (r < 0) { - sc_log(card->ctx, "Failed to seek the blob representing the tag %04X. Error %d.", tag, r); - return 0; - } - return pgp_blob_iswritable(card, *ref_blob); -} - /* ABI: PUT DATA */ static int pgp_put_data(sc_card_t *card, unsigned int tag, const u8 *buf, size_t buf_len) @@ -1111,7 +1101,8 @@ pgp_put_data(sc_card_t *card, unsigned int tag, const u8 *buf, size_t buf_len) LOG_FUNC_CALLED(card->ctx); /* Check if the tag is writable */ - if (!pgp_do_iswritable(card, tag, &affected_blob)) { + affected_blob = pgp_find_blob(card, tag); + if (affected_blob == NULL || (affected_blob->info->access & WRITE_MASK) == WRITE_NEVER) { sc_log(card->ctx, "The %04X DO is not writable.", tag); return SC_ERROR_NOT_ALLOWED; }