diff options
Diffstat (limited to 'lib/opencdk/read-packet.c')
-rw-r--r-- | lib/opencdk/read-packet.c | 40 |
1 files changed, 29 insertions, 11 deletions
diff --git a/lib/opencdk/read-packet.c b/lib/opencdk/read-packet.c index cdb47007a6..b999e1c000 100644 --- a/lib/opencdk/read-packet.c +++ b/lib/opencdk/read-packet.c @@ -482,46 +482,64 @@ read_attribute(cdk_stream_t inp, size_t pktlen, cdk_pkt_userid_t attr, return CDK_Out_Of_Core; rc = stream_read(inp, buf, pktlen, &nread); if (rc) { - cdk_free(buf); - return CDK_Inv_Packet; + gnutls_assert(); + rc = CDK_Inv_Packet; + goto error; } + p = buf; len = *p++; pktlen--; + if (len == 255) { + if (pktlen < 4) { + gnutls_assert(); + rc = CDK_Inv_Packet; + goto error; + } + len = _cdk_buftou32(p); p += 4; pktlen -= 4; } else if (len >= 192) { if (pktlen < 2) { - cdk_free(buf); - return CDK_Inv_Packet; + gnutls_assert(); + rc = CDK_Inv_Packet; + goto error; } + len = ((len - 192) << 8) + *p + 192; p++; pktlen--; } - if (*p != 1) { /* Currently only 1, meaning an image, is defined. */ - cdk_free(buf); - return CDK_Inv_Packet; + if (!len || *p != 1) { /* Currently only 1, meaning an image, is defined. */ + rc = CDK_Inv_Packet; + goto error; } + p++; len--; if (len >= pktlen) { - cdk_free(buf); - return CDK_Inv_Packet; + rc = CDK_Inv_Packet; + goto error; } + attr->attrib_img = cdk_calloc(1, len); if (!attr->attrib_img) { - cdk_free(buf); - return CDK_Out_Of_Core; + rc = CDK_Out_Of_Core; + goto error; } + attr->attrib_len = len; memcpy(attr->attrib_img, p, len); cdk_free(buf); return rc; + + error: + cdk_free(buf); + return rc; } |