fixed handling SC_ASN1_TAG_EOC from sc_asn1_read_tag

We can't check for `tag == SC_ASN1_TAG_EOC` directly, because this
would also be true for a tag of 0x80 (with `class ==
SC_ASN1_CLASS_CONSTRUCTED`). So what we do is we check for the output
buffer to be NULL!

fixes https://github.com/OpenSC/OpenSC/issues/1273
This commit is contained in:
Frank Morgner 2018-03-19 15:25:14 +01:00
parent fe0d6f9187
commit 45ad44e311
10 changed files with 43 additions and 26 deletions

View File

@ -364,7 +364,7 @@ static void print_tags_recursive(const u8 * buf0, const u8 * buf,
size_t len;
r = sc_asn1_read_tag(&tagp, bytesleft, &cla, &tag, &len);
if (r != SC_SUCCESS) {
if (r != SC_SUCCESS || tagp == NULL) {
printf("Error in decoding.\n");
return;
}
@ -475,8 +475,10 @@ const u8 *sc_asn1_find_tag(sc_context_t *ctx, const u8 * buf,
buf = p;
/* read a tag */
if (sc_asn1_read_tag(&p, left, &cla, &tag, &taglen) != SC_SUCCESS)
if (sc_asn1_read_tag(&p, left, &cla, &tag, &taglen) != SC_SUCCESS
|| p == NULL)
return NULL;
left -= (p - buf);
/* we need to shift the class byte to the leftmost
* byte of the tag */
@ -506,7 +508,8 @@ const u8 *sc_asn1_skip_tag(sc_context_t *ctx, const u8 ** buf, size_t *buflen,
size_t len = *buflen, taglen;
unsigned int cla = 0, tag;
if (sc_asn1_read_tag((const u8 **) &p, len, &cla, &tag, &taglen) != SC_SUCCESS)
if (sc_asn1_read_tag((const u8 **) &p, len, &cla, &tag, &taglen) != SC_SUCCESS
|| p == NULL)
return NULL;
switch (cla & 0xC0) {
case SC_ASN1_TAG_UNIVERSAL:

View File

@ -533,17 +533,19 @@ static int gids_get_pin_status(sc_card_t *card, int pinreference, int *tries_lef
r = gids_get_DO(card, GIDS_APPLET_EFID, dataObjectIdentifier, buffer, &buffersize);
SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "unable to update the masterfile");
p = sc_asn1_find_tag(card->ctx, buffer, sizeof(buffer), GIDS_TRY_COUNTER_OLD_TAG, &datasize);
buffersize = buffersize > sizeof(buffer) ? sizeof(buffer) : buffersize;
p = sc_asn1_find_tag(card->ctx, buffer, buffersize, GIDS_TRY_COUNTER_OLD_TAG, &datasize);
if (p && datasize == 1) {
if (tries_left)
*tries_left = p[0];
}
p = sc_asn1_find_tag(card->ctx, buffer, sizeof(buffer), GIDS_TRY_COUNTER_TAG, &datasize);
p = sc_asn1_find_tag(card->ctx, buffer, buffersize, GIDS_TRY_COUNTER_TAG, &datasize);
if (p && datasize == 1) {
if (tries_left)
*tries_left = p[0];
}
p = sc_asn1_find_tag(card->ctx, buffer, sizeof(buffer), GIDS_TRY_LIMIT_TAG, &datasize);
p = sc_asn1_find_tag(card->ctx, buffer, buffersize , GIDS_TRY_LIMIT_TAG, &datasize);
if (p && datasize == 1) {
if (tries_left)
*max_tries = p[0];

View File

@ -606,8 +606,8 @@ static void process_arr(sc_card_t * card, sc_file_t * file,
skip = 1; /* Skip over initial unknown SC DOs. */
for (;;) {
buf = p;
if (sc_asn1_read_tag(&p, left, &cla, &tag, &taglen) !=
SC_SUCCESS)
if (sc_asn1_read_tag(&p, left, &cla, &tag, &taglen) != SC_SUCCESS
|| p == NULL)
break;
left -= (p - buf);
tag |= cla;

View File

@ -922,7 +922,7 @@ pgp_enumerate_blob(sc_card_t *card, pgp_blob_t *blob)
r = sc_asn1_read_tag(&data, blob->len - (in - blob->data),
&cla, &tag, &len);
if (r < 0) {
if (r < 0 || data == NULL) {
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
"Unexpected end of contents\n");
return SC_ERROR_OBJECT_NOT_VALID;
@ -2132,6 +2132,8 @@ pgp_parse_and_set_pubkey_output(sc_card_t *card, u8* data, size_t data_len,
r = sc_asn1_read_tag((const u8**)&part,
data_len - (in - data),
&cla, &tag, &len);
if (part == NULL)
r = SC_ERROR_ASN1_OBJECT_NOT_FOUND;
LOG_TEST_RET(card->ctx, r, "Unexpected end of contents.");
/* undo ASN1's split of tag & class */
for (tmptag = tag; tmptag > 0x0FF; tmptag >>= 8) {

View File

@ -573,7 +573,8 @@ static int piv_general_io(sc_card_t *card, int ins, int p1, int p2,
* the buffer is bigger, so it will not produce "ASN1.tag too long!" */
body = rbuf;
if (sc_asn1_read_tag(&body, 0xffff, &cla_out, &tag_out, &bodylen) != SC_SUCCESS) {
if (sc_asn1_read_tag(&body, 0xffff, &cla_out, &tag_out, &bodylen) != SC_SUCCESS
|| body == NULL) {
/* only early beta cards had this problem */
sc_log(card->ctx, "***** received buffer tag MISSING ");
body = rbuf;
@ -679,6 +680,9 @@ static int piv_generate_key(sc_card_t *card,
in_len = rbuflen;
r = sc_asn1_read_tag(&cp, rbuflen, &cla_out, &tag_out, &in_len);
if (cp == NULL) {
r = SC_ERROR_ASN1_OBJECT_NOT_FOUND;
}
if (r != SC_SUCCESS) {
sc_log(card->ctx, "Tag buffer not found");
goto err;
@ -881,7 +885,8 @@ static int piv_read_obj_from_file(sc_card_t * card, char * filename,
goto err;
}
body = tagbuf;
if (sc_asn1_read_tag(&body, 0xfffff, &cla_out, &tag_out, &bodylen) != SC_SUCCESS) {
if (sc_asn1_read_tag(&body, 0xfffff, &cla_out, &tag_out, &bodylen) != SC_SUCCESS
|| body == NULL) {
sc_log(card->ctx, "DER problem");
r = SC_ERROR_INVALID_ASN1_OBJECT;
goto err;
@ -947,7 +952,8 @@ piv_get_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len)
r = piv_general_io(card, 0xCB, 0x3F, 0xFF, tagbuf, p - tagbuf, &rbuf, &rbuflen);
if (r > 0) {
body = rbuf;
if (sc_asn1_read_tag(&body, 0xffff, &cla_out, &tag_out, &bodylen) != SC_SUCCESS) {
if (sc_asn1_read_tag(&body, 0xffff, &cla_out, &tag_out, &bodylen) != SC_SUCCESS
|| body == NULL) {
sc_log(card->ctx, "***** received buffer tag MISSING ");
r = SC_ERROR_FILE_NOT_FOUND;
goto err;
@ -2847,8 +2853,8 @@ piv_process_history(sc_card_t *card)
body = ocfhfbuf;
if (sc_asn1_read_tag(&body, ocfhflen, &cla_out,
&tag_out, &bodylen) != SC_SUCCESS ||
cla_out+tag_out != 0x30) {
&tag_out, &bodylen) != SC_SUCCESS
|| cla_out+tag_out != 0x30) {
sc_log(card->ctx, "DER problem");
r = SC_ERROR_INVALID_ASN1_OBJECT;
goto err;
@ -2857,8 +2863,8 @@ piv_process_history(sc_card_t *card)
while (bodylen > 0) {
seqtag = seq;
if (sc_asn1_read_tag(&seq, bodylen, &cla_out,
&tag_out, &seqlen) != SC_SUCCESS ||
cla_out+tag_out != 0x30) {
&tag_out, &seqlen) != SC_SUCCESS
|| cla_out+tag_out != 0x30) {
sc_log(card->ctx, "DER problem");
r = SC_ERROR_INVALID_ASN1_OBJECT;
goto err;

View File

@ -47,7 +47,7 @@ sc_parse_ef_gdo_content(const unsigned char *gdo, size_t gdo_len,
}
break;
}
if (tag == SC_ASN1_TAG_EOC) {
if (p == NULL) {
/* done parsing */
break;
}

View File

@ -343,7 +343,8 @@ iso7816_process_fci(struct sc_card *card, struct sc_file *file,
p < end;
p += length, length = end - p) {
if (SC_SUCCESS != sc_asn1_read_tag(&p, length, &cla, &tag, &length)) {
if (SC_SUCCESS != sc_asn1_read_tag(&p, length, &cla, &tag, &length)
|| p == NULL) {
break;
}
switch (cla | tag) {

View File

@ -1269,7 +1269,7 @@ sc_pkcs15_read_der_file(sc_context_t *ctx, char * filename,
if (r != SC_SUCCESS && r != SC_ERROR_ASN1_END_OF_CONTENTS)
goto out;
if (tag_out == SC_ASN1_TAG_EOC || body == NULL) {
if (body == NULL) {
r = SC_SUCCESS;
goto out;
}

View File

@ -821,6 +821,8 @@ myeid_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
dataptr = data_obj.Data;
r = sc_asn1_read_tag((const u8 **)&dataptr, data_obj.DataLen, &cla, &tag, &taglen);
if (dataptr == NULL)
r = SC_ERROR_ASN1_OBJECT_NOT_FOUND;
LOG_TEST_RET(ctx, r, "Invalid EC public key data. Cannot parse DER structure.");
if (taglen == 0)

View File

@ -1223,7 +1223,8 @@ static size_t determineLength(const u8 *tlv, size_t buflen)
unsigned int cla,tag;
size_t len;
if (sc_asn1_read_tag(&ptr, buflen, &cla, &tag, &len) != SC_SUCCESS) {
if (sc_asn1_read_tag(&ptr, buflen, &cla, &tag, &len) != SC_SUCCESS
|| ptr == NULL) {
return 0;
}
@ -1515,16 +1516,16 @@ static int unwrap_key(sc_card_t *card, int keyid, const char *inf, const char *p
fclose(in);
ptr = keyblob;
if ((sc_asn1_read_tag(&ptr, keybloblen, &cla, &tag, &len) != SC_SUCCESS) ||
((cla & SC_ASN1_TAG_CONSTRUCTED) != SC_ASN1_TAG_CONSTRUCTED) ||
((tag != SC_ASN1_TAG_SEQUENCE)) ){
if ((sc_asn1_read_tag(&ptr, keybloblen, &cla, &tag, &len) != SC_SUCCESS)
|| ((cla & SC_ASN1_TAG_CONSTRUCTED) != SC_ASN1_TAG_CONSTRUCTED)
|| (tag != SC_ASN1_TAG_SEQUENCE) ){
fprintf(stderr, "Invalid wrapped key format (Outer sequence).\n");
return -1;
}
if ((sc_asn1_read_tag(&ptr, len, &cla, &tag, &olen) != SC_SUCCESS) ||
(cla & SC_ASN1_TAG_CONSTRUCTED) ||
((tag != SC_ASN1_TAG_OCTET_STRING)) ){
if ((sc_asn1_read_tag(&ptr, len, &cla, &tag, &olen) != SC_SUCCESS)
|| ((cla & SC_ASN1_TAG_CONSTRUCTED) != SC_ASN1_TAG_CONSTRUCTED)
|| (tag != SC_ASN1_TAG_OCTET_STRING) ){
fprintf(stderr, "Invalid wrapped key format (Key binary).\n");
return -1;
}