1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

scd:p15: Skip deleted records.

* scd/app-p15.c (select_and_read_record): Special case deleted
records.  Support 3 byte TLVs.
(read_ef_prkdf): Skip deleted records.
(read_ef_pukdf): Ditto.
(read_ef_cdf): Ditto.
(read_ef_aodf): Ditto.
--

This fixes a problem with some CardOS 5 applications.
This commit is contained in:
Werner Koch 2022-12-07 10:16:50 +01:00
parent 11d3114e1a
commit e778c9ce89
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B

View File

@ -744,7 +744,15 @@ select_and_read_record (app_t app, unsigned short efid, int recno,
/* On CardOS with a Linear TLV file structure the records starts /* On CardOS with a Linear TLV file structure the records starts
* with some tag (often the record number) followed by the length * with some tag (often the record number) followed by the length
* byte for this record. Detect and remove this prefix. */ * byte for this record. Detect and remove this prefix. */
if (*buflen > 2 && (*buffer)[0] != 0x30 && (*buffer)[1] == *buflen - 2) if (*buflen == 2 && !(*buffer)[0] && !(*buffer)[1])
; /* deleted record. */
else if (*buflen > 3 && (*buffer)[0] == 0xff
&& buf16_to_uint ((*buffer)+1) == *buflen - 3)
{
memmove (*buffer, *buffer + 3, *buflen - 3);
*buflen = *buflen - 3;
}
else if (*buflen > 2 && (*buffer)[0] != 0x30 && (*buffer)[1] == *buflen - 2)
{ {
memmove (*buffer, *buffer + 2, *buflen - 2); memmove (*buffer, *buffer + 2, *buflen - 2);
*buflen = *buflen - 2; *buflen = *buflen - 2;
@ -1771,6 +1779,9 @@ read_ef_prkdf (app_t app, unsigned short fid, prkdf_object_t *result)
starting with 0x00 or 0xff as these values are commonly used to starting with 0x00 or 0xff as these values are commonly used to
pad data blocks and are no valid ASN.1 encoding. Note the pad data blocks and are no valid ASN.1 encoding. Note the
special handling for record mode at the end of the loop. */ special handling for record mode at the end of the loop. */
if (record_mode && buflen == 2 && !buffer[0] && !buffer[1])
goto next_record; /* Deleted record - continue with next */
while (n && *p && *p != 0xff) while (n && *p && *p != 0xff)
{ {
const unsigned char *pp; const unsigned char *pp;
@ -2026,6 +2037,8 @@ read_ef_prkdf (app_t app, unsigned short fid, prkdf_object_t *result)
err = 0; err = 0;
goto leave; goto leave;
} }
if (buflen == 2 && !buffer[0] && !buffer[1])
goto next_record; /* Deleted record - continue with next */
p = buffer; p = buffer;
n = buflen; n = buflen;
} }
@ -2075,6 +2088,9 @@ read_ef_pukdf (app_t app, unsigned short fid, pukdf_object_t *result)
* starting with 0x00 or 0xff as these values are commonly used to * starting with 0x00 or 0xff as these values are commonly used to
* pad data blocks and are no valid ASN.1 encoding. Note the * pad data blocks and are no valid ASN.1 encoding. Note the
* special handling for record mode at the end of the loop. */ * special handling for record mode at the end of the loop. */
if (record_mode && buflen == 2 && !buffer[0] && !buffer[1])
goto next_record; /* Deleted record - continue with next */
while (n && *p && *p != 0xff) while (n && *p && *p != 0xff)
{ {
const unsigned char *pp; const unsigned char *pp;
@ -2352,6 +2368,8 @@ read_ef_pukdf (app_t app, unsigned short fid, pukdf_object_t *result)
err = 0; err = 0;
goto leave; goto leave;
} }
if (buflen == 2 && !buffer[0] && !buffer[1])
goto next_record; /* Deleted record - continue with next */
p = buffer; p = buffer;
n = buflen; n = buflen;
} }
@ -2402,6 +2420,9 @@ read_ef_cdf (app_t app, unsigned short fid, int cdftype, cdf_object_t *result)
starting with 0x00 or 0xff as these values are commonly used to starting with 0x00 or 0xff as these values are commonly used to
pad data blocks and are no valid ASN.1 encoding. Note the pad data blocks and are no valid ASN.1 encoding. Note the
special handling for record mode at the end of the loop. */ special handling for record mode at the end of the loop. */
if (record_mode && buflen == 2 && !buffer[0] && !buffer[1])
goto next_record; /* Deleted record - continue with next */
while (n && *p && *p != 0xff) while (n && *p && *p != 0xff)
{ {
const unsigned char *pp; const unsigned char *pp;
@ -2623,8 +2644,8 @@ read_ef_cdf (app_t app, unsigned short fid, int cdftype, cdf_object_t *result)
err = 0; err = 0;
next_record: next_record:
xfree (authid); xfree (authid); authid = NULL;
xfree (label); xfree (label); label = NULL;
/* If the card uses a record oriented file structure, read the /* If the card uses a record oriented file structure, read the
* next record. Otherwise we keep on parsing the current buffer. */ * next record. Otherwise we keep on parsing the current buffer. */
recno++; recno++;
@ -2633,11 +2654,14 @@ read_ef_cdf (app_t app, unsigned short fid, int cdftype, cdf_object_t *result)
xfree (buffer); buffer = NULL; xfree (buffer); buffer = NULL;
err = select_and_read_record (app, 0, recno, "CDF", err = select_and_read_record (app, 0, recno, "CDF",
&buffer, &buflen, NULL); &buffer, &buflen, NULL);
if (err) { if (err)
{
if (gpg_err_code (err) == GPG_ERR_NOT_FOUND) if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
err = 0; err = 0;
goto leave; goto leave;
} }
if (buflen == 2 && !buffer[0] && !buffer[1])
goto next_record; /* Deleted record - continue with next */
p = buffer; p = buffer;
n = buflen; n = buflen;
} }
@ -2726,6 +2750,9 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result)
starting with 0x00 or 0xff as these values are commonly used to starting with 0x00 or 0xff as these values are commonly used to
pad data blocks and are no valid ASN.1 encoding. Note the pad data blocks and are no valid ASN.1 encoding. Note the
special handling for record mode at the end of the loop. */ special handling for record mode at the end of the loop. */
if (record_mode && buflen == 2 && !buffer[0] && !buffer[1])
goto next_record; /* Deleted record - continue with next */
while (n && *p && *p != 0xff) while (n && *p && *p != 0xff)
{ {
const unsigned char *pp; const unsigned char *pp;
@ -3295,6 +3322,8 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result)
err = 0; err = 0;
goto leave; goto leave;
} }
if (buflen == 2 && !buffer[0] && !buffer[1])
goto next_record; /* Deleted record - continue with next */
p = buffer; p = buffer;
n = buflen; n = buflen;
} }