compact TLV - add generic sc_compacttlv_find_tag() function (#1374)
* new function sc_compacttlv_find_tag() Add function sc_compacttlv_find_tag() to search for a tag in a compact-TLV structure. * OpenPGP: use sc_compacttlv_find_tag() While doing so, fix a typo affection OpenPGP v3.x cards
This commit is contained in:
parent
6dfeb9959f
commit
266b811e55
|
@ -507,32 +507,25 @@ static void
|
|||
pgp_parse_hist_bytes(sc_card_t *card, u8 *ctlv, size_t ctlv_len)
|
||||
{
|
||||
struct pgp_priv_data *priv = DRVDATA(card);
|
||||
size_t offs;
|
||||
const u8 *ptr;
|
||||
|
||||
for (offs = 0; offs < ctlv_len; offs++) {
|
||||
switch (ctlv[offs]) {
|
||||
case 0x73: /* IS07816-4 hist bytes 3rd function table */
|
||||
if (offs+3 < ctlv_len) {
|
||||
/* bit 0x40 in byte 3 of TL 0x73 means "extended Le/Lc" */
|
||||
if (ctlv[offs+3] & 0x40) {
|
||||
card->caps |= SC_CARD_CAP_APDU_EXT;
|
||||
priv->ext_caps |= EXT_CAP_APDU_EXT;
|
||||
}
|
||||
/* bit 0x80 in byte 3 of TL 0x73 means "Command chaining" */
|
||||
if ((ctlv[offs+3] & 0x40) &&
|
||||
(priv->bcd_version >= OPENPGP_CARD_3_0)) {
|
||||
priv->ext_caps |= EXT_CAP_CHAINING;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x31:
|
||||
if ((offs + 1 < ctlv_len) &&
|
||||
(priv->bcd_version >= OPENPGP_CARD_3_0)) {
|
||||
// ToDo ...
|
||||
}
|
||||
break;
|
||||
/* IS07816-4 hist bytes: 3rd function table */
|
||||
if ((ptr = sc_compacttlv_find_tag(ctlv, ctlv_len, 0x73, NULL)) != NULL) {
|
||||
/* bit 0x40 in byte 3 of TL 0x73 means "extended Le/Lc" */
|
||||
if (ptr[2] & 0x40) {
|
||||
card->caps |= SC_CARD_CAP_APDU_EXT;
|
||||
priv->ext_caps |= EXT_CAP_APDU_EXT;
|
||||
}
|
||||
offs += ctlv[offs] & 0x0F;
|
||||
/* bit 0x80 in byte 3 of TL 0x73 means "Command chaining" */
|
||||
if ((ptr[2] & 0x80) &&
|
||||
(priv->bcd_version >= OPENPGP_CARD_3_0)) {
|
||||
priv->ext_caps |= EXT_CAP_CHAINING;
|
||||
}
|
||||
}
|
||||
|
||||
if ((priv->bcd_version >= OPENPGP_CARD_3_0) &&
|
||||
((ptr = sc_compacttlv_find_tag(ctlv, ctlv_len, 0x31, NULL)) != NULL)) {
|
||||
// ToDo ...
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1357,6 +1357,18 @@ scconf_block *sc_match_atr_block(sc_context_t *ctx, struct sc_card_driver *drive
|
|||
*/
|
||||
unsigned sc_crc32(const unsigned char *value, size_t len);
|
||||
|
||||
/**
|
||||
* Find a given tag in a compact TLV structure
|
||||
* @param[in] buf input buffer holding the compact TLV structure
|
||||
* @param[in] len length of the input buffer @buf in bytes
|
||||
* @param[in] tag compact tag to search for - high nibble: plain tag, low nibble: length.
|
||||
* If length is 0, only the plain tag is used for searching,
|
||||
* in any other case, the length must also match.
|
||||
* @param[out] outlen pointer where the size of the buffer returned is to be stored
|
||||
* @return pointer to the tag value found within @buf, or NULL if not found/on error
|
||||
*/
|
||||
const u8 *sc_compacttlv_find_tag(const u8 *buf, size_t len, u8 tag, size_t *outlen);
|
||||
|
||||
/**
|
||||
* Used to initialize the @c sc_remote_data structure --
|
||||
* reset the header of the 'remote APDUs' list, set the handlers
|
||||
|
|
|
@ -948,6 +948,26 @@ unsigned sc_crc32(const unsigned char *value, size_t len)
|
|||
return crc%0xffff;
|
||||
}
|
||||
|
||||
const u8 *sc_compacttlv_find_tag(const u8 *buf, size_t len, u8 tag, size_t *outlen)
|
||||
{
|
||||
if (buf != NULL) {
|
||||
size_t idx;
|
||||
u8 plain_tag = tag & 0xF0;
|
||||
size_t expected_len = tag & 0x0F;
|
||||
|
||||
for (idx = 0; idx < len; idx++) {
|
||||
if ((buf[idx] & 0xF0) == plain_tag && idx + expected_len < len &&
|
||||
(expected_len == 0 || expected_len == (buf[idx] & 0x0F))) {
|
||||
if (outlen != NULL)
|
||||
*outlen = buf[idx] & 0x0F;
|
||||
return buf + (idx + 1);
|
||||
}
|
||||
idx += (buf[idx] & 0x0F);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**************************** mutex functions ************************/
|
||||
|
||||
int sc_mutex_create(const sc_context_t *ctx, void **mutex)
|
||||
|
|
Loading…
Reference in New Issue