Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP4:Update
opensc.35661
opensc-CVE-2024-45619.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File opensc-CVE-2024-45619.patch of Package opensc.35661
commit f01bfbd19b9c8243a40f7f17d554fe0eb9e89d0d Author: Veronika HanulĂková <vhanulik@redhat.com> Date: Tue Jul 16 14:22:02 2024 +0200 pkcs15-tcos: Check number of read bytes for cert Thanks Matteo Marini for report https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8 fuzz_pkcs11/15 Index: opensc-0.22.0/src/libopensc/pkcs15-tcos.c =================================================================== --- opensc-0.22.0.orig/src/libopensc/pkcs15-tcos.c +++ opensc-0.22.0/src/libopensc/pkcs15-tcos.c @@ -45,6 +45,7 @@ static int insert_cert( struct sc_pkcs15_cert_info cert_info; struct sc_pkcs15_object cert_obj; unsigned char cert[20]; + size_t cert_len = 0; int r; memset(&cert_info, 0, sizeof(cert_info)); @@ -57,24 +58,31 @@ static int insert_cert( strlcpy(cert_obj.label, label, sizeof(cert_obj.label)); cert_obj.flags = writable ? SC_PKCS15_CO_FLAG_MODIFIABLE : 0; - if(sc_select_file(card, &cert_info.path, NULL)!=SC_SUCCESS){ - sc_log(ctx, - "Select(%s) failed\n", path); + if (sc_select_file(card, &cert_info.path, NULL) != SC_SUCCESS) { + sc_log(ctx, "Select(%s) failed", path); return 1; } - if(sc_read_binary(card, 0, cert, sizeof(cert), 0)<0){ - sc_log(ctx, - "ReadBinary(%s) failed\n", path); + r = sc_read_binary(card, 0, cert, sizeof(cert), 0); + if (r <= 0) { + sc_log(ctx, "ReadBinary(%s) failed\n", path); return 2; } - if(cert[0]!=0x30 || cert[1]!=0x82){ - sc_log(ctx, - "Invalid Cert: %02X:%02X:...\n", cert[0], cert[1]); + cert_len = r; /* actual number of read bytes */ + if (cert_len < 7 || (size_t)(7 + cert[5]) > cert_len) { + sc_log(ctx, "Invalid certificate length"); + return 3; + } + if (cert[0] != 0x30 || cert[1] != 0x82) { + sc_log(ctx, "Invalid Cert: %02X:%02X:...\n", cert[0], cert[1]); return 3; } /* some certificates are prefixed by an OID */ - if(cert[4]==0x06 && cert[5]<10 && cert[6+cert[5]]==0x30 && cert[7+cert[5]]==0x82){ + if (cert[4] == 0x06 && cert[5] < 10 && cert[6 + cert[5]] == 0x30 && cert[7 + cert[5]] == 0x82) { + if ((size_t)(9 + cert[5]) > cert_len) { + sc_log(ctx, "Invalid certificate length"); + return 3; + } cert_info.path.index=6+cert[5]; cert_info.path.count=(cert[8+cert[5]]<<8) + cert[9+cert[5]] + 4; } else { @@ -82,12 +90,12 @@ static int insert_cert( cert_info.path.count=(cert[2]<<8) + cert[3] + 4; } - r=sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); - if(r!=SC_SUCCESS){ - sc_log(ctx, "sc_pkcs15emu_add_x509_cert(%s) failed\n", path); + r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); + if (r != SC_SUCCESS) { + sc_log(ctx, "sc_pkcs15emu_add_x509_cert(%s) failed", path); return 4; } - sc_log(ctx, "%s: OK, Index=%d, Count=%d\n", path, cert_info.path.index, cert_info.path.count); + sc_log(ctx, "%s: OK, Index=%d, Count=%d", path, cert_info.path.index, cert_info.path.count); return 0; } Index: opensc-0.22.0/src/libopensc/pkcs15-gemsafeV1.c =================================================================== --- opensc-0.22.0.orig/src/libopensc/pkcs15-gemsafeV1.c +++ opensc-0.22.0/src/libopensc/pkcs15-gemsafeV1.c @@ -168,6 +168,7 @@ static int gemsafe_get_cert_len(sc_card_ struct sc_file *file; size_t objlen, certlen; unsigned int ind, i=0; + int read_len; sc_format_path(GEMSAFE_PATH, &path); r = sc_select_file(card, &path, &file); @@ -176,9 +177,11 @@ static int gemsafe_get_cert_len(sc_card_ sc_file_free(file); /* Initial read */ - r = sc_read_binary(card, 0, ibuf, GEMSAFE_READ_QUANTUM, 0); - if (r < 0) + read_len = sc_read_binary(card, 0, ibuf, GEMSAFE_READ_QUANTUM, 0); + if (read_len <= 2) { + sc_log(card->ctx, "Invalid size of object data: %d", read_len); return SC_ERROR_INTERNAL; + } /* Actual stored object size is encoded in first 2 bytes * (allocated EF space is much greater!) @@ -207,7 +210,7 @@ static int gemsafe_get_cert_len(sc_card_ * the private key. */ ind = 2; /* skip length */ - while (ibuf[ind] == 0x01 && i < gemsafe_cert_max) { + while (ind + 1 < (size_t)read_len && ibuf[ind] == 0x01 && i < gemsafe_cert_max) { if (ibuf[ind+1] == 0xFE) { gemsafe_prkeys[i].ref = ibuf[ind+4]; sc_log(card->ctx, "Key container %d is allocated and uses key_ref %d", @@ -234,7 +237,7 @@ static int gemsafe_get_cert_len(sc_card_ /* Read entire file, then dissect in memory. * Gemalto ClassicClient seems to do it the same way. */ - iptr = ibuf + GEMSAFE_READ_QUANTUM; + iptr = ibuf + read_len; while ((size_t)(iptr - ibuf) < objlen) { r = sc_read_binary(card, iptr - ibuf, iptr, MIN(GEMSAFE_READ_QUANTUM, objlen - (iptr - ibuf)), 0); @@ -242,7 +245,14 @@ static int gemsafe_get_cert_len(sc_card_ sc_log(card->ctx, "Could not read cert object"); return SC_ERROR_INTERNAL; } - iptr += GEMSAFE_READ_QUANTUM; + if (r == 0) + break; + read_len += r; + iptr += r; + } + if ((size_t)read_len < objlen) { + sc_log(card->ctx, "Could not read cert object"); + return SC_ERROR_INTERNAL; } /* Search buffer for certificates, they start with 0x3082. */ Index: opensc-0.22.0/src/pkcs15init/pkcs15-setcos.c =================================================================== --- opensc-0.22.0.orig/src/pkcs15init/pkcs15-setcos.c +++ opensc-0.22.0/src/pkcs15init/pkcs15-setcos.c @@ -488,6 +488,9 @@ setcos_generate_key(struct sc_profile *p r = sc_card_ctl(p15card->card, SC_CARDCTL_SETCOS_GETDATA, &data_obj); LOG_TEST_RET(ctx, r, "Cannot get key modulus: 'SETCOS_GETDATA' failed"); + if (data_obj.DataLen < 3 || data_obj.DataLen < pubkey->u.rsa.modulus.len) + LOG_TEST_RET(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED, "Cannot get key modulus: wrong length of raw key"); + keybits = ((raw_pubkey[0] * 256) + raw_pubkey[1]); /* modulus bit length */ if (keybits != key_info->modulus_length) { sc_log(ctx, @@ -495,7 +498,7 @@ setcos_generate_key(struct sc_profile *p keybits, key_info->modulus_length); LOG_TEST_RET(ctx, SC_ERROR_PKCS15INIT, "Failed to generate key"); } - memcpy (pubkey->u.rsa.modulus.data, &raw_pubkey[2], pubkey->u.rsa.modulus.len); + memcpy(pubkey->u.rsa.modulus.data, &raw_pubkey[2], pubkey->u.rsa.modulus.len); } sc_file_free(file); Index: opensc-0.22.0/src/pkcs15init/pkcs15-sc-hsm.c =================================================================== --- opensc-0.22.0.orig/src/pkcs15init/pkcs15-sc-hsm.c +++ opensc-0.22.0/src/pkcs15init/pkcs15-sc-hsm.c @@ -140,7 +140,7 @@ static int sc_hsm_determine_free_id(stru LOG_TEST_RET(card->ctx, filelistlength, "Could not enumerate file and key identifier"); for (j = 0; j < 256; j++) { - for (i = 0; i < filelistlength; i += 2) { + for (i = 0; i + 1 < filelistlength; i += 2) { if ((filelist[i] == range) && (filelist[i + 1] == j)) { break; } Index: opensc-0.22.0/src/libopensc/card-coolkey.c =================================================================== --- opensc-0.22.0.orig/src/libopensc/card-coolkey.c +++ opensc-0.22.0/src/libopensc/card-coolkey.c @@ -1684,6 +1684,7 @@ static int coolkey_rsa_op(sc_card_t *car u8 key_number; size_t params_len; u8 buf[MAX_COMPUTE_BUF + 2]; + size_t buf_len; u8 *buf_out; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -1724,8 +1725,6 @@ static int coolkey_rsa_op(sc_card_t *car ushort2bebytes(params.init.buf_len, 0); } else { /* The data fits in APDU. Copy it to the params object */ - size_t buf_len; - params.init.location = COOLKEY_CRYPT_LOCATION_APDU; params_len = sizeof(params.init) + datalen; @@ -1745,6 +1744,7 @@ static int coolkey_rsa_op(sc_card_t *car if (r < 0) { goto done; } + buf_len = crypt_out_len_p; if (datalen > MAX_COMPUTE_BUF) { u8 len_buf[2]; @@ -1763,7 +1763,12 @@ static int coolkey_rsa_op(sc_card_t *car priv->nonce, sizeof(priv->nonce)); } else { - size_t out_length = bebytes2ushort(buf); + size_t out_length; + if (buf_len < 2) { + r = SC_ERROR_WRONG_LENGTH; + goto done; + } + out_length = bebytes2ushort(buf); if (out_length > sizeof buf - 2) { r = SC_ERROR_WRONG_LENGTH; goto done;
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