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:
parent
fe0d6f9187
commit
45ad44e311
|
@ -364,7 +364,7 @@ static void print_tags_recursive(const u8 * buf0, const u8 * buf,
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
r = sc_asn1_read_tag(&tagp, bytesleft, &cla, &tag, &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");
|
printf("Error in decoding.\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -475,8 +475,10 @@ const u8 *sc_asn1_find_tag(sc_context_t *ctx, const u8 * buf,
|
||||||
|
|
||||||
buf = p;
|
buf = p;
|
||||||
/* read a tag */
|
/* 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;
|
return NULL;
|
||||||
|
|
||||||
left -= (p - buf);
|
left -= (p - buf);
|
||||||
/* we need to shift the class byte to the leftmost
|
/* we need to shift the class byte to the leftmost
|
||||||
* byte of the tag */
|
* 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;
|
size_t len = *buflen, taglen;
|
||||||
unsigned int cla = 0, tag;
|
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;
|
return NULL;
|
||||||
switch (cla & 0xC0) {
|
switch (cla & 0xC0) {
|
||||||
case SC_ASN1_TAG_UNIVERSAL:
|
case SC_ASN1_TAG_UNIVERSAL:
|
||||||
|
|
|
@ -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);
|
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");
|
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 (p && datasize == 1) {
|
||||||
if (tries_left)
|
if (tries_left)
|
||||||
*tries_left = p[0];
|
*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 (p && datasize == 1) {
|
||||||
if (tries_left)
|
if (tries_left)
|
||||||
*tries_left = p[0];
|
*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 (p && datasize == 1) {
|
||||||
if (tries_left)
|
if (tries_left)
|
||||||
*max_tries = p[0];
|
*max_tries = p[0];
|
||||||
|
|
|
@ -606,8 +606,8 @@ static void process_arr(sc_card_t * card, sc_file_t * file,
|
||||||
skip = 1; /* Skip over initial unknown SC DOs. */
|
skip = 1; /* Skip over initial unknown SC DOs. */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
buf = p;
|
buf = p;
|
||||||
if (sc_asn1_read_tag(&p, left, &cla, &tag, &taglen) !=
|
if (sc_asn1_read_tag(&p, left, &cla, &tag, &taglen) != SC_SUCCESS
|
||||||
SC_SUCCESS)
|
|| p == NULL)
|
||||||
break;
|
break;
|
||||||
left -= (p - buf);
|
left -= (p - buf);
|
||||||
tag |= cla;
|
tag |= cla;
|
||||||
|
|
|
@ -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),
|
r = sc_asn1_read_tag(&data, blob->len - (in - blob->data),
|
||||||
&cla, &tag, &len);
|
&cla, &tag, &len);
|
||||||
if (r < 0) {
|
if (r < 0 || data == NULL) {
|
||||||
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
|
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
|
||||||
"Unexpected end of contents\n");
|
"Unexpected end of contents\n");
|
||||||
return SC_ERROR_OBJECT_NOT_VALID;
|
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,
|
r = sc_asn1_read_tag((const u8**)&part,
|
||||||
data_len - (in - data),
|
data_len - (in - data),
|
||||||
&cla, &tag, &len);
|
&cla, &tag, &len);
|
||||||
|
if (part == NULL)
|
||||||
|
r = SC_ERROR_ASN1_OBJECT_NOT_FOUND;
|
||||||
LOG_TEST_RET(card->ctx, r, "Unexpected end of contents.");
|
LOG_TEST_RET(card->ctx, r, "Unexpected end of contents.");
|
||||||
/* undo ASN1's split of tag & class */
|
/* undo ASN1's split of tag & class */
|
||||||
for (tmptag = tag; tmptag > 0x0FF; tmptag >>= 8) {
|
for (tmptag = tag; tmptag > 0x0FF; tmptag >>= 8) {
|
||||||
|
|
|
@ -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!" */
|
* the buffer is bigger, so it will not produce "ASN1.tag too long!" */
|
||||||
|
|
||||||
body = rbuf;
|
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 */
|
/* only early beta cards had this problem */
|
||||||
sc_log(card->ctx, "***** received buffer tag MISSING ");
|
sc_log(card->ctx, "***** received buffer tag MISSING ");
|
||||||
body = rbuf;
|
body = rbuf;
|
||||||
|
@ -679,6 +680,9 @@ static int piv_generate_key(sc_card_t *card,
|
||||||
in_len = rbuflen;
|
in_len = rbuflen;
|
||||||
|
|
||||||
r = sc_asn1_read_tag(&cp, rbuflen, &cla_out, &tag_out, &in_len);
|
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) {
|
if (r != SC_SUCCESS) {
|
||||||
sc_log(card->ctx, "Tag buffer not found");
|
sc_log(card->ctx, "Tag buffer not found");
|
||||||
goto err;
|
goto err;
|
||||||
|
@ -881,7 +885,8 @@ static int piv_read_obj_from_file(sc_card_t * card, char * filename,
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
body = tagbuf;
|
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");
|
sc_log(card->ctx, "DER problem");
|
||||||
r = SC_ERROR_INVALID_ASN1_OBJECT;
|
r = SC_ERROR_INVALID_ASN1_OBJECT;
|
||||||
goto err;
|
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);
|
r = piv_general_io(card, 0xCB, 0x3F, 0xFF, tagbuf, p - tagbuf, &rbuf, &rbuflen);
|
||||||
if (r > 0) {
|
if (r > 0) {
|
||||||
body = rbuf;
|
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 ");
|
sc_log(card->ctx, "***** received buffer tag MISSING ");
|
||||||
r = SC_ERROR_FILE_NOT_FOUND;
|
r = SC_ERROR_FILE_NOT_FOUND;
|
||||||
goto err;
|
goto err;
|
||||||
|
@ -2847,8 +2853,8 @@ piv_process_history(sc_card_t *card)
|
||||||
|
|
||||||
body = ocfhfbuf;
|
body = ocfhfbuf;
|
||||||
if (sc_asn1_read_tag(&body, ocfhflen, &cla_out,
|
if (sc_asn1_read_tag(&body, ocfhflen, &cla_out,
|
||||||
&tag_out, &bodylen) != SC_SUCCESS ||
|
&tag_out, &bodylen) != SC_SUCCESS
|
||||||
cla_out+tag_out != 0x30) {
|
|| cla_out+tag_out != 0x30) {
|
||||||
sc_log(card->ctx, "DER problem");
|
sc_log(card->ctx, "DER problem");
|
||||||
r = SC_ERROR_INVALID_ASN1_OBJECT;
|
r = SC_ERROR_INVALID_ASN1_OBJECT;
|
||||||
goto err;
|
goto err;
|
||||||
|
@ -2857,8 +2863,8 @@ piv_process_history(sc_card_t *card)
|
||||||
while (bodylen > 0) {
|
while (bodylen > 0) {
|
||||||
seqtag = seq;
|
seqtag = seq;
|
||||||
if (sc_asn1_read_tag(&seq, bodylen, &cla_out,
|
if (sc_asn1_read_tag(&seq, bodylen, &cla_out,
|
||||||
&tag_out, &seqlen) != SC_SUCCESS ||
|
&tag_out, &seqlen) != SC_SUCCESS
|
||||||
cla_out+tag_out != 0x30) {
|
|| cla_out+tag_out != 0x30) {
|
||||||
sc_log(card->ctx, "DER problem");
|
sc_log(card->ctx, "DER problem");
|
||||||
r = SC_ERROR_INVALID_ASN1_OBJECT;
|
r = SC_ERROR_INVALID_ASN1_OBJECT;
|
||||||
goto err;
|
goto err;
|
||||||
|
|
|
@ -47,7 +47,7 @@ sc_parse_ef_gdo_content(const unsigned char *gdo, size_t gdo_len,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (tag == SC_ASN1_TAG_EOC) {
|
if (p == NULL) {
|
||||||
/* done parsing */
|
/* done parsing */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -343,7 +343,8 @@ iso7816_process_fci(struct sc_card *card, struct sc_file *file,
|
||||||
p < end;
|
p < end;
|
||||||
p += length, length = end - p) {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
switch (cla | tag) {
|
switch (cla | tag) {
|
||||||
|
|
|
@ -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)
|
if (r != SC_SUCCESS && r != SC_ERROR_ASN1_END_OF_CONTENTS)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (tag_out == SC_ASN1_TAG_EOC || body == NULL) {
|
if (body == NULL) {
|
||||||
r = SC_SUCCESS;
|
r = SC_SUCCESS;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -821,6 +821,8 @@ myeid_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
|
||||||
|
|
||||||
dataptr = data_obj.Data;
|
dataptr = data_obj.Data;
|
||||||
r = sc_asn1_read_tag((const u8 **)&dataptr, data_obj.DataLen, &cla, &tag, &taglen);
|
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.");
|
LOG_TEST_RET(ctx, r, "Invalid EC public key data. Cannot parse DER structure.");
|
||||||
|
|
||||||
if (taglen == 0)
|
if (taglen == 0)
|
||||||
|
|
|
@ -1223,7 +1223,8 @@ static size_t determineLength(const u8 *tlv, size_t buflen)
|
||||||
unsigned int cla,tag;
|
unsigned int cla,tag;
|
||||||
size_t len;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1515,16 +1516,16 @@ static int unwrap_key(sc_card_t *card, int keyid, const char *inf, const char *p
|
||||||
fclose(in);
|
fclose(in);
|
||||||
|
|
||||||
ptr = keyblob;
|
ptr = keyblob;
|
||||||
if ((sc_asn1_read_tag(&ptr, keybloblen, &cla, &tag, &len) != SC_SUCCESS) ||
|
if ((sc_asn1_read_tag(&ptr, keybloblen, &cla, &tag, &len) != SC_SUCCESS)
|
||||||
((cla & SC_ASN1_TAG_CONSTRUCTED) != SC_ASN1_TAG_CONSTRUCTED) ||
|
|| ((cla & SC_ASN1_TAG_CONSTRUCTED) != SC_ASN1_TAG_CONSTRUCTED)
|
||||||
((tag != SC_ASN1_TAG_SEQUENCE)) ){
|
|| (tag != SC_ASN1_TAG_SEQUENCE) ){
|
||||||
fprintf(stderr, "Invalid wrapped key format (Outer sequence).\n");
|
fprintf(stderr, "Invalid wrapped key format (Outer sequence).\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((sc_asn1_read_tag(&ptr, len, &cla, &tag, &olen) != SC_SUCCESS) ||
|
if ((sc_asn1_read_tag(&ptr, len, &cla, &tag, &olen) != SC_SUCCESS)
|
||||||
(cla & SC_ASN1_TAG_CONSTRUCTED) ||
|
|| ((cla & SC_ASN1_TAG_CONSTRUCTED) != SC_ASN1_TAG_CONSTRUCTED)
|
||||||
((tag != SC_ASN1_TAG_OCTET_STRING)) ){
|
|| (tag != SC_ASN1_TAG_OCTET_STRING) ){
|
||||||
fprintf(stderr, "Invalid wrapped key format (Key binary).\n");
|
fprintf(stderr, "Invalid wrapped key format (Key binary).\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue