OpenPGP: implement pgp_find_blob()
Replace the "one-trick-pony" pgp_do_iswritable() with a more generic function returning the blob matching the passed tag. This way we can get rid of the one-line function pgp_blob_iswritable() too. comparisons like these can be done in the caller.
This commit is contained in:
parent
f5dc252aa9
commit
9e04ae46bb
|
@ -829,6 +829,27 @@ pgp_seek_blob(sc_card_t *card, struct blob *root, unsigned int id,
|
||||||
return SC_ERROR_FILE_NOT_FOUND;
|
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
|
* Strip out the parts of PKCS15 file layout in the path. Get the reduced version
|
||||||
* which is understood by the OpenPGP card driver.
|
* 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);
|
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 */
|
/* ABI: PUT DATA */
|
||||||
static int
|
static int
|
||||||
pgp_put_data(sc_card_t *card, unsigned int tag, const u8 *buf, size_t buf_len)
|
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);
|
LOG_FUNC_CALLED(card->ctx);
|
||||||
|
|
||||||
/* Check if the tag is writable */
|
/* 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);
|
sc_log(card->ctx, "The %04X DO is not writable.", tag);
|
||||||
return SC_ERROR_NOT_ALLOWED;
|
return SC_ERROR_NOT_ALLOWED;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue