From 58d3215b4aa08ba9b72af593a3edd6ee447fb6f7b8c971a42a3e9b2c99942745 Mon Sep 17 00:00:00 2001 From: Otto Hollmann Date: Tue, 10 Oct 2023 12:49:01 +0000 Subject: [PATCH] Accepting request 1116477 from home:ohollmann:branches:security:chipcard - Security Fix: [CVE-2023-40661, bsc#1215761] * opensc: multiple memory issues with pkcs15-init (enrollment tool) * Add patches: - opensc-CVE-2023-40661-1of12.patch - opensc-CVE-2023-40661-2of12.patch - opensc-CVE-2023-40661-3of12.patch - opensc-CVE-2023-40661-4of12.patch - opensc-CVE-2023-40661-5of12.patch - opensc-CVE-2023-40661-6of12.patch - opensc-CVE-2023-40661-7of12.patch - opensc-CVE-2023-40661-8of12.patch - opensc-CVE-2023-40661-9of12.patch - opensc-CVE-2023-40661-10of12.patch - opensc-CVE-2023-40661-11of12.patch - opensc-CVE-2023-40661-12of12.patch - Security Fix: [CVE-2023-4535, bsc#1215763] * Add patches: - opensc-CVE-2023-4535.patch - opensc-NULL_pointer_fix.patch - Security Fix: [CVE-2023-40660, bsc#1215762] * opensc: PIN bypass when card tracks its own login state * Add patches: - opensc-CVE-2023-40660-1of2.patch - opensc-CVE-2023-40660-2of2.patch OBS-URL: https://build.opensuse.org/request/show/1116477 OBS-URL: https://build.opensuse.org/package/show/security:chipcard/opensc?expand=0&rev=75 --- opensc-CVE-2023-40660-1of2.patch | 50 +++ opensc-CVE-2023-40660-2of2.patch | 513 +++++++++++++++++++++++++++ opensc-CVE-2023-40661-10of12.patch | 25 ++ opensc-CVE-2023-40661-11of12.patch | 38 ++ opensc-CVE-2023-40661-12of12.patch | 26 ++ opensc-CVE-2023-40661-1of12.patch | 23 ++ opensc-CVE-2023-40661-2of12.patch | 25 ++ opensc-CVE-2023-40661-3of12.patch | 37 ++ opensc-CVE-2023-40661-4of12.patch | 546 +++++++++++++++++++++++++++++ opensc-CVE-2023-40661-5of12.patch | 61 ++++ opensc-CVE-2023-40661-6of12.patch | 25 ++ opensc-CVE-2023-40661-7of12.patch | 27 ++ opensc-CVE-2023-40661-8of12.patch | 29 ++ opensc-CVE-2023-40661-9of12.patch | 27 ++ opensc-CVE-2023-4535.patch | 39 +++ opensc-NULL_pointer_fix.patch | 54 +++ opensc.changes | 36 ++ opensc.spec | 19 + 18 files changed, 1600 insertions(+) create mode 100644 opensc-CVE-2023-40660-1of2.patch create mode 100644 opensc-CVE-2023-40660-2of2.patch create mode 100644 opensc-CVE-2023-40661-10of12.patch create mode 100644 opensc-CVE-2023-40661-11of12.patch create mode 100644 opensc-CVE-2023-40661-12of12.patch create mode 100644 opensc-CVE-2023-40661-1of12.patch create mode 100644 opensc-CVE-2023-40661-2of12.patch create mode 100644 opensc-CVE-2023-40661-3of12.patch create mode 100644 opensc-CVE-2023-40661-4of12.patch create mode 100644 opensc-CVE-2023-40661-5of12.patch create mode 100644 opensc-CVE-2023-40661-6of12.patch create mode 100644 opensc-CVE-2023-40661-7of12.patch create mode 100644 opensc-CVE-2023-40661-8of12.patch create mode 100644 opensc-CVE-2023-40661-9of12.patch create mode 100644 opensc-CVE-2023-4535.patch create mode 100644 opensc-NULL_pointer_fix.patch diff --git a/opensc-CVE-2023-40660-1of2.patch b/opensc-CVE-2023-40660-1of2.patch new file mode 100644 index 0000000..1b72500 --- /dev/null +++ b/opensc-CVE-2023-40660-1of2.patch @@ -0,0 +1,50 @@ +From 74ddc3636db18ae78de62922a74bfdefae015c76 Mon Sep 17 00:00:00 2001 +From: Frank Morgner +Date: Wed, 21 Jun 2023 12:27:23 +0200 +Subject: [PATCH] Fixed PIN authentication bypass + +If two processes are accessing a token, then one process may leave the +card usable with an authenticated PIN so that a key may sign/decrypt any +data. This is especially the case if the token does not support a way of +resetting the authentication status (logout). + +We have some tracking of the authentication status in software via +PKCS#11, Minidriver (os-wise) and CryptoTokenKit, which is why a +PIN-prompt will appear even though the card may technically be unlocked +as described in the above example. However, before this change, an empty +PIN was not verified (likely yielding an error during PIN-verification), +but it was just checked whether the PIN is authenticated. This defeats +the purpose of the PIN verification, because an empty PIN is not the +correct one. Especially during OS Logon, we don't want that kind of +shortcut, but we want the user to verify the correct PIN (even though +the token was left unattended and authentication at the computer). + +This essentially reverts commit e6f7373ef066cfab6e3162e8b5f692683db23864. +--- + src/libopensc/pkcs15-pin.c | 13 ------------- + 1 file changed, 13 deletions(-) + +diff --git a/src/libopensc/pkcs15-pin.c b/src/libopensc/pkcs15-pin.c +index 48e16fdc1c..2402675316 100644 +--- a/src/libopensc/pkcs15-pin.c ++++ b/src/libopensc/pkcs15-pin.c +@@ -307,19 +307,6 @@ sc_pkcs15_verify_pin(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *pi + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_PIN_REFERENCE); + auth_info = (struct sc_pkcs15_auth_info *)pin_obj->data; + +- /* +- * if pin cache is disabled, we can get here with no PIN data. +- * in this case, to avoid error or unnecessary pin prompting on pinpad, +- * check if the PIN has been already verified and the access condition +- * is still open on card. +- */ +- if (pinlen == 0) { +- r = sc_pkcs15_get_pin_info(p15card, pin_obj); +- +- if (r == SC_SUCCESS && auth_info->logged_in == SC_PIN_STATE_LOGGED_IN) +- LOG_FUNC_RETURN(ctx, r); +- } +- + r = _validate_pin(p15card, auth_info, pinlen); + + if (r) diff --git a/opensc-CVE-2023-40660-2of2.patch b/opensc-CVE-2023-40660-2of2.patch new file mode 100644 index 0000000..dbc72e8 --- /dev/null +++ b/opensc-CVE-2023-40660-2of2.patch @@ -0,0 +1,513 @@ +From d7fadae950f6d33b32f979759c06ab78a3475c22 Mon Sep 17 00:00:00 2001 +From: Frank Morgner +Date: Wed, 21 Jun 2023 13:49:40 +0200 +Subject: [PATCH 01/15] PIV: implemented logout + +--- + src/libopensc/card-asepcos.c | 15 +++++++++++++ + src/libopensc/card-authentic.c | 11 ++++++++++ + src/libopensc/card-cac.c | 10 ++++++--- + src/libopensc/card-cac1.c | 10 ++++++--- + src/libopensc/card-coolkey.c | 3 -- + src/libopensc/card-edo.c | 7 ++++++ + src/libopensc/card-epass2003.c | 18 ++++++++++++++++ + src/libopensc/card-esteid2018.c | 5 ++++ + src/libopensc/card-gemsafeV1.c | 8 +++++++ + src/libopensc/card-isoApplet.c | 8 +++++++ + src/libopensc/card-jpki.c | 6 +++++ + src/libopensc/card-mcrd.c | 10 +++++++++ + src/libopensc/card-muscle.c | 18 ++++++++++++---- + src/libopensc/card-piv.c | 20 ++++++++++-------- + src/libopensc/card-starcos.c | 11 ---------- + src/libopensc/card-westcos.c | 44 ++++++++++++++++++++++++---------------- + 16 files changed, 155 insertions(+), 49 deletions(-) + +--- a/src/libopensc/card-asepcos.c ++++ b/src/libopensc/card-asepcos.c +@@ -1050,6 +1050,20 @@ static int asepcos_card_reader_lock_obta + LOG_FUNC_RETURN(card->ctx, r); + } + ++static int asepcos_logout(sc_card_t *card) ++{ ++ int r = SC_ERROR_NOT_SUPPORTED; ++ ++ SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); ++ ++ if (card->type == SC_CARD_TYPE_ASEPCOS_JAVA) { ++ /* in case of a Java card try to select the ASEPCOS applet */ ++ r = asepcos_select_asepcos_applet(card); ++ } ++ ++ LOG_FUNC_RETURN(card->ctx, r); ++} ++ + static struct sc_card_driver * sc_get_driver(void) + { + if (iso_ops == NULL) +@@ -1066,6 +1080,7 @@ static struct sc_card_driver * sc_get_dr + asepcos_ops.list_files = asepcos_list_files; + asepcos_ops.card_ctl = asepcos_card_ctl; + asepcos_ops.pin_cmd = asepcos_pin_cmd; ++ asepcos_ops.logout = asepcos_logout; + asepcos_ops.card_reader_lock_obtained = asepcos_card_reader_lock_obtained; + + return &asepcos_drv; +--- a/src/libopensc/card-authentic.c ++++ b/src/libopensc/card-authentic.c +@@ -2311,6 +2311,17 @@ authentic_sm_get_wrapped_apdu(struct sc_ + } + #endif + ++int authentic_logout(sc_card_t *card) ++{ ++ int r = SC_ERROR_NOT_SUPPORTED; ++ ++ if (card->type == SC_CARD_TYPE_OBERTHUR_AUTHENTIC_3_2) { ++ r = authentic_select_aid(card, aid_AuthentIC_3_2, sizeof(aid_AuthentIC_3_2), NULL, NULL); ++ } ++ ++ return r; ++} ++ + static struct sc_card_driver * + sc_get_driver(void) + { +--- a/src/libopensc/card-cac.c ++++ b/src/libopensc/card-cac.c +@@ -1831,9 +1831,6 @@ static int cac_match_card(sc_card_t *car + { + int r; + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); +- /* Since we send an APDU, the card's logout function may be called... +- * however it may be in dirty memory */ +- card->ops->logout = NULL; + + r = cac_find_and_initialize(card, 0); + return (r == SC_SUCCESS); /* never match */ +@@ -1862,6 +1859,12 @@ static int cac_init(sc_card_t *card) + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + } + ++static int cac_logout(sc_card_t *card) ++{ ++ int index; ++ return cac_find_first_pki_applet(card, &index); ++} ++ + static int cac_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) + { + /* CAC, like PIV needs Extra validation of (new) PIN during +@@ -1933,6 +1936,7 @@ static struct sc_card_driver * sc_get_dr + cac_ops.decipher = cac_decipher; + cac_ops.card_ctl = cac_card_ctl; + cac_ops.pin_cmd = cac_pin_cmd; ++ cac_ops.logout = cac_logout; + + return &cac_drv; + } +--- a/src/libopensc/card-cac1.c ++++ b/src/libopensc/card-cac1.c +@@ -498,9 +498,6 @@ static int cac_match_card(sc_card_t *car + { + int r; + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); +- /* Since we send an APDU, the card's logout function may be called... +- * however it may be in dirty memory */ +- card->ops->logout = NULL; + + r = cac_find_and_initialize(card, 0); + return (r == SC_SUCCESS); /* never match */ +@@ -529,6 +526,12 @@ static int cac_init(sc_card_t *card) + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + } + ++static int cac_logout(sc_card_t *card) ++{ ++ int index; ++ return cac_find_first_pki_applet(card, &index); ++} ++ + static struct sc_card_operations cac_ops; + + static struct sc_card_driver cac1_drv = { +@@ -550,6 +553,7 @@ static struct sc_card_driver * sc_get_dr + + cac_ops.select_file = cac_select_file; /* need to record object type */ + cac_ops.read_binary = cac_read_binary; ++ cac_ops.logout = cac_logout; + + return &cac1_drv; + } +--- a/src/libopensc/card-coolkey.c ++++ b/src/libopensc/card-coolkey.c +@@ -2264,9 +2264,6 @@ static int coolkey_match_card(sc_card_t + int r; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); +- /* Since we send an APDU, the card's logout function may be called... +- * however it may be in dirty memory */ +- card->ops->logout = NULL; + + r = coolkey_select_applet(card); + if (r == SC_SUCCESS) { +--- a/src/libopensc/card-edo.c ++++ b/src/libopensc/card-edo.c +@@ -302,6 +302,12 @@ static int edo_init(sc_card_t* card) { + } + + ++static int edo_logout(sc_card_t* card) { ++ sc_sm_stop(card); ++ return edo_unlock(card); ++} ++ ++ + struct sc_card_driver* sc_get_edo_driver(void) { + edo_ops = *sc_get_iso7816_driver()->ops; + edo_ops.match_card = edo_match_card; +@@ -309,6 +315,7 @@ struct sc_card_driver* sc_get_edo_driver + edo_ops.select_file = edo_select_file; + edo_ops.set_security_env = edo_set_security_env; + edo_ops.compute_signature = edo_compute_signature; ++ edo_ops.logout = edo_logout; + + return &edo_drv; + } +--- a/src/libopensc/card-epass2003.c ++++ b/src/libopensc/card-epass2003.c +@@ -3278,6 +3278,23 @@ epass2003_pin_cmd(struct sc_card *card, + return r; + } + ++static int ++epass2003_logout(struct sc_card *card) ++{ ++ epass2003_exdata *exdata = NULL; ++ ++ if (!card->drv_data) ++ return SC_ERROR_INVALID_ARGUMENTS; ++ ++ exdata = (epass2003_exdata *)card->drv_data; ++ if (exdata->sm) { ++ sc_sm_stop(card); ++ return epass2003_refresh(card); ++ } ++ ++ return SC_ERROR_NOT_SUPPORTED; ++} ++ + static struct sc_card_driver *sc_get_driver(void) + { + struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); +@@ -3307,6 +3324,7 @@ static struct sc_card_driver *sc_get_dri + epass2003_ops.pin_cmd = epass2003_pin_cmd; + epass2003_ops.check_sw = epass2003_check_sw; + epass2003_ops.get_challenge = epass2003_get_challenge; ++ epass2003_ops.logout = epass2003_logout; + return &epass2003_drv; + } + +--- a/src/libopensc/card-esteid2018.c ++++ b/src/libopensc/card-esteid2018.c +@@ -306,6 +306,10 @@ static int esteid_finish(sc_card_t *card + return 0; + } + ++static int esteid_logout(sc_card_t *card) { ++ return gp_select_aid(card, &IASECC_AID); ++} ++ + struct sc_card_driver *sc_get_esteid2018_driver(void) { + struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); + +@@ -323,6 +327,7 @@ struct sc_card_driver *sc_get_esteid2018 + esteid_ops.set_security_env = esteid_set_security_env; + esteid_ops.compute_signature = esteid_compute_signature; + esteid_ops.pin_cmd = esteid_pin_cmd; ++ esteid_ops.logout = esteid_logout; + + return &esteid2018_driver; + } +--- a/src/libopensc/card-gemsafeV1.c ++++ b/src/libopensc/card-gemsafeV1.c +@@ -582,6 +582,13 @@ static int gemsafe_card_reader_lock_obta + LOG_FUNC_RETURN(card->ctx, r); + } + ++static int gemsafe_logout(sc_card_t *card) ++{ ++ gemsafe_exdata *exdata = (gemsafe_exdata *)card->drv_data; ++ ++ return gp_select_applet(card, exdata->aid, exdata->aid_len); ++} ++ + static struct sc_card_driver *sc_get_driver(void) + { + struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); +@@ -602,6 +609,7 @@ static struct sc_card_driver *sc_get_dri + gemsafe_ops.process_fci = gemsafe_process_fci; + gemsafe_ops.pin_cmd = iso_ops->pin_cmd; + gemsafe_ops.card_reader_lock_obtained = gemsafe_card_reader_lock_obtained; ++ gemsafe_ops.logout = gemsafe_logout; + + return &gemsafe_drv; + } +--- a/src/libopensc/card-isoApplet.c ++++ b/src/libopensc/card-isoApplet.c +@@ -1244,6 +1244,13 @@ static int isoApplet_card_reader_lock_ob + LOG_FUNC_RETURN(card->ctx, r); + } + ++static int isoApplet_logout(sc_card_t *card) ++{ ++ size_t rlen = SC_MAX_APDU_BUFFER_SIZE; ++ u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; ++ return isoApplet_select_applet(card, isoApplet_aid, sizeof(isoApplet_aid), rbuf, &rlen); ++} ++ + static struct sc_card_driver *sc_get_driver(void) + { + sc_card_driver_t *iso_drv = sc_get_iso7816_driver(); +@@ -1267,6 +1274,7 @@ static struct sc_card_driver *sc_get_dri + isoApplet_ops.compute_signature = isoApplet_compute_signature; + isoApplet_ops.get_challenge = isoApplet_get_challenge; + isoApplet_ops.card_reader_lock_obtained = isoApplet_card_reader_lock_obtained; ++ isoApplet_ops.logout = isoApplet_logout; + + /* unsupported functions */ + isoApplet_ops.write_binary = NULL; +--- a/src/libopensc/card-jpki.c ++++ b/src/libopensc/card-jpki.c +@@ -361,6 +361,11 @@ static int jpki_card_reader_lock_obtaine + LOG_FUNC_RETURN(card->ctx, r); + } + ++static int jpki_logout(sc_card_t *card) ++{ ++ return jpki_select_ap(card); ++} ++ + static struct sc_card_driver * + sc_get_driver(void) + { +@@ -375,6 +380,7 @@ sc_get_driver(void) + jpki_ops.set_security_env = jpki_set_security_env; + jpki_ops.compute_signature = jpki_compute_signature; + jpki_ops.card_reader_lock_obtained = jpki_card_reader_lock_obtained; ++ jpki_ops.logout = jpki_logout; + + return &jpki_drv; + } +--- a/src/libopensc/card-mcrd.c ++++ b/src/libopensc/card-mcrd.c +@@ -1174,6 +1174,15 @@ static int mcrd_pin_cmd(sc_card_t * card + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, iso_ops->pin_cmd(card, data, tries_left)); + } + ++static int mcrd_logout(sc_card_t * card) ++{ ++ if (card->type == SC_CARD_TYPE_MCRD_ESTEID_V30) { ++ return gp_select_aid(card, &EstEID_v35_AID); ++ } else { ++ return SC_ERROR_NOT_SUPPORTED; ++ } ++} ++ + /* Driver binding */ + static struct sc_card_driver *sc_get_driver(void) + { +@@ -1190,6 +1199,7 @@ static struct sc_card_driver *sc_get_dri + mcrd_ops.compute_signature = mcrd_compute_signature; + mcrd_ops.decipher = mcrd_decipher; + mcrd_ops.pin_cmd = mcrd_pin_cmd; ++ mcrd_ops.logout = mcrd_logout; + + return &mcrd_drv; + } +--- a/src/libopensc/card-muscle.c ++++ b/src/libopensc/card-muscle.c +@@ -81,10 +81,6 @@ static int muscle_match_card(sc_card_t * + u8 response[64]; + int r; + +- /* Since we send an APDU, the card's logout function may be called... +- * however it's not always properly nulled out... */ +- card->ops->logout = NULL; +- + if (msc_select_applet(card, muscleAppletId, sizeof muscleAppletId) == 1) { + /* Muscle applet is present, check the protocol version to be sure */ + sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0x3C, 0x00, 0x00); +@@ -853,6 +849,19 @@ static int muscle_card_reader_lock_obtai + LOG_FUNC_RETURN(card->ctx, r); + } + ++static int muscle_logout(sc_card_t *card) ++{ ++ int r = SC_ERROR_NOT_SUPPORTED; ++ ++ SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); ++ ++ if (msc_select_applet(card, muscleAppletId, sizeof muscleAppletId) == 1) { ++ r = SC_SUCCESS; ++ } ++ ++ LOG_FUNC_RETURN(card->ctx, r); ++} ++ + + static struct sc_card_driver * sc_get_driver(void) + { +@@ -881,6 +890,7 @@ static struct sc_card_driver * sc_get_dr + muscle_ops.delete_file = muscle_delete_file; + muscle_ops.list_files = muscle_list_files; + muscle_ops.card_reader_lock_obtained = muscle_card_reader_lock_obtained; ++ muscle_ops.logout = muscle_logout; + + return &muscle_drv; + } +--- a/src/libopensc/card-piv.c ++++ b/src/libopensc/card-piv.c +@@ -2183,11 +2183,11 @@ static int piv_is_object_present(sc_card + * or the global pin for the card 0x00. Look at Discovery object to get this. + * called by pkcs15-piv.c via cardctl when setting up the pins. + */ +-static int piv_get_pin_preference(sc_card_t *card, int *ptr) ++static int piv_get_pin_preference(sc_card_t *card, int *pin_ref) + { + piv_private_data_t * priv = PIV_DATA(card); + +- *ptr = priv->pin_preference; ++ *pin_ref = priv->pin_preference; + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + } + +@@ -3082,10 +3082,6 @@ static int piv_match_card_continued(sc_c + piv_private_data_t *priv = NULL; + int saved_type = card->type; + +- /* Since we send an APDU, the card's logout function may be called... +- * however it may be in dirty memory */ +- card->ops->logout = NULL; +- + /* piv_match_card may be called with card->type, set by opensc.conf */ + /* user provide card type must be one we know */ + switch (card->type) { +@@ -3747,12 +3743,18 @@ piv_pin_cmd(sc_card_t *card, struct sc_p + + static int piv_logout(sc_card_t *card) + { +- int r = SC_ERROR_NOT_SUPPORTED; /* TODO Some PIV cards may support a logout */ +- /* piv_private_data_t * priv = PIV_DATA(card); */ ++ int r = SC_ERROR_NOT_SUPPORTED; ++ piv_private_data_t * priv = PIV_DATA(card); + + LOG_FUNC_CALLED(card->ctx); + +- /* TODO 800-73-3 does not define a logout, 800-73-4 does */ ++ if (priv) { ++ /* logout defined since 800-73-4 */ ++ r = iso7816_logout(card, priv->pin_preference); ++ if (r == SC_SUCCESS) { ++ priv->logged_in = SC_PIN_STATE_LOGGED_OUT; ++ } ++ } + + LOG_FUNC_RETURN(card->ctx, r); + } +--- a/src/libopensc/card-starcos.c ++++ b/src/libopensc/card-starcos.c +@@ -2150,18 +2150,9 @@ static int starcos_card_ctl(sc_card_t *c + } + } + +-/** +- * starcos_logout_v3_x() +- * StarCOS 3.x cards will not clear the security status by selecting MF. +- * Returning NOT_SUPPORTED would cause card reset, effectively invalidating +- * the security status. +- */ + static int starcos_logout_v3_x(sc_card_t *card) + { +- int r = SC_ERROR_NOT_SUPPORTED; +- SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL); +- +- SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); ++ return SC_ERROR_NOT_SUPPORTED; + } + + static int starcos_logout(sc_card_t *card) +--- a/src/libopensc/card-westcos.c ++++ b/src/libopensc/card-westcos.c +@@ -166,6 +166,26 @@ static int westcos_finish(sc_card_t * ca + return 0; + } + ++static int select_westcos_applet(sc_card_t *card) ++{ ++ int r; ++ sc_apdu_t apdu; ++ u8 aid[] = { ++ 0xA0, 0x00, 0xCE, 0x00, 0x07, 0x01 ++ }; ++ sc_format_apdu(card, &apdu, ++ SC_APDU_CASE_3_SHORT, 0xA4, 0x04, ++ 0); ++ apdu.cla = 0x00; ++ apdu.lc = sizeof(aid); ++ apdu.datalen = sizeof(aid); ++ apdu.data = aid; ++ r = sc_transmit_apdu(card, &apdu); ++ if (r) ++ return r; ++ return sc_check_sw(card, apdu.sw1, apdu.sw2); ++} ++ + static int westcos_match_card(sc_card_t * card) + { + int i; +@@ -176,23 +196,7 @@ static int westcos_match_card(sc_card_t + + /* JAVACARD, look for westcos applet */ + if (i == 1) { +- int r; +- sc_apdu_t apdu; +- u8 aid[] = { +- 0xA0, 0x00, 0xCE, 0x00, 0x07, 0x01 +- }; +- sc_format_apdu(card, &apdu, +- SC_APDU_CASE_3_SHORT, 0xA4, 0x04, +- 0); +- apdu.cla = 0x00; +- apdu.lc = sizeof(aid); +- apdu.datalen = sizeof(aid); +- apdu.data = aid; +- r = sc_transmit_apdu(card, &apdu); +- if (r) +- return 0; +- r = sc_check_sw(card, apdu.sw1, apdu.sw2); +- if (r) ++ if (select_westcos_applet(card)) + return 0; + } + +@@ -1257,6 +1261,11 @@ static int westcos_decipher(sc_card_t *c + return westcos_sign_decipher(1, card, crgram, crgram_len, out, outlen); + } + ++static int westcos_logout(sc_card_t *card) ++{ ++ return select_westcos_applet(card); ++} ++ + struct sc_card_driver *sc_get_westcos_driver(void) + { + if (iso_ops == NULL) +@@ -1288,6 +1297,7 @@ struct sc_card_driver *sc_get_westcos_dr + westcos_ops.process_fci = westcos_process_fci; + westcos_ops.construct_fci = NULL; + westcos_ops.pin_cmd = westcos_pin_cmd; ++ westcos_ops.logout = westcos_logout; + + return &westcos_drv; + } diff --git a/opensc-CVE-2023-40661-10of12.patch b/opensc-CVE-2023-40661-10of12.patch new file mode 100644 index 0000000..4e57b18 --- /dev/null +++ b/opensc-CVE-2023-40661-10of12.patch @@ -0,0 +1,25 @@ +From 440ca666eff10cc7011901252d20f3fc4ea23651 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Thu, 17 Aug 2023 13:41:36 +0200 +Subject: [PATCH] setcos: Avoid buffer underflow + +Thanks oss-fuzz + +https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60672 +--- + src/pkcs15init/pkcs15-setcos.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/src/pkcs15init/pkcs15-setcos.c ++++ b/src/pkcs15init/pkcs15-setcos.c +@@ -349,6 +349,10 @@ setcos_create_key(sc_profile_t *profile, + + /* Replace the path of instantiated key template by the path from the object data. */ + memcpy(&file->path, &key_info->path, sizeof(file->path)); ++ if (file->path.len < 2) { ++ sc_file_free(file); ++ LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Invalid path"); ++ } + file->id = file->path.value[file->path.len - 2] * 0x100 + + file->path.value[file->path.len - 1]; + diff --git a/opensc-CVE-2023-40661-11of12.patch b/opensc-CVE-2023-40661-11of12.patch new file mode 100644 index 0000000..6fb03a2 --- /dev/null +++ b/opensc-CVE-2023-40661-11of12.patch @@ -0,0 +1,38 @@ +From 245efe608d083fd4e4ec96793fdefd218e26fde7 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Thu, 17 Aug 2023 13:54:42 +0200 +Subject: [PATCH] pkcs15: Avoid buffer overflow when getting last update + +Thanks oss-fuzz + +https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60769 +--- + src/libopensc/pkcs15.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/src/libopensc/pkcs15.c ++++ b/src/libopensc/pkcs15.c +@@ -528,7 +528,7 @@ sc_pkcs15_get_lastupdate(struct sc_pkcs1 + struct sc_context *ctx = p15card->card->ctx; + struct sc_file *file = NULL; + struct sc_asn1_entry asn1_last_update[C_ASN1_LAST_UPDATE_SIZE]; +- unsigned char *content, last_update[32]; ++ unsigned char *content, last_update[32] = {0}; + size_t lupdate_len = sizeof(last_update) - 1; + int r, content_len; + size_t size; +@@ -564,9 +564,11 @@ sc_pkcs15_get_lastupdate(struct sc_pkcs1 + if (r < 0) + return NULL; + +- p15card->tokeninfo->last_update.gtime = strdup((char *)last_update); +- if (!p15card->tokeninfo->last_update.gtime) +- return NULL; ++ if (asn1_last_update[0].flags & SC_ASN1_PRESENT) { ++ p15card->tokeninfo->last_update.gtime = strdup((char *)last_update); ++ if (!p15card->tokeninfo->last_update.gtime) ++ return NULL; ++ } + done: + sc_log(ctx, "lastUpdate.gtime '%s'", p15card->tokeninfo->last_update.gtime); + return p15card->tokeninfo->last_update.gtime; diff --git a/opensc-CVE-2023-40661-12of12.patch b/opensc-CVE-2023-40661-12of12.patch new file mode 100644 index 0000000..1c8db8e --- /dev/null +++ b/opensc-CVE-2023-40661-12of12.patch @@ -0,0 +1,26 @@ +From 41d61da8481582e12710b5858f8b635e0a71ab5e Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Wed, 20 Sep 2023 10:13:57 +0200 +Subject: [PATCH] oberthur: Avoid buffer overflow + +Thanks oss-fuzz + +https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60650 +--- + src/pkcs15init/pkcs15-oberthur.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/pkcs15init/pkcs15-oberthur.c b/src/pkcs15init/pkcs15-oberthur.c +index ad2cabd530..c441ab1e76 100644 +--- a/src/pkcs15init/pkcs15-oberthur.c ++++ b/src/pkcs15init/pkcs15-oberthur.c +@@ -715,6 +715,9 @@ cosm_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, + if (object->type != SC_PKCS15_TYPE_PRKEY_RSA) + LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Create key failed: RSA only supported"); + ++ if (key_info->path.len < 2) ++ LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_VALID, "The path needs to be at least to bytes long"); ++ + sc_log(ctx, "create private key ID:%s", sc_pkcs15_print_id(&key_info->id)); + /* Here, the path of private key file should be defined. + * Nevertheless, we need to instantiate private key to get the ACLs. */ diff --git a/opensc-CVE-2023-40661-1of12.patch b/opensc-CVE-2023-40661-1of12.patch new file mode 100644 index 0000000..1539d04 --- /dev/null +++ b/opensc-CVE-2023-40661-1of12.patch @@ -0,0 +1,23 @@ +From 578aed8391ef117ca64a9e0cba8e5c264368a0ec Mon Sep 17 00:00:00 2001 +From: Frank Morgner +Date: Thu, 8 Dec 2022 00:27:18 +0100 +Subject: [PATCH] sc_pkcs15init_rmdir: prevent out of bounds write + +fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=53927 +--- + src/pkcs15init/pkcs15-lib.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c +index 91cee37310..3df03c6e1f 100644 +--- a/src/pkcs15init/pkcs15-lib.c ++++ b/src/pkcs15init/pkcs15-lib.c +@@ -685,6 +685,8 @@ sc_pkcs15init_rmdir(struct sc_pkcs15_card *p15card, struct sc_profile *profile, + + path = df->path; + path.len += 2; ++ if (path.len > SC_MAX_PATH_SIZE) ++ return SC_ERROR_INTERNAL; + + nfids = r / 2; + while (r >= 0 && nfids--) { diff --git a/opensc-CVE-2023-40661-2of12.patch b/opensc-CVE-2023-40661-2of12.patch new file mode 100644 index 0000000..9a21965 --- /dev/null +++ b/opensc-CVE-2023-40661-2of12.patch @@ -0,0 +1,25 @@ +From df5a176bfdf8c52ba89c7fef1f82f6f3b9312bc1 Mon Sep 17 00:00:00 2001 +From: Veronika Hanulikova +Date: Fri, 10 Feb 2023 11:47:34 +0100 +Subject: [PATCH] Check array bounds + +Thanks OSS-Fuzz +https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=54312 +--- + src/libopensc/muscle.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/libopensc/muscle.c b/src/libopensc/muscle.c +index 61a4ec24d8..9d01e0c113 100644 +--- a/src/libopensc/muscle.c ++++ b/src/libopensc/muscle.c +@@ -181,6 +181,9 @@ int msc_partial_update_object(sc_card_t *card, msc_id objectId, int offset, cons + sc_apdu_t apdu; + int r; + ++ if (dataLength + 9 > MSC_MAX_APDU) ++ return SC_ERROR_INVALID_ARGUMENTS; ++ + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x54, 0x00, 0x00); + apdu.lc = dataLength + 9; + if (card->ctx->debug >= 2) diff --git a/opensc-CVE-2023-40661-3of12.patch b/opensc-CVE-2023-40661-3of12.patch new file mode 100644 index 0000000..03987a4 --- /dev/null +++ b/opensc-CVE-2023-40661-3of12.patch @@ -0,0 +1,37 @@ +From 5631e9843c832a99769def85b7b9b68b4e3e3959 Mon Sep 17 00:00:00 2001 +From: Veronika Hanulikova +Date: Fri, 3 Mar 2023 16:07:38 +0100 +Subject: [PATCH] Check length of string before making copy + +Thanks OSS-Fuzz +https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=55851 +https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=55998 +--- + src/pkcs15init/profile.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c +index 2b793b0282..3bad1e8536 100644 +--- a/src/pkcs15init/profile.c ++++ b/src/pkcs15init/profile.c +@@ -1575,7 +1575,10 @@ do_acl(struct state *cur, int argc, char **argv) + while (argc--) { + unsigned int op, method, id; + ++ if (strlen(*argv) >= sizeof(oper)) ++ goto bad; + strlcpy(oper, *argv++, sizeof(oper)); ++ + if ((what = strchr(oper, '=')) == NULL) + goto bad; + *what++ = '\0'; +@@ -2288,6 +2291,9 @@ get_authid(struct state *cur, const char *value, + return get_uint(cur, value, type); + } + ++ if (strlen(value) >= sizeof(temp)) ++ return 1; ++ + n = strcspn(value, "0123456789x"); + strlcpy(temp, value, (sizeof(temp) > n) ? n + 1 : sizeof(temp)); + diff --git a/opensc-CVE-2023-40661-4of12.patch b/opensc-CVE-2023-40661-4of12.patch new file mode 100644 index 0000000..fad2429 --- /dev/null +++ b/opensc-CVE-2023-40661-4of12.patch @@ -0,0 +1,546 @@ +From aadd82bb071e574fc57263a103e3bf06ebbd8de7 Mon Sep 17 00:00:00 2001 +From: "Ingo Struck (git commits)" +Date: Sat, 21 Jan 2023 22:15:10 +0100 +Subject: [PATCH] Handle reader limits for SC Card unwrap operations + +Fixes #2514 +--- + src/libopensc/card-sc-hsm.c | 181 ++++++++++++++----------- + src/libopensc/reader-pcsc.c | 91 ++++++++----- + src/tests/fuzzing/fuzz_pkcs15_decode.c | 3 +- + src/tests/fuzzing/fuzz_pkcs15_encode.c | 2 +- + 4 files changed, 159 insertions(+), 118 deletions(-) + +diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c +index 60d5895127..1b707f08df 100644 +--- a/src/libopensc/card-sc-hsm.c ++++ b/src/libopensc/card-sc-hsm.c +@@ -145,9 +145,7 @@ static int sc_hsm_select_file_ex(sc_card_t *card, + + if (file_out == NULL) { // Versions before 0.16 of the SmartCard-HSM do not support P2='0C' + rv = sc_hsm_select_file_ex(card, in_path, forceselect, &file); +- if (file != NULL) { +- sc_file_free(file); +- } ++ sc_file_free(file); + return rv; + } + +@@ -181,9 +179,7 @@ static int sc_hsm_select_file_ex(sc_card_t *card, + LOG_TEST_RET(card->ctx, rv, "Could not select SmartCard-HSM application"); + + if (priv) { +- if (priv->dffcp != NULL) { +- sc_file_free(priv->dffcp); +- } ++ sc_file_free(priv->dffcp); + // Cache the FCP returned when selecting the applet + sc_file_dup(&priv->dffcp, *file_out); + } +@@ -730,12 +726,12 @@ static int sc_hsm_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, + u8 recvbuf[SC_MAX_APDU_BUFFER_SIZE]; + #ifdef ENABLE_SM + if (card->sm_ctx.sm_mode != SM_MODE_TRANSMIT) { +- sc_log(card->ctx, ++ sc_log(card->ctx, + "Session PIN generation only supported in SM"); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + } + #else +- sc_log(card->ctx, ++ sc_log(card->ctx, + "Session PIN generation only supported in SM"); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + #endif +@@ -746,7 +742,7 @@ static int sc_hsm_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, + apdu.le = 0; + if (sc_transmit_apdu(card, &apdu) != SC_SUCCESS + || sc_check_sw(card, apdu.sw1, apdu.sw2) != SC_SUCCESS) { +- sc_log(card->ctx, ++ sc_log(card->ctx, + "Generating session PIN failed"); + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + } +@@ -756,12 +752,12 @@ static int sc_hsm_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, + apdu.resplen); + data->pin2.len = apdu.resplen; + } else { +- sc_log(card->ctx, ++ sc_log(card->ctx, + "Buffer too small for session PIN"); + } + } + } else { +- sc_log(card->ctx, ++ sc_log(card->ctx, + "Session PIN not supported for this PIN (0x%02X)", + data->pin_reference); + } +@@ -848,47 +844,61 @@ static int sc_hsm_write_ef(sc_card_t *card, + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + } + +- p = cmdbuff; +- *p++ = 0x54; +- *p++ = 0x02; +- *p++ = (idx >> 8) & 0xFF; +- *p++ = idx & 0xFF; +- *p++ = 0x53; +- if (count < 128) { +- *p++ = (u8) count; +- len = 6; +- } else if (count < 256) { +- *p++ = 0x81; +- *p++ = (u8) count; +- len = 7; +- } else { +- *p++ = 0x82; +- *p++ = (count >> 8) & 0xFF; +- *p++ = count & 0xFF; +- len = 8; +- } ++ size_t bytes_left = count; ++ // 8 bytes are required for T54(4) and T53(4) ++ size_t blk_size = card->max_send_size - 8; ++ size_t to_send = 0; ++ size_t offset = (size_t) idx; ++ do { ++ len = 0; ++ to_send = bytes_left >= blk_size ? blk_size : bytes_left; ++ p = cmdbuff; ++ // ASN1 0x54 offset ++ *p++ = 0x54; ++ *p++ = 0x02; ++ *p++ = (offset >> 8) & 0xFF; ++ *p++ = offset & 0xFF; ++ // ASN1 0x53 to_send ++ *p++ = 0x53; ++ if (to_send < 128) { ++ *p++ = (u8)to_send; ++ len = 6; ++ } else if (to_send < 256) { ++ *p++ = 0x81; ++ *p++ = (u8)to_send; ++ len = 7; ++ } else { ++ *p++ = 0x82; ++ *p++ = (to_send >> 8) & 0xFF; ++ *p++ = to_send & 0xFF; ++ len = 8; ++ } + +- if (buf != NULL) +- memcpy(p, buf, count); +- len += count; ++ if (buf != NULL) ++ memcpy(p, buf+offset, to_send); ++ len += to_send; + +- sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xD7, fid >> 8, fid & 0xFF); +- apdu.data = cmdbuff; +- apdu.datalen = len; +- apdu.lc = len; ++ sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xD7, fid >> 8, fid & 0xFF); ++ apdu.data = cmdbuff; ++ apdu.datalen = len; ++ apdu.lc = len; + +- r = sc_transmit_apdu(card, &apdu); +- free(cmdbuff); +- LOG_TEST_RET(ctx, r, "APDU transmit failed"); ++ r = sc_transmit_apdu(card, &apdu); ++ LOG_TEST_GOTO_ERR(ctx, r, "APDU transmit failed"); ++ r = sc_check_sw(card, apdu.sw1, apdu.sw2); ++ LOG_TEST_GOTO_ERR(ctx, r, "Check SW error"); + +- r = sc_check_sw(card, apdu.sw1, apdu.sw2); +- LOG_TEST_RET(ctx, r, "Check SW error"); ++ bytes_left -= to_send; ++ offset += to_send; ++ } while (0 < bytes_left); ++ ++err: ++ free(cmdbuff); + + LOG_FUNC_RETURN(ctx, count); + } + + +- + static int sc_hsm_update_binary(sc_card_t *card, + unsigned int idx, const u8 *buf, size_t count, + unsigned long flags) +@@ -1227,7 +1237,7 @@ static int sc_hsm_initialize(sc_card_t *card, sc_cardctl_sc_hsm_init_param_t *pa + return SC_ERROR_INVALID_ARGUMENTS; + } + *p++ = 0x81; // User PIN +- *p++ = (u8) params->user_pin_len; ++ *p++ = (u8)params->user_pin_len; + memcpy(p, params->user_pin, params->user_pin_len); + p += params->user_pin_len; + +@@ -1400,12 +1410,11 @@ static int sc_hsm_unwrap_key(sc_card_t *card, sc_cardctl_sc_hsm_wrapped_key_t *p + + LOG_FUNC_CALLED(card->ctx); + +- sc_format_apdu(card, &apdu, SC_APDU_CASE_3_EXT, 0x74, params->key_id, 0x93); +- apdu.cla = 0x80; +- apdu.lc = params->wrapped_key_length; +- apdu.data = params->wrapped_key; +- apdu.datalen = params->wrapped_key_length; ++ r = sc_hsm_write_ef(card, 0x2F10, 0, params->wrapped_key, params->wrapped_key_length); ++ LOG_TEST_RET(card->ctx, r, "Create EF failed"); + ++ sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x74, params->key_id, 0x93); ++ apdu.cla = 0x80; + r = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(ctx, r, "APDU transmit failed"); + +@@ -1765,17 +1774,10 @@ static int sc_hsm_init(struct sc_card *card) + int flags,ext_flags; + sc_file_t *file = NULL; + sc_path_t path; +- sc_hsm_private_data_t *priv = card->drv_data; ++ sc_hsm_private_data_t *priv = NULL; + + LOG_FUNC_CALLED(card->ctx); + +- if (!priv) { +- priv = calloc(1, sizeof(sc_hsm_private_data_t)); +- if (!priv) +- LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); +- card->drv_data = priv; +- } +- + flags = SC_ALGORITHM_RSA_RAW|SC_ALGORITHM_RSA_PAD_PSS|SC_ALGORITHM_ONBOARD_KEY_GEN; + + _sc_card_add_rsa_alg(card, 1024, flags, 0); +@@ -1807,6 +1809,46 @@ static int sc_hsm_init(struct sc_card *card) + + card->caps |= SC_CARD_CAP_RNG|SC_CARD_CAP_APDU_EXT|SC_CARD_CAP_ISO7816_PIN_INFO; + ++ // APDU Buffer limits ++ // JCOP 2.4.1r3 1462 ++ // JCOP 2.4.2r3 1454 ++ // JCOP 3 1232 ++ // MicroSD with JCOP 3 478 / 506 - handled in reader-pcsc.c ++ // Reiner SCT 1014 - handled in reader-pcsc.c ++ ++ // Use JCOP 3 card limits for sending ++ card->max_send_size = 1232; ++ // Assume that card supports sending with extended length APDU and without limit ++ card->max_recv_size = 0; ++ ++ if (card->type == SC_CARD_TYPE_SC_HSM_SOC ++ || card->type == SC_CARD_TYPE_SC_HSM_GOID) { ++ card->max_recv_size = 0x0630; // SoC Proxy forces this limit ++ } else { ++ // Adjust to the limits set by the reader ++ if (card->reader->max_send_size < card->max_send_size) { ++ if (18 >= card->reader->max_send_size) ++ LOG_FUNC_RETURN(card->ctx, SC_ERROR_INCONSISTENT_CONFIGURATION); ++ ++ // 17 byte header and TLV because of odd ins in UPDATE BINARY ++ card->max_send_size = card->reader->max_send_size - 17; ++ } ++ ++ if (0 < card->reader->max_recv_size) { ++ if (3 >= card->reader->max_recv_size) ++ LOG_FUNC_RETURN(card->ctx, SC_ERROR_INCONSISTENT_CONFIGURATION); ++ card->max_recv_size = card->reader->max_recv_size - 2; ++ } ++ } ++ ++ priv = card->drv_data; ++ if (!priv) { ++ priv = calloc(1, sizeof(sc_hsm_private_data_t)); ++ if (!priv) ++ LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); ++ card->drv_data = priv; ++ } ++ + sc_path_set(&path, SC_PATH_TYPE_DF_NAME, sc_hsm_aid.value, sc_hsm_aid.len, 0, 0); + if (sc_hsm_select_file_ex(card, &path, 0, &file) == SC_SUCCESS + && file && file->prop_attr && file->prop_attr_len >= 2) { +@@ -1839,25 +1881,6 @@ static int sc_hsm_init(struct sc_card *card) + } + sc_file_free(file); + +- // APDU Buffer limits +- // JCOP 2.4.1r3 1462 +- // JCOP 2.4.2r3 1454 +- // JCOP 3 1232 +- // MicroSD with JCOP 3 478 / 506 +- // Reiner SCT 1014 +- +- card->max_send_size = 1232 - 17; // 1232 buffer size - 17 byte header and TLV because of odd ins in UPDATE BINARY +- +- if (!strncmp("Secure Flash Card", card->reader->name, 17)) { +- card->max_send_size = 478 - 17; +- card->max_recv_size = 506 - 2; +- } else if (card->type == SC_CARD_TYPE_SC_HSM_SOC +- || card->type == SC_CARD_TYPE_SC_HSM_GOID) { +- card->max_recv_size = 0x0630; // SoC Proxy forces this limit +- } else { +- card->max_recv_size = 0; // Card supports sending with extended length APDU and without limit +- } +- + priv->EF_C_DevAut = NULL; + priv->EF_C_DevAut_len = 0; + +@@ -1883,13 +1906,11 @@ static int sc_hsm_finish(sc_card_t * card) + #ifdef ENABLE_SM + sc_sm_stop(card); + #endif +- if (priv->serialno) { ++ if (priv) { + free(priv->serialno); +- } +- if (priv->dffcp) { + sc_file_free(priv->dffcp); ++ free(priv->EF_C_DevAut); + } +- free(priv->EF_C_DevAut); + free(priv); + + return SC_SUCCESS; +diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c +index 40bfd293d3..04d5ac8fdd 100644 +--- a/src/libopensc/reader-pcsc.c ++++ b/src/libopensc/reader-pcsc.c +@@ -311,7 +311,7 @@ static int pcsc_transmit(sc_reader_t *reader, sc_apdu_t *apdu) + * The buffer for the returned data needs to be at least 2 bytes + * larger than the expected data length to store SW1 and SW2. */ + rsize = rbuflen = apdu->resplen <= 256 ? 258 : apdu->resplen + 2; +- rbuf = malloc(rbuflen); ++ rbuf = malloc(rbuflen); + if (rbuf == NULL) { + r = SC_ERROR_OUT_OF_MEMORY; + goto out; +@@ -386,7 +386,7 @@ static int refresh_attributes(sc_reader_t *reader) + } + LOG_FUNC_RETURN(reader->ctx, SC_SUCCESS); + } +- ++ + /* the system could not detect the reader. It means, the prevoiusly attached reader is disconnected. */ + if (rv == (LONG)SCARD_E_UNKNOWN_READER + #ifdef SCARD_E_NO_READERS_AVAILABLE +@@ -424,7 +424,7 @@ static int refresh_attributes(sc_reader_t *reader) + if (priv->reader_state.cbAtr > SC_MAX_ATR_SIZE) + return SC_ERROR_INTERNAL; + +- /* Some cards have a different cold (after a powerup) and warm (after a reset) ATR */ ++ /* Some cards have a different cold (after a powerup) and warm (after a reset) ATR */ + if (memcmp(priv->reader_state.rgbAtr, reader->atr.value, priv->reader_state.cbAtr) != 0) { + reader->atr.len = priv->reader_state.cbAtr; + memcpy(reader->atr.value, priv->reader_state.rgbAtr, reader->atr.len); +@@ -556,7 +556,7 @@ static int pcsc_reconnect(sc_reader_t * reader, DWORD action) + priv->gpriv->connect_exclusive ? SCARD_SHARE_EXCLUSIVE : SCARD_SHARE_SHARED, + protocol, action, &active_proto); + +- ++ + PCSC_TRACE(reader, "SCardReconnect returned", rv); + if (rv != SCARD_S_SUCCESS) { + PCSC_TRACE(reader, "SCardReconnect failed", rv); +@@ -593,7 +593,7 @@ static void initialize_uid(sc_reader_t *reader) + sc_log_hex(reader->ctx, "UID", + reader->uid.value, reader->uid.len); + } else { +- sc_log(reader->ctx, "unable to get UID"); ++ sc_log(reader->ctx, "unable to get UID"); + } + } + } +@@ -1177,7 +1177,7 @@ static void detect_reader_features(sc_reader_t *reader, SCARDHANDLE card_handle) + priv->modify_ioctl_finish = ntohl(pcsc_tlv->value); + } else if (pcsc_tlv->tag == FEATURE_IFD_PIN_PROPERTIES) { + priv->pin_properties_ioctl = ntohl(pcsc_tlv->value); +- } else if (pcsc_tlv->tag == FEATURE_GET_TLV_PROPERTIES) { ++ } else if (pcsc_tlv->tag == FEATURE_GET_TLV_PROPERTIES) { + priv->get_tlv_properties = ntohl(pcsc_tlv->value); + } else if (pcsc_tlv->tag == FEATURE_EXECUTE_PACE) { + priv->pace_ioctl = ntohl(pcsc_tlv->value); +@@ -1240,11 +1240,11 @@ static void detect_reader_features(sc_reader_t *reader, SCARDHANDLE card_handle) + sc_log(ctx, "Reader has a display: %04X", caps->wLcdLayout); + reader->capabilities |= SC_READER_CAP_DISPLAY; + } +- else { ++ else { + sc_log(ctx, "Reader does not have a display."); + } + } +- else { ++ else { + sc_log(ctx, + "Returned PIN properties structure has bad length (%lu/%"SC_FORMAT_LEN_SIZE_T"u)", + (unsigned long)rcount, +@@ -1266,34 +1266,55 @@ static void detect_reader_features(sc_reader_t *reader, SCARDHANDLE card_handle) + } + } + ++ size_t max_send_size = 0; ++ size_t max_recv_size = 0; + if (priv->get_tlv_properties) { + /* Try to set reader max_send_size and max_recv_size based on + * detected max_data */ +- int max_data = part10_detect_max_data(reader, card_handle); +- +- if (max_data > 0) { +- sc_log(ctx, "Reader supports transceiving %d bytes of data", +- max_data); +- if (!priv->gpriv->force_max_send_size) +- reader->max_send_size = max_data; +- else +- sc_log(ctx, "Sending is limited to %"SC_FORMAT_LEN_SIZE_T"u bytes of data" +- " in configuration file", reader->max_send_size); +- if (!priv->gpriv->force_max_recv_size) +- reader->max_recv_size = max_data; +- else +- sc_log(ctx, "Receiving is limited to %"SC_FORMAT_LEN_SIZE_T"u bytes of data" +- " in configuration file", reader->max_recv_size); +- } else { +- sc_log(ctx, "Assuming that the reader supports transceiving " +- "short length APDUs only"); +- } ++ max_send_size = max_recv_size = part10_detect_max_data(reader, card_handle); + + /* debug the product and vendor ID of the reader */ + part10_get_vendor_product(reader, card_handle, NULL, NULL); + } ++ else { ++ /* Try to set default limits based on device name */ ++ if (!strncmp("REINER SCT cyberJack", reader->name, 20)) { ++ max_send_size = 1014; ++ max_recv_size = 1014; ++ } ++ else if (!strncmp("Secure Flash Card", reader->name, 17)) { ++ max_send_size = 478; ++ max_recv_size = 506; ++ } ++ } + +- if(gpriv->SCardGetAttrib != NULL) { ++ if (max_send_size > 0) { ++ sc_log(ctx, "Reader supports sending %"SC_FORMAT_LEN_SIZE_T"u bytes of data", ++ max_send_size); ++ if (!priv->gpriv->force_max_send_size) ++ reader->max_send_size = max_send_size; ++ else ++ sc_log(ctx, "Sending is limited to %"SC_FORMAT_LEN_SIZE_T"u bytes of data" ++ " in configuration file", reader->max_send_size); ++ } else { ++ sc_log(ctx, "Assuming that the reader supports sending " ++ "short length APDUs only"); ++ } ++ ++ if (max_recv_size > 0) { ++ sc_log(ctx, "Reader supports receiving %"SC_FORMAT_LEN_SIZE_T"u bytes of data", ++ max_recv_size); ++ if (!priv->gpriv->force_max_recv_size) ++ reader->max_recv_size = max_recv_size; ++ else ++ sc_log(ctx, "Receiving is limited to %"SC_FORMAT_LEN_SIZE_T"u bytes of data" ++ " in configuration file", reader->max_recv_size); ++ } else { ++ sc_log(ctx, "Assuming that the reader supports receiving " ++ "short length APDUs only"); ++ } ++ ++ if (gpriv->SCardGetAttrib != NULL) { + rcount = sizeof(buf); + if (gpriv->SCardGetAttrib(card_handle, SCARD_ATTR_VENDOR_NAME, + buf, &rcount) == SCARD_S_SUCCESS +@@ -1304,7 +1325,7 @@ static void detect_reader_features(sc_reader_t *reader, SCARDHANDLE card_handle) + } + + rcount = sizeof i; +- if(gpriv->SCardGetAttrib(card_handle, SCARD_ATTR_VENDOR_IFD_VERSION, ++ if (gpriv->SCardGetAttrib(card_handle, SCARD_ATTR_VENDOR_IFD_VERSION, + (u8 *) &i, &rcount) == SCARD_S_SUCCESS + && rcount == sizeof i) { + reader->version_major = (i >> 24) & 0xFF; +@@ -1314,7 +1335,7 @@ static void detect_reader_features(sc_reader_t *reader, SCARDHANDLE card_handle) + } + + int pcsc_add_reader(sc_context_t *ctx, +- char *reader_name, size_t reader_name_len, ++ char *reader_name, size_t reader_name_len, + sc_reader_t **out_reader) + { + int ret = SC_ERROR_INTERNAL; +@@ -1574,7 +1595,7 @@ static int pcsc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_re + + LOG_FUNC_CALLED(ctx); + +- if (!event_reader && !event && reader_states) { ++ if (!event_reader && !event && reader_states) { + sc_log(ctx, "free allocated reader states"); + free(*reader_states); + *reader_states = NULL; +@@ -1684,7 +1705,7 @@ static int pcsc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_re + state = rsp->dwEventState; + rsp->dwCurrentState = rsp->dwEventState; + if (state & SCARD_STATE_CHANGED) { +- /* check for hotplug events */ ++ /* check for hotplug events */ + if (!strcmp(rsp->szReader, "\\\\?PnP?\\Notification")) { + sc_log(ctx, "detected hotplug event"); + /* Windows sends hotplug event on both, attaching and +@@ -1859,7 +1880,7 @@ static int part10_build_verify_pin_block(struct sc_reader *reader, u8 * buf, siz + u8 tmp; + unsigned int tmp16; + unsigned int off; +- PIN_VERIFY_STRUCTURE *pin_verify = (PIN_VERIFY_STRUCTURE *)buf; ++ PIN_VERIFY_STRUCTURE *pin_verify = (PIN_VERIFY_STRUCTURE *)buf; + + /* PIN verification control message */ + pin_verify->bTimerOut = SC_CCID_PIN_TIMEOUT; +@@ -1958,7 +1979,7 @@ static int part10_build_modify_pin_block(struct sc_reader *reader, u8 * buf, siz + sc_apdu_t *apdu = data->apdu; + u8 tmp; + unsigned int tmp16; +- PIN_MODIFY_STRUCTURE *pin_modify = (PIN_MODIFY_STRUCTURE *)buf; ++ PIN_MODIFY_STRUCTURE *pin_modify = (PIN_MODIFY_STRUCTURE *)buf; + struct sc_pin_cmd_pin *pin_ref = + data->flags & SC_PIN_CMD_IMPLICIT_CHANGE ? + &data->pin2 : &data->pin1; +@@ -2569,7 +2590,7 @@ int pcsc_use_reader(sc_context_t *ctx, void * pcsc_context_handle, void * pcsc_c + gpriv->attached_reader = NULL; + + gpriv->pcsc_ctx = *(SCARDCONTEXT *)pcsc_context_handle; +- card_handle = *(SCARDHANDLE *)pcsc_card_handle; ++ card_handle = *(SCARDHANDLE *)pcsc_card_handle; + + if(SCARD_S_SUCCESS == gpriv->SCardGetAttrib(card_handle, + SCARD_ATTR_DEVICE_SYSTEM_NAME_A, (LPBYTE) +diff --git a/src/tests/fuzzing/fuzz_pkcs15_decode.c b/src/tests/fuzzing/fuzz_pkcs15_decode.c +index a83c719cb9..e5758ba4d5 100644 +--- a/src/tests/fuzzing/fuzz_pkcs15_decode.c ++++ b/src/tests/fuzzing/fuzz_pkcs15_decode.c +@@ -108,9 +108,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) + + sc_pkcs15_parse_unusedspace(buf, buf_len, p15card); + +- sc_pkcs15_card_free(p15card); +- + err: ++ sc_pkcs15_card_free(p15card); + sc_disconnect_card(card); + sc_release_context(ctx); + return 0; +diff --git a/src/tests/fuzzing/fuzz_pkcs15_encode.c b/src/tests/fuzzing/fuzz_pkcs15_encode.c +index eb3436dae2..a10ecf5645 100644 +--- a/src/tests/fuzzing/fuzz_pkcs15_encode.c ++++ b/src/tests/fuzzing/fuzz_pkcs15_encode.c +@@ -80,8 +80,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) + sc_pkcs15_encode_unusedspace(ctx, p15card, &unused_space, &unused_space_len); + free(unused_space); + +- sc_pkcs15_card_free(p15card); + err: ++ sc_pkcs15_card_free(p15card); + sc_disconnect_card(card); + sc_release_context(ctx); + diff --git a/opensc-CVE-2023-40661-5of12.patch b/opensc-CVE-2023-40661-5of12.patch new file mode 100644 index 0000000..4fd6d37 --- /dev/null +++ b/opensc-CVE-2023-40661-5of12.patch @@ -0,0 +1,61 @@ +From dd138d0600a1acd7991989127f36827e5836b24e Mon Sep 17 00:00:00 2001 +From: "Ingo Struck (git commits)" +Date: Thu, 16 Mar 2023 22:12:49 +0100 +Subject: [PATCH] Fixed loop in sc_hsm_write_ef, handle offset into buf and + into EF separately + +--- + src/libopensc/card-sc-hsm.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c +index 1b707f08df..c100a87c2a 100644 +--- a/src/libopensc/card-sc-hsm.c ++++ b/src/libopensc/card-sc-hsm.c +@@ -782,7 +782,7 @@ static int sc_hsm_logout(sc_card_t * card) + } + + +- ++/* NOTE: idx is an offset into the card's file, not into buf */ + static int sc_hsm_read_binary(sc_card_t *card, + unsigned int idx, u8 *buf, size_t count, + unsigned long flags) +@@ -823,7 +823,7 @@ static int sc_hsm_read_binary(sc_card_t *card, + } + + +- ++/* NOTE: idx is an offset into the card's file, not into buf */ + static int sc_hsm_write_ef(sc_card_t *card, + int fid, + unsigned int idx, const u8 *buf, size_t count) +@@ -848,7 +848,8 @@ static int sc_hsm_write_ef(sc_card_t *card, + // 8 bytes are required for T54(4) and T53(4) + size_t blk_size = card->max_send_size - 8; + size_t to_send = 0; +- size_t offset = (size_t) idx; ++ size_t file_offset = (size_t) idx; ++ size_t offset = 0; + do { + len = 0; + to_send = bytes_left >= blk_size ? blk_size : bytes_left; +@@ -856,8 +857,8 @@ static int sc_hsm_write_ef(sc_card_t *card, + // ASN1 0x54 offset + *p++ = 0x54; + *p++ = 0x02; +- *p++ = (offset >> 8) & 0xFF; +- *p++ = offset & 0xFF; ++ *p++ = (file_offset >> 8) & 0xFF; ++ *p++ = file_offset & 0xFF; + // ASN1 0x53 to_send + *p++ = 0x53; + if (to_send < 128) { +@@ -890,6 +891,7 @@ static int sc_hsm_write_ef(sc_card_t *card, + + bytes_left -= to_send; + offset += to_send; ++ file_offset += to_send; + } while (0 < bytes_left); + + err: diff --git a/opensc-CVE-2023-40661-6of12.patch b/opensc-CVE-2023-40661-6of12.patch new file mode 100644 index 0000000..ecb7ff1 --- /dev/null +++ b/opensc-CVE-2023-40661-6of12.patch @@ -0,0 +1,25 @@ +From c449a181a6988cc1e8dc8764d23574e48cdc3fa6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= +Date: Mon, 19 Jun 2023 16:14:51 +0200 +Subject: [PATCH] pkcs15-cflex: check path length to prevent underflow + +Thanks OSS-Fuzz +https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=58932 +--- + src/pkcs15init/pkcs15-cflex.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/pkcs15init/pkcs15-cflex.c b/src/pkcs15init/pkcs15-cflex.c +index d06568073d..ce1d48e62c 100644 +--- a/src/pkcs15init/pkcs15-cflex.c ++++ b/src/pkcs15init/pkcs15-cflex.c +@@ -56,6 +56,9 @@ cflex_delete_file(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *d + int r = 0; + /* Select the parent DF */ + path = df->path; ++ if (path.len < 2) { ++ return SC_ERROR_INVALID_ARGUMENTS; ++ } + path.len -= 2; + r = sc_select_file(p15card->card, &path, &parent); + if (r < 0) diff --git a/opensc-CVE-2023-40661-7of12.patch b/opensc-CVE-2023-40661-7of12.patch new file mode 100644 index 0000000..a2d3772 --- /dev/null +++ b/opensc-CVE-2023-40661-7of12.patch @@ -0,0 +1,27 @@ +From 88880db0307a07e33cf2e1592bb029e9c170dfea Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= +Date: Wed, 21 Jun 2023 15:48:27 +0200 +Subject: [PATCH] pkcs15-pubkey: free DER value when parsing public key fails + +The der value might be allocated in asn1_decode_entry() +but it is not released when errror occurs. + +Thanks OSS-Fuzz +https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=59615 +--- + src/libopensc/pkcs15-pubkey.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c +index 4a0ddffbeb..7107c47cbc 100644 +--- a/src/libopensc/pkcs15-pubkey.c ++++ b/src/libopensc/pkcs15-pubkey.c +@@ -351,6 +351,8 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, + err: + if (r < 0) { + sc_pkcs15_free_pubkey_info(info); ++ if (der->len) ++ free(der->value); + } + + LOG_FUNC_RETURN(ctx, r); diff --git a/opensc-CVE-2023-40661-8of12.patch b/opensc-CVE-2023-40661-8of12.patch new file mode 100644 index 0000000..c5986d8 --- /dev/null +++ b/opensc-CVE-2023-40661-8of12.patch @@ -0,0 +1,29 @@ +From 638a5007a5d240d6fa901aa822cfeef94fe36e85 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= +Date: Thu, 10 Aug 2023 12:20:33 +0200 +Subject: [PATCH] pkcs15-pubkey.c: Avoid double-free + +Thanks OSS-Fuzz +https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60616 +--- + src/libopensc/pkcs15-pubkey.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c +index 7107c47cbc..49b514968b 100644 +--- a/src/libopensc/pkcs15-pubkey.c ++++ b/src/libopensc/pkcs15-pubkey.c +@@ -351,8 +351,12 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, + err: + if (r < 0) { + sc_pkcs15_free_pubkey_info(info); +- if (der->len) ++ if (der->len) { + free(der->value); ++ /* der points to obj->content */ ++ obj->content.value = NULL; ++ obj->content.len = 0; ++ } + } + + LOG_FUNC_RETURN(ctx, r); diff --git a/opensc-CVE-2023-40661-9of12.patch b/opensc-CVE-2023-40661-9of12.patch new file mode 100644 index 0000000..ea407e4 --- /dev/null +++ b/opensc-CVE-2023-40661-9of12.patch @@ -0,0 +1,27 @@ +From ce7fcdaa35196706a83fe982900228e15464f928 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Thu, 17 Aug 2023 11:55:06 +0200 +Subject: [PATCH] oberthur: Avoid heap buffer overflow + +Thanks oss-fuzz + +https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60650 +--- + src/pkcs15init/pkcs15-oberthur.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/pkcs15init/pkcs15-oberthur.c b/src/pkcs15init/pkcs15-oberthur.c +index 377e28948e..b20bd6e6c4 100644 +--- a/src/pkcs15init/pkcs15-oberthur.c ++++ b/src/pkcs15init/pkcs15-oberthur.c +@@ -531,7 +531,9 @@ cosm_new_file(struct sc_profile *profile, struct sc_card *card, + } + + file->id |= (num & 0xFF); +- file->path.value[file->path.len-1] |= (num & 0xFF); ++ if (file->path.len) { ++ file->path.value[file->path.len - 1] |= (num & 0xFF); ++ } + if (file->type == SC_FILE_TYPE_INTERNAL_EF) { + file->ef_structure = structure; + } diff --git a/opensc-CVE-2023-4535.patch b/opensc-CVE-2023-4535.patch new file mode 100644 index 0000000..e544e1e --- /dev/null +++ b/opensc-CVE-2023-4535.patch @@ -0,0 +1,39 @@ +From f1993dc4e0b33050b8f72a3558ee88b24c4063b2 Mon Sep 17 00:00:00 2001 +From: Peter Popovec +Date: Tue, 27 Jun 2023 09:50:42 +0200 +Subject: [PATCH] myeid: fixed CID 380538 Out-of-bounds read (OVERRUN) + +also fixes output buffer size checking +--- + src/libopensc/card-myeid.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c +index 4ee4246840..50e78ff1d8 100644 +--- a/src/libopensc/card-myeid.c ++++ b/src/libopensc/card-myeid.c +@@ -1986,18 +1986,20 @@ myeid_enc_dec_sym(struct sc_card *card, const u8 *data, size_t datalen, + sc_log(ctx, "Found padding byte %02x", pad_byte); + if (pad_byte == 0 || pad_byte > block_size) + LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_PADDING); +- sdata = priv->sym_plain_buffer + block_size - pad_byte; ++ sdata = priv->sym_plain_buffer + block_size; + for (i = 0; i < pad_byte; i++) +- if (sdata[i] != pad_byte) ++ if (*(--sdata) != pad_byte) + LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_PADDING); + return_len = block_size - pad_byte; + } +- *outlen = return_len; + /* application can request buffer size or actual buffer size is too small */ +- if (out == NULL) ++ if (out == NULL) { ++ *outlen = return_len; + LOG_FUNC_RETURN(ctx, SC_SUCCESS); ++ } + if (return_len > *outlen) + LOG_FUNC_RETURN(ctx, SC_ERROR_BUFFER_TOO_SMALL); ++ *outlen = return_len; + memcpy(out, priv->sym_plain_buffer, return_len); + sc_log(ctx, "C_DecryptFinal %zu bytes", *outlen); + return SC_SUCCESS; diff --git a/opensc-NULL_pointer_fix.patch b/opensc-NULL_pointer_fix.patch new file mode 100644 index 0000000..fa91dcc --- /dev/null +++ b/opensc-NULL_pointer_fix.patch @@ -0,0 +1,54 @@ +From cde2e050ec4f2f1b7db38429aa4e9c0f4656308c Mon Sep 17 00:00:00 2001 +From: Peter Popovec +Date: Wed, 26 Apr 2023 13:22:09 +0200 +Subject: [PATCH] NULL pointer fix + +Thanks to the clang analyzer: + Null pointer passed to 2nd parameter expecting 'nonnull' + [clang-analyzer-core.NonNullParamChecker] + + modified: src/libopensc/card-myeid.c +--- + src/libopensc/card-myeid.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c +index 31dd209f3e..951c179f1b 100644 +--- a/src/libopensc/card-myeid.c ++++ b/src/libopensc/card-myeid.c +@@ -1973,6 +1973,9 @@ myeid_enc_dec_sym(struct sc_card *card, const u8 *data, size_t datalen, + return_len = block_size - pad_byte; + } + *outlen = return_len; ++ /* application can request buffer size or actual buffer size is too small */ ++ if (out == NULL) ++ LOG_FUNC_RETURN(ctx, SC_SUCCESS); + if (return_len > *outlen) + LOG_FUNC_RETURN(ctx, SC_ERROR_BUFFER_TOO_SMALL); + memcpy(out, priv->sym_plain_buffer, return_len); +@@ -2042,10 +2045,11 @@ myeid_enc_dec_sym(struct sc_card *card, const u8 *data, size_t datalen, + priv->sym_crypt_buffer_len = 0; + rest_len = 0; + } +- memcpy(sdata, data, apdu_datalen); +- data += apdu_datalen; +- datalen -= apdu_datalen; +- ++ if (data) { ++ memcpy(sdata, data, apdu_datalen); ++ data += apdu_datalen; ++ datalen -= apdu_datalen; ++ } + r = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(ctx, r, "APDU transmit failed"); + r = sc_check_sw(card, apdu.sw1, apdu.sw2); +@@ -2084,7 +2088,8 @@ myeid_enc_dec_sym(struct sc_card *card, const u8 *data, size_t datalen, + /* save rest of data for next run */ + priv->sym_crypt_buffer_len = datalen; + sc_log(ctx, "rest data len = %zu", datalen); +- memcpy(priv->sym_crypt_buffer, data, datalen); ++ if (data) ++ memcpy(priv->sym_crypt_buffer, data, datalen); + sc_log(ctx, "return data len = %zu", return_len); + *outlen = return_len; + return SC_SUCCESS; diff --git a/opensc.changes b/opensc.changes index 2764550..1c6ad47 100644 --- a/opensc.changes +++ b/opensc.changes @@ -1,3 +1,39 @@ +------------------------------------------------------------------- +Fri Oct 6 06:49:24 UTC 2023 - Otto Hollmann + +- Security Fix: [CVE-2023-40661, bsc#1215761] + * opensc: multiple memory issues with pkcs15-init (enrollment tool) + * Add patches: + - opensc-CVE-2023-40661-1of12.patch + - opensc-CVE-2023-40661-2of12.patch + - opensc-CVE-2023-40661-3of12.patch + - opensc-CVE-2023-40661-4of12.patch + - opensc-CVE-2023-40661-5of12.patch + - opensc-CVE-2023-40661-6of12.patch + - opensc-CVE-2023-40661-7of12.patch + - opensc-CVE-2023-40661-8of12.patch + - opensc-CVE-2023-40661-9of12.patch + - opensc-CVE-2023-40661-10of12.patch + - opensc-CVE-2023-40661-11of12.patch + - opensc-CVE-2023-40661-12of12.patch + +------------------------------------------------------------------- +Thu Oct 5 13:45:16 UTC 2023 - Otto Hollmann + +- Security Fix: [CVE-2023-4535, bsc#1215763] + * Add patches: + - opensc-CVE-2023-4535.patch + - opensc-NULL_pointer_fix.patch + +------------------------------------------------------------------- +Wed Oct 4 13:26:11 UTC 2023 - Otto Hollmann + +- Security Fix: [CVE-2023-40660, bsc#1215762] + * opensc: PIN bypass when card tracks its own login state + * Add patches: + - opensc-CVE-2023-40660-1of2.patch + - opensc-CVE-2023-40660-2of2.patch + ------------------------------------------------------------------- Thu Jun 1 12:55:19 UTC 2023 - Otto Hollmann diff --git a/opensc.spec b/opensc.spec index 6eca5be..0435f67 100644 --- a/opensc.spec +++ b/opensc.spec @@ -33,6 +33,25 @@ Source3: opensc.module Patch0: opensc-gcc11.patch # PATCH-FIX-UPSTREAM: bsc#1211894, CVE-2023-2977 out of bounds read in pkcs15 cardos_have_verifyrc_package() Patch1: opensc-CVE-2023-2977.patch +# PATCH-FIX-UPSTREAM: bsc#1215762 CVE-2023-40660: PIN bypass when card tracks its own login state +Patch2: opensc-CVE-2023-40660-1of2.patch +Patch3: opensc-CVE-2023-40660-2of2.patch +# PATCH-FIX-UPSTREAM: bsc#1215763 CVE-2023-4535: out-of-bounds read in MyEID driver handling encryption using symmetric keys +Patch4: opensc-NULL_pointer_fix.patch +Patch5: opensc-CVE-2023-4535.patch +# PATCH-FIX-UPSTREAM: bsc#1215761 CVE-2023-40661: multiple memory issues with pkcs15-init (enrollment tool) +Patch6: opensc-CVE-2023-40661-1of12.patch +Patch7: opensc-CVE-2023-40661-2of12.patch +Patch8: opensc-CVE-2023-40661-3of12.patch +Patch9: opensc-CVE-2023-40661-4of12.patch +Patch10: opensc-CVE-2023-40661-5of12.patch +Patch11: opensc-CVE-2023-40661-6of12.patch +Patch12: opensc-CVE-2023-40661-7of12.patch +Patch13: opensc-CVE-2023-40661-8of12.patch +Patch14: opensc-CVE-2023-40661-9of12.patch +Patch15: opensc-CVE-2023-40661-10of12.patch +Patch16: opensc-CVE-2023-40661-11of12.patch +Patch17: opensc-CVE-2023-40661-12of12.patch BuildRequires: docbook-xsl-stylesheets BuildRequires: libxslt BuildRequires: pkgconfig