Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP2:GA
opensc
opensc-CVE-2024-45619.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File opensc-CVE-2024-45619.patch of Package opensc
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.19.0/src/libopensc/pkcs15-tcos.c =================================================================== --- opensc-0.19.0.orig/src/libopensc/pkcs15-tcos.c +++ opensc-0.19.0/src/libopensc/pkcs15-tcos.c @@ -50,6 +50,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)); @@ -62,24 +63,32 @@ 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_debug(ctx, SC_LOG_DEBUG_NORMAL, - "Select(%s) failed\n", path); + if(sc_select_file(card, &cert_info.path, NULL) != SC_SUCCESS) { + sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Select(%s) failed\n", path); return 1; } - if(sc_read_binary(card, 0, cert, sizeof(cert), 0)<0){ - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, - "ReadBinary(%s) failed\n", path); + r = sc_read_binary(card, 0, cert, sizeof(cert), 0); + if(r <= 0) { + sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "ReadBinary(%s) failed\n", path); return 2; } - if(cert[0]!=0x30 || cert[1]!=0x82){ - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, - "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_debug(ctx, SC_LOG_DEBUG_NORMAL, "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 { Index: opensc-0.19.0/src/libopensc/pkcs15-gemsafeV1.c =================================================================== --- opensc-0.19.0.orig/src/libopensc/pkcs15-gemsafeV1.c +++ opensc-0.19.0/src/libopensc/pkcs15-gemsafeV1.c @@ -170,6 +170,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); @@ -177,9 +178,11 @@ static int gemsafe_get_cert_len(sc_card_ return SC_ERROR_INTERNAL; /* 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!) @@ -208,7 +211,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", @@ -235,7 +238,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); @@ -243,7 +246,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.19.0/src/pkcs15init/pkcs15-setcos.c =================================================================== --- opensc-0.19.0.orig/src/pkcs15init/pkcs15-setcos.c +++ opensc-0.19.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); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, 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_debug(ctx, SC_LOG_DEBUG_NORMAL, @@ -495,7 +498,7 @@ setcos_generate_key(struct sc_profile *p keybits, key_info->modulus_length); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, 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.19.0/src/pkcs15init/pkcs15-sc-hsm.c =================================================================== --- opensc-0.19.0.orig/src/pkcs15init/pkcs15-sc-hsm.c +++ opensc-0.19.0/src/pkcs15init/pkcs15-sc-hsm.c @@ -139,7 +139,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.19.0/src/libopensc/card-coolkey.c =================================================================== --- opensc-0.19.0.orig/src/libopensc/card-coolkey.c +++ opensc-0.19.0/src/libopensc/card-coolkey.c @@ -1684,8 +1684,8 @@ static int coolkey_rsa_op(sc_card_t *car coolkey_compute_crypt_params_t params; u8 key_number; size_t params_len; - size_t buf_len; u8 buf[MAX_COMPUTE_BUF+2]; + size_t buf_len; u8 *buf_out; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -1741,6 +1741,7 @@ static int coolkey_rsa_op(sc_card_t *car if (crypt_in_len) { memcpy(params.buf, crypt_in, crypt_in_len); } + buf_len = *crypt_out_len_p; r = coolkey_apdu_io(card, COOLKEY_CLASS, COOLKEY_INS_COMPUTE_CRYPT, @@ -1767,7 +1768,16 @@ 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; + } out_length = MIN(out_length, max_out_len); memcpy(out, buf+2, out_length); r = out_length;
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