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;
|
||||
|
||||
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:
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue