Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Step:15-SP2
opensc
opensc-0_19_0-CVE-2021-42782.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File opensc-0_19_0-CVE-2021-42782.patch of Package opensc
diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index 4862592..84f9b81 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -134,7 +134,7 @@ static int cardos_have_2048bit_package(sc_card_t *card) sc_apdu_t apdu; u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; int r; - const u8 *p = rbuf, *q; + const u8 *p = rbuf, *q, *pp; size_t len, tlen = 0, ilen = 0; sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0x01, 0x88); @@ -150,10 +150,10 @@ static int cardos_have_2048bit_package(sc_card_t *card) return 0; while (len != 0) { - p = sc_asn1_find_tag(card->ctx, p, len, 0xe1, &tlen); - if (p == NULL) + pp = sc_asn1_find_tag(card->ctx, p, len, 0xe1, &tlen); + if (pp == NULL) return 0; - q = sc_asn1_find_tag(card->ctx, p, tlen, 0x01, &ilen); + q = sc_asn1_find_tag(card->ctx, pp, tlen, 0x01, &ilen); if (q == NULL || ilen != 4) return 0; if (q[0] == 0x1c) diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index dcd4a83..6829171 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -1109,7 +1109,7 @@ iasecc_process_fci(struct sc_card *card, struct sc_file *file, else acls = sc_asn1_find_tag(ctx, buf, buflen, IASECC_DOCP_TAG_ACLS_CONTACT, &taglen); - if (!acls) { + if (!acls || taglen < 7) { sc_log(ctx, "ACLs not found in data(%"SC_FORMAT_LEN_SIZE_T"u) %s", buflen, sc_dump_hex(buf, buflen)); diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 61acedc..a97e6ff 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -669,14 +669,12 @@ static int piv_generate_key(sc_card_t *card, const u8 *cp; keydata->exponent = 0; - /* expected tag is 7f49. */ - /* we will whatever tag is present */ - cp = rbuf; in_len = rbuflen; + /* expected tag is 0x7f49,returned as cla_out == 0x60 and tag_out = 0x1F49 */ r = sc_asn1_read_tag(&cp, rbuflen, &cla_out, &tag_out, &in_len); - if (cp == NULL) { + if (cp == NULL || in_len == 0 || cla_out != 0x60 || tag_out != 0x1f49) { r = SC_ERROR_ASN1_OBJECT_NOT_FOUND; } if (r != SC_SUCCESS) { @@ -1090,7 +1088,7 @@ piv_cache_internal_data(sc_card_t *card, int enumtag) priv->obj_cache[enumtag].obj_len, 0x53, &bodylen); - if (body == NULL) + if (body == NULL || priv->obj_cache[enumtag].obj_data[0] != 0x53) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_VALID); /* get the certificate out */ @@ -1660,7 +1658,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, /* Remove the encompassing outer TLV of 0x7C and get the data */ body = sc_asn1_find_tag(card->ctx, rbuf, r, 0x7C, &body_len); - if (!body) { + if (!body || rbuf[0] != 0x7C) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid Witness Data response of NULL\n"); r = SC_ERROR_INVALID_DATA; goto err; @@ -1784,7 +1782,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, /* Remove the encompassing outer TLV of 0x7C and get the data */ body = sc_asn1_find_tag(card->ctx, rbuf, r, 0x7C, &body_len); - if(!body) { + if(!body || rbuf[0] != 0x7C) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not find outer tag 0x7C in response"); r = SC_ERROR_INVALID_DATA; goto err; @@ -1948,7 +1946,7 @@ static int piv_general_external_authenticate(sc_card_t *card, /* Remove the encompassing outer TLV of 0x7C and get the data */ body = sc_asn1_find_tag(card->ctx, rbuf, r, 0x7C, &body_len); - if (!body) { + if (!body || rbuf[0] != 0x7C) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid Challenge Data response of NULL\n"); r = SC_ERROR_INVALID_DATA; goto err; @@ -2108,7 +2106,7 @@ piv_get_serial_nr_from_CHUI(sc_card_t* card, sc_serial_number_t* serial) r = SC_ERROR_INTERNAL; if (rbuflen != 0) { body = sc_asn1_find_tag(card->ctx, rbuf, rbuflen, 0x53, &bodylen); /* Pass the outer wrapper asn1 */ - if (body != NULL && bodylen != 0) { + if (body != NULL && bodylen != 0 && rbuf[0] == 0x53) { fascn = sc_asn1_find_tag(card->ctx, body, bodylen, 0x30, &fascnlen); /* Find the FASC-N data */ guid = sc_asn1_find_tag(card->ctx, body, bodylen, 0x34, &guidlen); @@ -2323,10 +2321,10 @@ static int piv_validate_general_authentication(sc_card_t *card, piv_private_data_t * priv = PIV_DATA(card); int r; u8 *p; - const u8 *tag; + const unsigned char *p2; size_t taglen; - const u8 *body; size_t bodylen; + unsigned int cla, tag; unsigned int real_alg_id; u8 sbuf[4096]; /* needs work. for 3072 keys, needs 384+10 or so */ @@ -2369,20 +2367,28 @@ static int piv_validate_general_authentication(sc_card_t *card, r = piv_general_io(card, 0x87, real_alg_id, priv->key_ref, sbuf, p - sbuf, &rbuf, &rbuflen); + if (r < 0) + goto err; - if (r >= 0) { - body = sc_asn1_find_tag(card->ctx, rbuf, rbuflen, 0x7c, &bodylen); - if (body) { - tag = sc_asn1_find_tag(card->ctx, body, bodylen, 0x82, &taglen); - if (tag) { - memcpy(out, tag, taglen); - r = taglen; - } else - r = SC_ERROR_INVALID_DATA; - } else - r = SC_ERROR_INVALID_DATA; + p2= rbuf; + r= sc_asn1_read_tag(&p2, r, &cla, &tag, &bodylen); + if (p2 == NULL || r < 0 || bodylen == 0 || (cla|tag) != 0x7C) { + LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find 0x7C"); + } + + r = sc_asn1_read_tag(&p2, bodylen, &cla, &tag, &taglen); + if (p2 == NULL || r < 0 || taglen == 0 || (cla|tag) != 0x82) { + LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find 0x82"); } + if (taglen > outlen) { + LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "data read longer then buffer"); + } + + memcpy(out, p2, taglen); + r = taglen; + +err: if (rbuf) free(rbuf); @@ -2400,19 +2406,19 @@ piv_compute_signature(sc_card_t *card, const u8 * data, size_t datalen, size_t nLen; u8 rbuf[128]; /* For EC conversions 384 will fit */ size_t rbuflen = sizeof(rbuf); - const u8 * body; - size_t bodylen; - const u8 * tag; - size_t taglen; + const unsigned char *pseq, *pint, *ptemp, *pend; + unsigned int cla, tag; + size_t seqlen; + size_t intlen; + size_t templen; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); /* The PIV returns a DER SEQUENCE{INTEGER, INTEGER} - * Which may have leading 00 to force positive - * TODO: -DEE should check if PKCS15 want the same - * But PKCS11 just wants 2* filed_length in bytes + * Which may have leading 00 to force apositive integer + * But PKCS11 just wants 2* field_length in bytes * So we have to strip out the integers - * if present and pad on left if too short. + * and pad on left if too short. */ if (priv->alg_id == 0x11 || priv->alg_id == 0x14 ) { @@ -2431,32 +2437,34 @@ piv_compute_signature(sc_card_t *card, const u8 * data, size_t datalen, goto err; if ( r >= 0) { - body = sc_asn1_find_tag(card->ctx, rbuf, rbuflen, 0x30, &bodylen); - - for (i = 0; i<2; i++) { - if (body) { - tag = sc_asn1_find_tag(card->ctx, body, bodylen, 0x02, &taglen); - if (tag) { - bodylen -= taglen - (tag - body); - body = tag + taglen; - - if (taglen > nLen) { /* drop leading 00 if present */ - if (*tag != 0x00) { - r = SC_ERROR_INVALID_DATA; - goto err; - } - tag++; - taglen--; - } - memcpy(out + nLen*i + nLen - taglen , tag, taglen); - } else { + pseq = rbuf; + r = sc_asn1_read_tag(&pseq, r, &cla, &tag, &seqlen); + if (pseq == NULL || r < 0 || seqlen == 0 || (cla|tag) != 0x30) + LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find 0x30"); + + pint = pseq; + pend = pseq + seqlen; + for (i = 0; i < 2; i++) { + r = sc_asn1_read_tag(&pint, (pend - pint), &cla, &tag, &intlen); + if (pint == NULL || r < 0 || intlen == 0 || (cla|tag) != 0x02) + LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find 0x02"); + if (intlen> nLen + 1) + LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA,"Signature too long"); + + ptemp= pint; + templen = intlen; + if (intlen> nLen) { /* drop leading 00 if present */ + if (*ptemp!= 0x00) { + LOG_TEST_GOTO_ERR(card->ctx,SC_ERROR_INVALID_DATA,"Signaturetoolong"); r = SC_ERROR_INVALID_DATA; goto err; } - } else { - r = SC_ERROR_INVALID_DATA; - goto err; + ptemp++; + templen--; } + memcpy(out + nLen*i + nLen - templen , ptemp, templen); + pint += intlen; /* next integer */ + } r = 2 * nLen; } diff --git a/src/libopensc/pkcs15-coolkey.c b/src/libopensc/pkcs15-coolkey.c index 09618fe..3005785 100644 --- a/src/libopensc/pkcs15-coolkey.c +++ b/src/libopensc/pkcs15-coolkey.c @@ -428,7 +428,8 @@ coolkey_get_public_key_from_certificate(sc_pkcs15_card_t *p15card, sc_cardctl_co sc_pkcs15_pubkey_t *key = NULL; int r; - cert_info.value.value = NULL; + memset(&cert_info, 0, sizeof(cert_info)); + r = coolkey_get_certificate(p15card->card, obj, &cert_info.value); if (r < 0) { goto fail; diff --git a/src/libopensc/pkcs15-tcos.c b/src/libopensc/pkcs15-tcos.c index 547de12..642c2b5 100644 --- a/src/libopensc/pkcs15-tcos.c +++ b/src/libopensc/pkcs15-tcos.c @@ -152,7 +152,7 @@ static int insert_key( sc_debug(ctx, SC_LOG_DEBUG_NORMAL,"No EF_KEYD-Record found\n"); return 1; } - for(i=0;i<r;i+=2+buf[i+1]){ + for(i=0;i+1<r;i+=2+buf[i+1]){ if(buf[i]==0xB6) can_sign++; if(buf[i]==0xB8) can_crypt++; }
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor