Accepting request 1224836 from security:chipcard

OBS-URL: https://build.opensuse.org/request/show/1224836
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/opensc?expand=0&rev=61
This commit is contained in:
Ana Guerrero 2024-11-18 19:02:19 +00:00 committed by Git OBS Bridge
commit 839812f4ce
11 changed files with 83 additions and 847 deletions

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:23cbaae8bd7c8eb589b68c0a961dfb0d02007bea3165a3fc5efe2621d549b37b
size 2395579

3
opensc-0.26.0.tar.gz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:837baead45e1505260d868871056150ede6e73d35460a470f2595a9e5e75f82b
size 2415271

View File

@ -1,111 +0,0 @@
commit 5e4f26b510b04624386c54816bf26aacea0fe4a1
Author: Veronika Hanulíková <vhanulik@redhat.com>
Date: Thu Jul 11 14:58:25 2024 +0200
cac: Fix uninitialized values
Thanks Matteo Marini for report
https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8
fuzz_card/1,fuzz_pkcs11/6
Index: opensc-0.25.1/src/libopensc/card-cac.c
===================================================================
--- opensc-0.25.1.orig/src/libopensc/card-cac.c
+++ opensc-0.25.1/src/libopensc/card-cac.c
@@ -252,7 +252,7 @@ static int cac_apdu_io(sc_card_t *card,
size_t * recvbuflen)
{
int r;
- sc_apdu_t apdu;
+ sc_apdu_t apdu = {0};
u8 rbufinitbuf[CAC_MAX_SIZE];
u8 *rbuf;
size_t rbuflen;
@@ -389,13 +389,13 @@ fail:
static int cac_read_file(sc_card_t *card, int file_type, u8 **out_buf, size_t *out_len)
{
u8 params[2];
- u8 count[2];
+ u8 count[2] = {0};
u8 *out = NULL;
- u8 *out_ptr;
+ u8 *out_ptr = NULL;
size_t offset = 0;
size_t size = 0;
size_t left = 0;
- size_t len;
+ size_t len = 0;
int r;
params[0] = file_type;
@@ -458,7 +458,7 @@ static int cac_read_binary(sc_card_t *ca
const u8 *tl_ptr, *val_ptr, *tl_start;
u8 *tlv_ptr;
const u8 *cert_ptr;
- size_t tl_len, val_len, tlv_len;
+ size_t tl_len = 0, val_len = 0, tlv_len;
size_t len, tl_head_len, cert_len;
u8 cert_type, tag;
@@ -1519,7 +1519,7 @@ static int cac_parse_CCC(sc_card_t *card
static int cac_process_CCC(sc_card_t *card, cac_private_data_t *priv, int depth)
{
u8 *tl = NULL, *val = NULL;
- size_t tl_len, val_len;
+ size_t tl_len = 0, val_len = 0;
int r;
if (depth > CAC_MAX_CCC_DEPTH) {
Index: opensc-0.25.1/src/libopensc/card-piv.c
===================================================================
--- opensc-0.25.1.orig/src/libopensc/card-piv.c
+++ opensc-0.25.1/src/libopensc/card-piv.c
@@ -4425,7 +4425,7 @@ static int piv_get_challenge(sc_card_t *
const u8 *p;
size_t out_len = 0;
int r;
- unsigned int tag_out, cla_out;
+ unsigned int tag_out = 0, cla_out = 0;
piv_private_data_t * priv = PIV_DATA(card);
LOG_FUNC_CALLED(card->ctx);
Index: opensc-0.25.1/src/libopensc/pkcs15-cert.c
===================================================================
--- opensc-0.25.1.orig/src/libopensc/pkcs15-cert.c
+++ opensc-0.25.1/src/libopensc/pkcs15-cert.c
@@ -169,7 +169,7 @@ sc_pkcs15_get_name_from_dn(struct sc_con
for (next_ava = rdn, next_ava_len = rdn_len; next_ava_len; ) {
const u8 *ava, *dummy, *oidp;
struct sc_object_id oid;
- size_t ava_len, dummy_len, oid_len;
+ size_t ava_len = 0, dummy_len, oid_len = 0;
/* unwrap the set and point to the next ava */
ava = sc_asn1_skip_tag(ctx, &next_ava, &next_ava_len, SC_ASN1_TAG_SET | SC_ASN1_CONS, &ava_len);
Index: opensc-0.25.1/src/libopensc/pkcs15-sc-hsm.c
===================================================================
--- opensc-0.25.1.orig/src/libopensc/pkcs15-sc-hsm.c
+++ opensc-0.25.1/src/libopensc/pkcs15-sc-hsm.c
@@ -386,7 +386,7 @@ int sc_pkcs15emu_sc_hsm_decode_cvc(sc_pk
struct sc_asn1_entry asn1_cvcert[C_ASN1_CVCERT_SIZE];
struct sc_asn1_entry asn1_cvc_body[C_ASN1_CVC_BODY_SIZE];
struct sc_asn1_entry asn1_cvc_pubkey[C_ASN1_CVC_PUBKEY_SIZE];
- unsigned int cla,tag;
+ unsigned int cla = 0, tag = 0;
size_t taglen;
const u8 *tbuf;
int r;
Index: opensc-0.25.1/src/pkcs15init/profile.c
===================================================================
--- opensc-0.25.1.orig/src/pkcs15init/profile.c
+++ opensc-0.25.1/src/pkcs15init/profile.c
@@ -1809,7 +1809,7 @@ do_pin_storedlength(struct state *cur, i
static int
do_pin_flags(struct state *cur, int argc, char **argv)
{
- unsigned int flags;
+ unsigned int flags = 0;
int i, r;
if (cur->pin->pin.auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)

View File

@ -1,233 +0,0 @@
commit 1d3b410e06d33cfc4c70e8a25386e456cfbd7bd1
Author: Veronika Hanulíková <vhanulik@redhat.com>
Date: Thu Jul 11 15:27:19 2024 +0200
cardos: Fix uninitialized values
Thanks Matteo Marini for report
https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8
fuzz_card/2
Index: opensc-0.25.1/src/libopensc/card-cardos.c
===================================================================
--- opensc-0.25.1.orig/src/libopensc/card-cardos.c
+++ opensc-0.25.1/src/libopensc/card-cardos.c
@@ -94,14 +94,14 @@ static void fixup_transceive_length(cons
static int cardos_match_card(sc_card_t *card)
{
- unsigned char atr[SC_MAX_ATR_SIZE];
+ unsigned char atr[SC_MAX_ATR_SIZE] = {0};
int i;
i = _sc_match_atr(card, cardos_atrs, &card->type);
if (i < 0)
return 0;
- memcpy(atr, card->atr.value, sizeof(atr));
+ memcpy(atr, card->atr.value, card->atr.len);
/* Do not change card type for CIE! */
if (card->type == SC_CARD_TYPE_CARDOS_CIE_V1)
@@ -114,8 +114,8 @@ static int cardos_match_card(sc_card_t *
return 1;
if (card->type == SC_CARD_TYPE_CARDOS_M4_2) {
int rv;
- sc_apdu_t apdu;
- u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
+ sc_apdu_t apdu = {0};
+ u8 rbuf[SC_MAX_APDU_BUFFER_SIZE] = {0};
/* first check some additional ATR bytes */
if ((atr[4] != 0xff && atr[4] != 0x02) ||
(atr[6] != 0x10 && atr[6] != 0x0a) ||
@@ -131,7 +131,7 @@ static int cardos_match_card(sc_card_t *
apdu.lc = 0;
rv = sc_transmit_apdu(card, &apdu);
LOG_TEST_RET(card->ctx, rv, "APDU transmit failed");
- if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00)
+ if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00 || apdu.resplen < 2)
return 0;
if (apdu.resp[0] != atr[10] ||
apdu.resp[1] != atr[11])
Index: opensc-0.25.1/src/libopensc/card-cac1.c
===================================================================
--- opensc-0.25.1.orig/src/libopensc/card-cac1.c
+++ opensc-0.25.1/src/libopensc/card-cac1.c
@@ -92,12 +92,12 @@ static int cac_cac1_get_certificate(sc_c
if (apdu.sw1 != 0x63 || apdu.sw2 < 1) {
/* we've either finished reading, or hit an error, break */
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
- left -= len;
+ left -= apdu.resplen;
break;
}
/* Adjust the lengths */
- left -= len;
- out_ptr += len;
+ left -= apdu.resplen;
+ out_ptr += apdu.resplen;
len = MIN(left, apdu.sw2);
}
if (r < 0) {
Index: opensc-0.25.1/src/libopensc/card-oberthur.c
===================================================================
--- opensc-0.25.1.orig/src/libopensc/card-oberthur.c
+++ opensc-0.25.1/src/libopensc/card-oberthur.c
@@ -148,7 +148,7 @@ auth_select_aid(struct sc_card *card)
{
struct sc_apdu apdu;
unsigned char apdu_resp[SC_MAX_APDU_BUFFER_SIZE];
- struct auth_private_data *data = (struct auth_private_data *) card->drv_data;
+ struct auth_private_data *data = (struct auth_private_data *)card->drv_data;
int rv, ii;
struct sc_path tmp_path;
@@ -165,6 +165,9 @@ auth_select_aid(struct sc_card *card)
rv = sc_transmit_apdu(card, &apdu);
LOG_TEST_RET(card->ctx, rv, "APDU transmit failed");
+ if (apdu.resplen < 20) {
+ LOG_TEST_RET(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED, "Serial number has incorrect length");
+ }
card->serialnr.len = 4;
memcpy(card->serialnr.value, apdu.resp+15, 4);
Index: opensc-0.25.1/src/libopensc/card-gids.c
===================================================================
--- opensc-0.25.1.orig/src/libopensc/card-gids.c
+++ opensc-0.25.1/src/libopensc/card-gids.c
@@ -231,6 +231,7 @@ static int gids_get_DO(sc_card_t* card,
size_t datasize = 0;
const u8* p;
u8 buffer[MAX_GIDS_FILE_SIZE];
+ size_t buffer_len = sizeof(buffer);
SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
sc_log(card->ctx,
@@ -244,14 +245,15 @@ static int gids_get_DO(sc_card_t* card,
apdu.data = data;
apdu.datalen = 04;
apdu.resp = buffer;
- apdu.resplen = sizeof(buffer);
+ apdu.resplen = buffer_len;
apdu.le = 256;
r = sc_transmit_apdu(card, &apdu);
LOG_TEST_RET(card->ctx, r, "gids get data failed");
LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return");
+ buffer_len = apdu.resplen;
- p = sc_asn1_find_tag(card->ctx, buffer, sizeof(buffer), dataObjectIdentifier, &datasize);
+ p = sc_asn1_find_tag(card->ctx, buffer, buffer_len, dataObjectIdentifier, &datasize);
if (!p) {
LOG_FUNC_RETURN(card->ctx, SC_ERROR_FILE_NOT_FOUND);
}
Index: opensc-0.25.1/src/libopensc/asn1.c
===================================================================
--- opensc-0.25.1.orig/src/libopensc/asn1.c
+++ opensc-0.25.1/src/libopensc/asn1.c
@@ -68,7 +68,7 @@ int sc_asn1_read_tag(const u8 ** buf, si
*buf = NULL;
- if (left == 0 || !p)
+ if (left == 0 || !p || buflen == 0)
return SC_ERROR_INVALID_ASN1_OBJECT;
if (*p == 0xff || *p == 0) {
/* end of data reached */
@@ -83,6 +83,8 @@ int sc_asn1_read_tag(const u8 ** buf, si
*/
cla = (*p & SC_ASN1_TAG_CLASS) | (*p & SC_ASN1_TAG_CONSTRUCTED);
tag = *p & SC_ASN1_TAG_PRIMITIVE;
+ if (left < 1)
+ return SC_ERROR_INVALID_ASN1_OBJECT;
p++;
left--;
if (tag == SC_ASN1_TAG_PRIMITIVE) {
Index: opensc-0.25.1/src/libopensc/card-dnie.c
===================================================================
--- opensc-0.25.1.orig/src/libopensc/card-dnie.c
+++ opensc-0.25.1/src/libopensc/card-dnie.c
@@ -1172,12 +1172,16 @@ static int dnie_compose_and_send_apdu(sc
if (file_out) {
/* finally process FCI response */
+ size_t len = apdu.resp[1];
sc_file_free(*file_out);
*file_out = sc_file_new();
if (*file_out == NULL) {
LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
}
- res = card->ops->process_fci(card, *file_out, apdu.resp + 2, apdu.resp[1]);
+ if (apdu.resplen - 2 < len || len < 1) {
+ LOG_FUNC_RETURN(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
+ }
+ res = card->ops->process_fci(card, *file_out, apdu.resp + 2, len);
}
LOG_FUNC_RETURN(ctx, res);
}
@@ -1935,7 +1939,7 @@ static int dnie_process_fci(struct sc_ca
int *op = df_acl;
int n = 0;
sc_context_t *ctx = NULL;
- if ((card == NULL) || (card->ctx == NULL) || (file == NULL))
+ if ((card == NULL) || (card->ctx == NULL) || (file == NULL) || buflen == 0)
return SC_ERROR_INVALID_ARGUMENTS;
ctx = card->ctx;
LOG_FUNC_CALLED(ctx);
Index: opensc-0.25.1/src/libopensc/muscle.c
===================================================================
--- opensc-0.25.1.orig/src/libopensc/muscle.c
+++ opensc-0.25.1/src/libopensc/muscle.c
@@ -111,13 +111,15 @@ int sc_partial_read_object(sc_card_t *c
int msc_read_object(sc_card_t *card, msc_id objectId, int offset, u8 *data, size_t dataLength)
{
- int r;
+ int r = 0;
unsigned int i;
size_t max_read_unit = MSC_MAX_READ;
- for(i = 0; i < dataLength; i += max_read_unit) {
+ for(i = 0; i < dataLength; i += r) {
r = msc_partial_read_object(card, objectId, offset + i, data + i, MIN(dataLength - i, max_read_unit));
LOG_TEST_RET(card->ctx, r, "Error in partial object read");
+ if (r == 0)
+ break;
}
return (int)dataLength;
}
@@ -154,7 +156,7 @@ int msc_create_object(sc_card_t *card, m
ushort2bebytes(buffer + 12, deleteAcl);
r = sc_transmit_apdu(card, &apdu);
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
- if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00)
+ if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00)
return (int)objectSize;
if(apdu.sw1 == 0x9C) {
if(apdu.sw2 == 0x01) {
@@ -170,7 +172,7 @@ int msc_create_object(sc_card_t *card, m
apdu.sw1, apdu.sw2);
}
msc_zero_object(card, objectId, objectSize);
- return (int)objectSize;
+ SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_UNKNOWN_DATA_RECEIVED);
}
/* Update up to MSC_MAX_READ - 9 bytes */
Index: opensc-0.25.1/src/libopensc/card-entersafe.c
===================================================================
--- opensc-0.25.1.orig/src/libopensc/card-entersafe.c
+++ opensc-0.25.1/src/libopensc/card-entersafe.c
@@ -1479,7 +1479,9 @@ static int entersafe_get_serialnr(sc_car
r=entersafe_transmit_apdu(card, &apdu,0,0,0,0);
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
LOG_TEST_RET(card->ctx, sc_check_sw(card,apdu.sw1,apdu.sw2),"EnterSafe get SN failed");
-
+ if (apdu.resplen != 8)
+ LOG_TEST_RET(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED, "Invalid length of SN");
+
card->serialnr.len=serial->len=8;
memcpy(card->serialnr.value,rbuf,8);
memcpy(serial->value,rbuf,8);

View File

@ -1,55 +0,0 @@
commit fdb9e903eb124b6b18a5a9350a26eceb775585bc
Author: Veronika Hanulíková <vhanulik@redhat.com>
Date: Tue Jul 16 14:05:36 2024 +0200
cac: Check return value when selecting AID
Thanks Matteo Marini for report
https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8
fuzz_pkcs11/14
Index: opensc-0.22.0/src/libopensc/card-cac.c
===================================================================
--- opensc-0.22.0.orig/src/libopensc/card-cac.c
+++ opensc-0.22.0/src/libopensc/card-cac.c
@@ -1302,10 +1302,10 @@ static int cac_parse_aid(sc_card_t *card
/* Call without OID set will just select the AID without subsequent
* OID selection, which we need to figure out just now
*/
- cac_select_file_by_type(card, &new_object.path, NULL);
+ r = cac_select_file_by_type(card, &new_object.path, NULL);
+ LOG_TEST_RET(card->ctx, r, "Cannot select AID");
r = cac_get_properties(card, &prop);
- if (r < 0)
- return SC_ERROR_INTERNAL;
+ LOG_TEST_RET(card->ctx, r, "Cannot get CAC properties");
for (i = 0; i < prop.num_objects; i++) {
/* don't fail just because we have more certs than we can support */
Index: opensc-0.22.0/src/libopensc/card-cardos.c
===================================================================
--- opensc-0.22.0.orig/src/libopensc/card-cardos.c
+++ opensc-0.22.0/src/libopensc/card-cardos.c
@@ -1277,7 +1277,7 @@ cardos_lifecycle_get(sc_card_t *card, in
LOG_TEST_RET(card->ctx, r, "Card returned error");
if (apdu.resplen < 1) {
- LOG_TEST_RET(card->ctx, r, "Lifecycle byte not in response");
+ LOG_TEST_RET(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED, "Lifecycle byte not in response");
}
r = SC_SUCCESS;
Index: opensc-0.22.0/src/libopensc/card-jpki.c
===================================================================
--- opensc-0.22.0.orig/src/libopensc/card-jpki.c
+++ opensc-0.22.0/src/libopensc/card-jpki.c
@@ -195,6 +195,8 @@ jpki_select_file(struct sc_card *card,
u8 buf[4];
rc = sc_read_binary(card, 0, buf, 4, 0);
LOG_TEST_RET(card->ctx, rc, "SW Check failed");
+ if (rc < 4)
+ LOG_TEST_RET(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED, "Received data too short");
file = sc_file_new();
if (!file) {
LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);

View File

@ -1,67 +0,0 @@
commit 8632ec172beda894581d67eaa991e519a7874f7d
Author: Veronika Hanulíková <vhanulik@redhat.com>
Date: Wed Jul 17 11:18:52 2024 +0200
pkcs15-tcos: Check return value of serial num conversion
Thanks Matteo Marini for report
https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8
fuzz_pkcs15_encode/21
diff --git a/src/libopensc/pkcs15-tcos.c b/src/libopensc/pkcs15-tcos.c
index 4d02a98ee..2bd275c4f 100644
--- a/src/libopensc/pkcs15-tcos.c
+++ b/src/libopensc/pkcs15-tcos.c
@@ -531,10 +531,15 @@ int sc_pkcs15emu_tcos_init_ex(
/* get the card serial number */
r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serialnr);
if (r < 0) {
- sc_log(ctx, "unable to get ICCSN\n");
+ sc_log(ctx, "unable to get ICCSN");
return SC_ERROR_WRONG_CARD;
}
- sc_bin_to_hex(serialnr.value, serialnr.len , serial, sizeof(serial), 0);
+ r = sc_bin_to_hex(serialnr.value, serialnr.len, serial, sizeof(serial), 0);
+ if (r != SC_SUCCESS) {
+ sc_log(ctx, "serial number invalid");
+ return SC_ERROR_INTERNAL;
+ }
+
serial[19] = '\0';
set_string(&p15card->tokeninfo->serial_number, serial);
commit f9d68660f032ad4d7803431d5fc7577ea8792ac3
Author: Veronika Hanulíková <vhanulik@redhat.com>
Date: Wed Jul 17 14:56:22 2024 +0200
pkcs15-lib: Report transport key error
Thanks Matteo Marini for report
https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8
fuzz_pkcs15init/17, fuzz_pkcs15init/18
diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c
index 6574e8025..943d53e98 100644
--- a/src/pkcs15init/pkcs15-lib.c
+++ b/src/pkcs15init/pkcs15-lib.c
@@ -3831,13 +3831,15 @@ sc_pkcs15init_get_transport_key(struct sc_profile *profile, struct sc_pkcs15_car
if (callbacks.get_key) {
rv = callbacks.get_key(profile, type, reference, defbuf, defsize, pinbuf, pinsize);
LOG_TEST_RET(ctx, rv, "Cannot get key");
- }
- else if (rv >= 0) {
+ } else if (rv >= 0) {
if (*pinsize < defsize)
LOG_TEST_RET(ctx, SC_ERROR_BUFFER_TOO_SMALL, "Get transport key error");
memcpy(pinbuf, data.key_data, data.len);
*pinsize = data.len;
+ } else {
+ /* pinbuf and pinsize were not filled */
+ LOG_TEST_RET(ctx, SC_ERROR_INTERNAL, "Get transport key error");
}
memset(&auth_info, 0, sizeof(auth_info));

View File

@ -1,212 +0,0 @@
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.25.1/src/libopensc/pkcs15-tcos.c
===================================================================
--- opensc-0.25.1.orig/src/libopensc/pkcs15-tcos.c
+++ opensc-0.25.1/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.25.1/src/libopensc/pkcs15-gemsafeV1.c
===================================================================
--- opensc-0.25.1.orig/src/libopensc/pkcs15-gemsafeV1.c
+++ opensc-0.25.1/src/libopensc/pkcs15-gemsafeV1.c
@@ -169,6 +169,7 @@ static int gemsafe_get_cert_len(sc_card_
size_t objlen;
int 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_
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!)
@@ -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, (unsigned)(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.25.1/src/pkcs15init/pkcs15-setcos.c
===================================================================
--- opensc-0.25.1.orig/src/pkcs15init/pkcs15-setcos.c
+++ opensc-0.25.1/src/pkcs15init/pkcs15-setcos.c
@@ -507,6 +507,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,
Index: opensc-0.25.1/src/pkcs15init/pkcs15-sc-hsm.c
===================================================================
--- opensc-0.25.1.orig/src/pkcs15init/pkcs15-sc-hsm.c
+++ opensc-0.25.1/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.25.1/src/libopensc/card-coolkey.c
===================================================================
--- opensc-0.25.1.orig/src/libopensc/card-coolkey.c
+++ opensc-0.25.1/src/libopensc/card-coolkey.c
@@ -1697,6 +1697,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);
@@ -1737,8 +1738,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;
@@ -1758,6 +1757,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];
@@ -1776,7 +1776,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;

View File

@ -1,73 +0,0 @@
commit a1bcc6516f43d570899820d259b71c53f8049168
Author: Veronika Hanulíková <vhanulik@redhat.com>
Date: Thu Jul 18 09:23:20 2024 +0200
pkcs15-starcos: Check length of file to be non-zero
Thanks Matteo Marini for report
https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8
fuzz_pkcs15init/20
Index: opensc-0.25.1/src/pkcs15init/pkcs15-starcos.c
===================================================================
--- opensc-0.25.1.orig/src/pkcs15init/pkcs15-starcos.c
+++ opensc-0.25.1/src/pkcs15init/pkcs15-starcos.c
@@ -670,6 +670,8 @@ static int starcos_write_pukey(sc_profil
return r;
len = tfile->size;
sc_file_free(tfile);
+ if (len == 0)
+ return SC_ERROR_INTERNAL;
buf = malloc(len);
if (!buf)
return SC_ERROR_OUT_OF_MEMORY;
@@ -684,7 +686,7 @@ static int starcos_write_pukey(sc_profil
if (num_keys == 0xff)
num_keys = 0;
/* encode public key */
- keylen = starcos_encode_pukey(rsa, NULL, kinfo);
+ keylen = starcos_encode_pukey(rsa, NULL, kinfo);
if (!keylen) {
free(buf);
return SC_ERROR_INTERNAL;
Index: opensc-0.25.1/src/libopensc/iasecc-sdo.c
===================================================================
--- opensc-0.25.1.orig/src/libopensc/iasecc-sdo.c
+++ opensc-0.25.1/src/libopensc/iasecc-sdo.c
@@ -318,16 +318,26 @@ iasecc_se_parse(struct sc_card *card, un
LOG_FUNC_CALLED(ctx);
+ if (data_len < 1)
+ LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
+
if (*data == IASECC_SDO_TEMPLATE_TAG) {
size_size = iasecc_parse_size(data + 1, data_len - 1, &size);
LOG_TEST_RET(ctx, size_size, "parse error: invalid size data of IASECC_SDO_TEMPLATE");
+ if (data_len - 1 < size)
+ LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
+
+
data += size_size + 1;
data_len = size;
sc_log(ctx,
"IASECC_SDO_TEMPLATE: size %"SC_FORMAT_LEN_SIZE_T"u, size_size %d",
size, size_size);
+ if (data_len < 3)
+ LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
+
if (*data != IASECC_SDO_TAG_HEADER)
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
@@ -759,6 +769,8 @@ iasecc_sdo_parse(struct sc_card *card, u
int rv;
LOG_FUNC_CALLED(ctx);
+ if (data == NULL || data_len < 2)
+ LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
if (*data == IASECC_SDO_TEMPLATE_TAG) {
size_size = iasecc_parse_size(data + 1, data_len - 1, &size);

View File

@ -1,78 +0,0 @@
commit b28a3cef416fcfb92fbb9ea7fd3c71df52c6c9fc
Author: Jakub Jelen <jjelen@redhat.com>
Date: Mon Aug 12 19:02:14 2024 +0200
openpgp: Do not accept non-matching key responses
When generating RSA key pair using PKCS#15 init, the driver could accept
responses relevant to ECC keys, which made further processing in the
pkcs15-init failing/accessing invalid parts of structures.
Thanks oss-fuzz!
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=71010
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Index: opensc-0.22.0/src/libopensc/card-openpgp.c
===================================================================
--- opensc-0.22.0.orig/src/libopensc/card-openpgp.c
+++ opensc-0.22.0/src/libopensc/card-openpgp.c
@@ -2657,14 +2657,21 @@ pgp_calculate_and_store_fingerprint(sc_c
/* update the blob containing fingerprints (00C5) */
sc_log(card->ctx, "Updating fingerprint blob 00C5.");
fpseq_blob = pgp_find_blob(card, 0x00C5);
- if (fpseq_blob == NULL)
- LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot find blob 00C5");
+ if (fpseq_blob == NULL) {
+ r = SC_ERROR_OUT_OF_MEMORY;
+ LOG_TEST_GOTO_ERR(card->ctx, r, "Cannot find blob 00C5");
+ }
+ if (20 * key_info->key_id > fpseq_blob->len) {
+ r = SC_ERROR_OBJECT_NOT_VALID;
+ LOG_TEST_GOTO_ERR(card->ctx, r, "The 00C5 blob is not large enough");
+ }
/* save the fingerprints sequence */
newdata = malloc(fpseq_blob->len);
- if (newdata == NULL)
- LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_OUT_OF_MEMORY,
- "Not enough memory to update fingerprint blob 00C5");
+ if (newdata == NULL) {
+ r = SC_ERROR_OUT_OF_MEMORY;
+ LOG_TEST_GOTO_ERR(card->ctx, r, "Not enough memory to update fingerprint blob 00C5");
+ }
memcpy(newdata, fpseq_blob->data, fpseq_blob->len);
/* move p to the portion holding the fingerprint of the current key */
@@ -2778,6 +2785,9 @@ pgp_parse_and_set_pubkey_output(sc_card_
/* RSA modulus */
if (tag == 0x0081) {
+ if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA) {
+ LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
+ }
if ((BYTES4BITS(key_info->u.rsa.modulus_len) < len) /* modulus_len is in bits */
|| key_info->u.rsa.modulus == NULL) {
@@ -2793,6 +2803,9 @@ pgp_parse_and_set_pubkey_output(sc_card_
}
/* RSA public exponent */
else if (tag == 0x0082) {
+ if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA) {
+ LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
+ }
if ((BYTES4BITS(key_info->u.rsa.exponent_len) < len) /* exponent_len is in bits */
|| key_info->u.rsa.exponent == NULL) {
@@ -2808,6 +2821,10 @@ pgp_parse_and_set_pubkey_output(sc_card_
}
/* ECC public key */
else if (tag == 0x0086) {
+ if (key_info->algorithm != SC_OPENPGP_KEYALGO_ECDSA &&
+ key_info->algorithm != SC_OPENPGP_KEYALGO_ECDH) {
+ LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
+ }
/* set the output data */
/* len is ecpoint length + format byte
* see section 7.2.14 of 3.3.1 specs */

View File

@ -1,3 +1,81 @@
-------------------------------------------------------------------
Thu Nov 14 19:35:35 UTC 2024 - Martin Hauke <mardnh@gmx.de>
- Update to version 0.26.0
Security
* CVE-2024-45615: Usage of uninitialized values in libopensc#
and pkcs15init (#3225).
* CVE-2024-45616: Uninitialized values after incorrect check or
usage of APDU response values in libopensc (#3225)
* CVE-2024-45617: Uninitialized values after incorrect or missing
checking return values of functions in libopensc (#3225)
* CVE-2024-45618: Uninitialized values after incorrect or missing
checking return values of functions in pkcs15init (#3225)
* CVE-2024-45619: Incorrect handling length of buffers or files
in libopensc (#3225)
* CVE-2024-45620: Incorrect handling of the length of buffers or
files in pkcs15init (#3225)
* CVE-2024-8443: Heap buffer overflow in OpenPGP driver when
generating key (#3219)
General improvements
* Fix reselection of DF after error in PKCS#15 layer (#3067)
* Unify OpenSSL logging throughout code (#2922)
* Extend the p11test to support kryoptic (#3141)
* Fix for error in PCSC reconnection (#3150)
* Fixed various issues reported by OSS-Fuzz and Coverity in
drivers, PKCS#11 and PKCS#15 layer
PKCS#15
* Documentation for PKCS#15 profile files (#3132)
minidriver
* Support PinCacheAlwaysPrompt usable for PIV cards (#3167)
pkcs11-tool
* Show URI when listing token information (#3125) and objects
* Do not limit size of objects to 5000 bytes (#3174)
* Add support for AES CMAC (#3184)
* Add support for AES GCM encryption (#3195)
* Add support for RSA OAEP encryption (#3175)
* Add support for HKDF (#3193)
* Implement better support for wrapping and unwrapping (#3198)
* Add support for EdDSA sign and verify (#2979)
pkcs15-crypt
* Fix PKCS#1 encoding function to correctly detect padding type
piv-tool
* Fix RSA key generation (#3158)
* Avoid possible state change when matching unknown card (#3112)
sc-hsm-tool
* Cleanse buffer with plaintext key share (#3226)
pkcs11-register
* Fix pkcs11-register defaults on macOS and Windows (#3053)
IDPrime
* Fix identification of IDPrime 840 cards (#3146)
* Fix container mapping for IDPrime 940 cards (#3220)
* Reorder ATRs for matching cards (#3154)
OpenPGP
* Fix state tracking after erasing card (#3024)
Belpic
* Disable Applet V1.8 (#3109)
MICARDO
* Deactivate driver (#3152)
SmartCard-HSM
* Fix signing with secp521r1 signature (#3157)
eOI
* Set model via sc_card_ctl function (#3189)
Rutoken
* increase the minimum PIN size to support Rutoken ECP BIO.
JPKI
* Adjust parameters for public key in PKCS#15 emulator (#3182)
D-Trust
* Add support for ECDSA signatures and ECDH key agreement for
D-Trust Signatures Cards 4.1/4.4 (#3240, #3248)
- Drop patches (changes now in upstream):
* opensc-CVE-2024-45615.patch
* opensc-CVE-2024-45616.patch
* opensc-CVE-2024-45617.patch
* opensc-CVE-2024-45618.patch
* opensc-CVE-2024-45619.patch
* opensc-CVE-2024-45620.patch
* opensc-CVE-2024-8443.patch
-------------------------------------------------------------------
Tue Oct 1 06:30:06 UTC 2024 - Angel Yankov <angel.yankov@suse.com>

View File

@ -16,10 +16,10 @@
#
%define sover 11
%define sover 12
%define completionsdir %(pkg-config --variable completionsdir bash-completion)
Name: opensc
Version: 0.25.1
Version: 0.26.0
Release: 0
Summary: Smart Card Utilities
License: LGPL-2.1-or-later
@ -33,19 +33,6 @@ Source2: %{name}-rpmlintrc
Source3: opensc.module
Patch0: opensc-gcc11.patch
Patch1: opensc-docbook-xsl-fix.patch
Patch2: opensc-CVE-2024-8443.patch
# PATCH-FIX-UPSTREAM: bsc#1230071 CVE-2024-45615: opensc: pkcs15init: Usage of uninitialized values in libopensc and pkcs15init
Patch3: opensc-CVE-2024-45615.patch
# PATCH-FIX-UPSTREAM: bsc#1230072 CVE-2024-45616: opensc: Uninitialized values after incorrect check or usage of APDU response values in libopensc
Patch4: opensc-CVE-2024-45616.patch
# PATCH-FIX-UPSTREAM: bsc#1230073 CVE-2024-45617: opensc: Uninitialized values after incorrect or missing checking return values of functions in libopensc
Patch5: opensc-CVE-2024-45617.patch
# PATCH-FIX-UPSTREAM: bsc#1230074 CVE-2024-45618: opensc: Uninitialized values after incorrect or missing checking return values of functions in pkcs15init
Patch6: opensc-CVE-2024-45618.patch
# PATCH-FIX-UPSTREAM: bsc#1230075 CVE-2024-45619: opensc: Incorrect handling length of buffers or files in libopensc
Patch7: opensc-CVE-2024-45619.patch
# PATCH-FIX-UPSTREAM: bsc#1230076 CVE-2024-45620: opensc: Incorrect handling of the length of buffers or files in pkcs15init
Patch8: opensc-CVE-2024-45620.patch
BuildRequires: automake
BuildRequires: docbook-xsl-stylesheets
BuildRequires: libxslt