diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index f1424029..d70d0319 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -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: diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index 34b4ce75..d8bcb885 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -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]; diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 57ead6bd..2923d1f5 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -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; diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 55c19395..bfb00149 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -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) { diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index c291374d..70fbd660 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -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; diff --git a/src/libopensc/ef-gdo.c b/src/libopensc/ef-gdo.c index bda51f22..39dea2e5 100644 --- a/src/libopensc/ef-gdo.c +++ b/src/libopensc/ef-gdo.c @@ -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; } diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index a8c12b51..df283d20 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -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) { diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 1d54dbe2..0be05bf7 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -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; } diff --git a/src/pkcs15init/pkcs15-myeid.c b/src/pkcs15init/pkcs15-myeid.c index 4931027d..29f9aa22 100644 --- a/src/pkcs15init/pkcs15-myeid.c +++ b/src/pkcs15init/pkcs15-myeid.c @@ -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) diff --git a/src/tools/sc-hsm-tool.c b/src/tools/sc-hsm-tool.c index 6ae21163..d246b461 100644 --- a/src/tools/sc-hsm-tool.c +++ b/src/tools/sc-hsm-tool.c @@ -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; }