From d5d15105dd4cc91e54c86efbd75f07c6f21bb281 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 19 Jun 2018 14:54:31 +0200 Subject: [PATCH] cac: Ignore end of content errors (#7) The CAC buffers are split to separate TL and V buffers so we need to ignore this error --- src/libopensc/card-cac.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c index 756788a0..a42df928 100644 --- a/src/libopensc/card-cac.c +++ b/src/libopensc/card-cac.c @@ -637,7 +637,8 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, val_len -= len, tlv_len -= len, val_ptr += len, tlv_ptr += len) { /* get the tag and the length */ tl_start = tl_ptr; - if (sc_simpletlv_read_tag(&tl_ptr, tl_len, &tag, &len) != SC_SUCCESS) + r = sc_simpletlv_read_tag(&tl_ptr, tl_len, &tag, &len); + if (r != SC_SUCCESS && r != SC_ERROR_TLV_END_OF_CONTENTS) break; tl_head_len = (tl_ptr - tl_start); sc_simpletlv_put_tag(tag, len, tlv_ptr, tlv_len, &tlv_ptr); @@ -646,6 +647,8 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, /* don't crash on bad data */ if (val_len < len) { + sc_log(card->ctx, "Received too long value %"SC_FORMAT_LEN_SIZE_T"u, " + "while only %"SC_FORMAT_LEN_SIZE_T"u left. Truncating", len, val_len); len = val_len; } /* if we run out of return space, truncate */ @@ -667,13 +670,17 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, for (tl_ptr = tl, val_ptr = val; tl_len >= 2; val_len -= len, val_ptr += len, tl_len -= tl_head_len) { tl_start = tl_ptr; - if (sc_simpletlv_read_tag(&tl_ptr, tl_len, &tag, &len) != SC_SUCCESS) + r = sc_simpletlv_read_tag(&tl_ptr, tl_len, &tag, &len); + if (r != SC_SUCCESS && r != SC_ERROR_TLV_END_OF_CONTENTS) break; tl_head_len = tl_ptr - tl_start; /* incomplete value */ - if (val_len < len) + if (val_len < len) { + sc_log(card->ctx, "Read incomplete value %"SC_FORMAT_LEN_SIZE_T"u, " + "while only %"SC_FORMAT_LEN_SIZE_T"u left", len, val_len); break; + } if (tag == CAC_TAG_CERTIFICATE) { cert_len = len; @@ -687,9 +694,6 @@ static int cac_read_binary(sc_card_t *card, unsigned int idx, if (tag == CAC_TAG_MSCUID) { sc_log_hex(card->ctx, "MSCUID", val_ptr, len); } - if ((val_len < len) || (tl_len < tl_head_len)) { - break; - } } /* if the info byte is 1, then the cert is compressed, decompress it */ if ((cert_type & 0x3) == 1) {