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)
|
pgp_parse_hist_bytes(sc_card_t *card, u8 *ctlv, size_t ctlv_len)
|
||||||
{
|
{
|
||||||
struct pgp_priv_data *priv = DRVDATA(card);
|
struct pgp_priv_data *priv = DRVDATA(card);
|
||||||
size_t offs;
|
const u8 *ptr;
|
||||||
|
|
||||||
for (offs = 0; offs < ctlv_len; offs++) {
|
/* IS07816-4 hist bytes: 3rd function table */
|
||||||
switch (ctlv[offs]) {
|
if ((ptr = sc_compacttlv_find_tag(ctlv, ctlv_len, 0x73, NULL)) != NULL) {
|
||||||
case 0x73: /* IS07816-4 hist bytes 3rd function table */
|
/* bit 0x40 in byte 3 of TL 0x73 means "extended Le/Lc" */
|
||||||
if (offs+3 < ctlv_len) {
|
if (ptr[2] & 0x40) {
|
||||||
/* bit 0x40 in byte 3 of TL 0x73 means "extended Le/Lc" */
|
card->caps |= SC_CARD_CAP_APDU_EXT;
|
||||||
if (ctlv[offs+3] & 0x40) {
|
priv->ext_caps |= EXT_CAP_APDU_EXT;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
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);
|
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 --
|
* Used to initialize the @c sc_remote_data structure --
|
||||||
* reset the header of the 'remote APDUs' list, set the handlers
|
* 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;
|
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 ************************/
|
/**************************** mutex functions ************************/
|
||||||
|
|
||||||
int sc_mutex_create(const sc_context_t *ctx, void **mutex)
|
int sc_mutex_create(const sc_context_t *ctx, void **mutex)
|
||||||
|
|
Loading…
Reference in New Issue