diff --git a/SPECS/opensc/CVE-2025-49010.patch b/SPECS/opensc/CVE-2025-49010.patch new file mode 100644 index 00000000000..fbceae52300 --- /dev/null +++ b/SPECS/opensc/CVE-2025-49010.patch @@ -0,0 +1,73 @@ +From e792df5c1e1a794741bb7a4b6beca477ddf8e83b Mon Sep 17 00:00:00 2001 +From: Frank Morgner +Date: Thu, 22 May 2025 00:24:32 +0200 +Subject: [PATCH] fixed Stack-buffer-overflow WRITE in GET RESPONSE + +The do-while loop in apdu.c requires the output data to be set in any +case, otherwise non existent data may be copied to the output data. + +fixes https://issues.oss-fuzz.com/issues/416351800 +fixes https://issues.oss-fuzz.com/issues/416295951 + +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference: https://github.com/OpenSC/OpenSC/commit/953986f65db61871bbbff72788d861d67d5140c6.patch +--- + src/libopensc/card-nqApplet.c | 11 ++++++----- + src/libopensc/iso7816.c | 5 +++-- + 2 files changed, 9 insertions(+), 7 deletions(-) + +diff --git a/src/libopensc/card-nqApplet.c b/src/libopensc/card-nqApplet.c +index b197432..6d40238 100644 +--- a/src/libopensc/card-nqApplet.c ++++ b/src/libopensc/card-nqApplet.c +@@ -190,9 +190,10 @@ static int nqapplet_finish(struct sc_card *card) + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + } + +-static int nqapplet_get_response(struct sc_card *card, size_t *cb_resp, u8 *resp) ++static int ++nqapplet_get_response(struct sc_card *card, size_t *cb_resp, u8 *resp) + { +- struct sc_apdu apdu; ++ struct sc_apdu apdu = {0}; + int rv; + size_t resplen; + +@@ -204,12 +205,12 @@ static int nqapplet_get_response(struct sc_card *card, size_t *cb_resp, u8 *resp + + rv = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, rv, "APDU transmit failed"); +- if (apdu.resplen == 0) { +- LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); +- } + + *cb_resp = apdu.resplen; + ++ if (apdu.resplen == 0) { ++ LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); ++ } + if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { + rv = SC_SUCCESS; + } else if (apdu.sw1 == 0x61) { +diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c +index 93b2707..89eba17 100644 +--- a/src/libopensc/iso7816.c ++++ b/src/libopensc/iso7816.c +@@ -805,11 +805,12 @@ iso7816_get_response(struct sc_card *card, size_t *count, u8 *buf) + + r = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); +- if (apdu.resplen == 0) +- LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); + + *count = apdu.resplen; + ++ if (apdu.resplen == 0) { ++ LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); ++ } + if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) + r = 0; /* no more data to read */ + else if (apdu.sw1 == 0x61) +-- +2.45.4 + diff --git a/SPECS/opensc/CVE-2025-66037.patch b/SPECS/opensc/CVE-2025-66037.patch new file mode 100644 index 00000000000..a584819dbb1 --- /dev/null +++ b/SPECS/opensc/CVE-2025-66037.patch @@ -0,0 +1,35 @@ +From 2b87a8d6c6164799b21a9dc014359346d39180b1 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Tue, 25 Nov 2025 15:58:02 +0100 +Subject: [PATCH] pkcs15: Avoid buffer overrun on invalid data + +Invalid data can contain zero-length buffer, which after copying +was dereferenced without length check + +Credit: Aldo Ristori + +Signed-off-by: Jakub Jelen +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference: https://github.com/OpenSC/OpenSC/commit/65fc211015cfcac27b10d0876054156c97225f50.patch +--- + src/libopensc/pkcs15-pubkey.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c +index bc5fa45..4ccb8ad 100644 +--- a/src/libopensc/pkcs15-pubkey.c ++++ b/src/libopensc/pkcs15-pubkey.c +@@ -1327,6 +1327,10 @@ sc_pkcs15_pubkey_from_spki_fields(struct sc_context *ctx, struct sc_pkcs15_pubke + "sc_pkcs15_pubkey_from_spki_fields() called: %p:%"SC_FORMAT_LEN_SIZE_T"u\n%s", + buf, buflen, sc_dump_hex(buf, buflen)); + ++ if (buflen < 1) { ++ LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "subjectPublicKeyInfo can not be empty"); ++ } ++ + tmp_buf = malloc(buflen); + if (!tmp_buf) { + r = SC_ERROR_OUT_OF_MEMORY; +-- +2.45.4 + diff --git a/SPECS/opensc/CVE-2025-66215.patch b/SPECS/opensc/CVE-2025-66215.patch new file mode 100644 index 00000000000..3c26dd0b211 --- /dev/null +++ b/SPECS/opensc/CVE-2025-66215.patch @@ -0,0 +1,744 @@ +From e064e2123752613a95bff50defd27a59ad562325 Mon Sep 17 00:00:00 2001 +From: AllSpark +Date: Fri, 3 Apr 2026 14:27:41 +0000 +Subject: [PATCH] Backport patches: fix stack buffer overflow by using + SC_MAX_APDU_BUFFER_SIZE for resplen, cap le to MIN and SC_MAX_APDU_RESP_SIZE, + switch magic 256 to SC_MAX_APDU_RESP_SIZE, use MIN macro, adjust response + buffer sizes to SC_MAX_APDU_RESP_SIZE, and formatting updates per upstream + patch. + +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference: AI Backport of https://github.com/OpenSC/OpenSC/pull/3436.patch +--- + src/libopensc/card-oberthur.c | 221 +++++++++++++++------------------- + 1 file changed, 96 insertions(+), 125 deletions(-) + +diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c +index 1fc40f7..f64ca90 100644 +--- a/src/libopensc/card-oberthur.c ++++ b/src/libopensc/card-oberthur.c +@@ -228,7 +228,7 @@ auth_init(struct sc_card *card) + card->caps |= SC_CARD_CAP_RNG; + card->caps |= SC_CARD_CAP_USE_FCI_AC; + +- if (auth_select_aid(card)) { ++ if (auth_select_aid(card)) { + sc_log(card->ctx, "Failed to initialize %s", card->name); + rv = SC_ERROR_INVALID_CARD; + LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_CARD, "Failed to initialize"); +@@ -259,7 +259,7 @@ static void + add_acl_entry(struct sc_card *card, struct sc_file *file, unsigned int op, + unsigned char acl_byte) + { +- if ((acl_byte & 0xE0) == 0x60) { ++ if ((acl_byte & 0xE0) == 0x60) { + sc_log(card->ctx, "called; op 0x%X; SC_AC_PRO; ref 0x%X", op, acl_byte); + sc_file_add_acl_entry(file, op, SC_AC_PRO, acl_byte); + return; +@@ -353,7 +353,7 @@ auth_process_fci(struct sc_card *card, struct sc_file *file, + file->size = PUBKEY_1024_ASN1_SIZE; + else if (file->size==2048) + file->size = PUBKEY_2048_ASN1_SIZE; +- else { ++ else { + sc_log(card->ctx, + "Not supported public key size: %"SC_FORMAT_LEN_SIZE_T"u", + file->size); +@@ -392,8 +392,7 @@ auth_process_fci(struct sc_card *card, struct sc_file *file, + add_acl_entry(card, file, SC_AC_OP_PIN_CHANGE, attr[5]); + add_acl_entry(card, file, SC_AC_OP_PIN_RESET, attr[6]); + sc_log(card->ctx, "SC_FILE_TYPE_DF:CRYPTO %X", attr[1]); +- } +- else if (file->type == SC_FILE_TYPE_INTERNAL_EF) { /* EF */ ++ } else if (file->type == SC_FILE_TYPE_INTERNAL_EF) { /* EF */ + switch (file->ef_structure) { + case SC_CARDCTL_OBERTHUR_KEY_DES: + add_acl_entry(card, file, SC_AC_OP_UPDATE, attr[0]); +@@ -417,8 +416,7 @@ auth_process_fci(struct sc_card *card, struct sc_file *file, + add_acl_entry(card, file, SC_AC_OP_INTERNAL_AUTHENTICATE, attr[5]); + break; + } +- } +- else { ++ } else { + switch (file->ef_structure) { + case SC_FILE_EF_TRANSPARENT: + add_acl_entry(card, file, SC_AC_OP_WRITE, attr[0]); +@@ -467,7 +465,7 @@ auth_select_file(struct sc_card *card, const struct sc_path *in_path, + sc_log(card->ctx, "current file; type=%d, path=%s", + auth_current_ef->path.type, sc_print_path(&auth_current_ef->path)); + +- if (path.type == SC_PATH_TYPE_PARENT || path.type == SC_PATH_TYPE_FILE_ID) { ++ if (path.type == SC_PATH_TYPE_PARENT || path.type == SC_PATH_TYPE_FILE_ID) { + sc_file_free(auth_current_ef); + auth_current_ef = NULL; + +@@ -476,7 +474,7 @@ auth_select_file(struct sc_card *card, const struct sc_path *in_path, + if (!tmp_file) + return SC_ERROR_OBJECT_NOT_FOUND; + +- if (path.type == SC_PATH_TYPE_PARENT) { ++ if (path.type == SC_PATH_TYPE_PARENT) { + memcpy(&tmp_file->path, &auth_current_df->path, sizeof(struct sc_path)); + if (tmp_file->path.len > 2) + tmp_file->path.len -= 2; +@@ -484,16 +482,14 @@ auth_select_file(struct sc_card *card, const struct sc_path *in_path, + sc_file_free(auth_current_df); + auth_current_df = NULL; + sc_file_dup(&auth_current_df, tmp_file); +- } +- else { +- if (tmp_file->type == SC_FILE_TYPE_DF) { ++ } else { ++ if (tmp_file->type == SC_FILE_TYPE_DF) { + sc_concatenate_path(&tmp_file->path, &auth_current_df->path, &path); + + sc_file_free(auth_current_df); + auth_current_df = NULL; + sc_file_dup(&auth_current_df, tmp_file); +- } +- else { ++ } else { + sc_file_free(auth_current_ef); + auth_current_ef = NULL; + +@@ -507,28 +503,26 @@ auth_select_file(struct sc_card *card, const struct sc_path *in_path, + } + + sc_file_free(tmp_file); +- } +- else if (path.type == SC_PATH_TYPE_DF_NAME) { ++ } else if (path.type == SC_PATH_TYPE_DF_NAME) { + rv = iso_ops->select_file(card, &path, NULL); +- if (rv) { ++ if (rv) { + sc_file_free(auth_current_ef); + auth_current_ef = NULL; + } + LOG_TEST_RET(card->ctx, rv, "select file failed"); +- } +- else { ++ } else { + for (offs = 0; offs < path.len && offs < auth_current_df->path.len; offs += 2) + if (path.value[offs] != auth_current_df->path.value[offs] || + path.value[offs + 1] != auth_current_df->path.value[offs + 1]) + break; + + sc_log(card->ctx, "offs %"SC_FORMAT_LEN_SIZE_T"u", offs); +- if (offs && offs < auth_current_df->path.len) { ++ if (offs && offs < auth_current_df->path.len) { + size_t deep = auth_current_df->path.len - offs; + + sc_log(card->ctx, "deep %"SC_FORMAT_LEN_SIZE_T"u", + deep); +- for (ii=0; iipath, sizeof(struct sc_path)); +@@ -539,21 +533,20 @@ auth_select_file(struct sc_card *card, const struct sc_path *in_path, + } + } + +- if (path.len > offs) { ++ if (path.len > offs) { + struct sc_path tmp_path; + + memset(&tmp_path, 0, sizeof(struct sc_path)); + tmp_path.type = SC_PATH_TYPE_FILE_ID; + tmp_path.len = 2; + +- for (ii=0; ii < path.len - offs; ii+=2) { ++ for (ii = 0; ii < path.len - offs; ii += 2) { + memcpy(tmp_path.value, path.value + offs + ii, 2); + + rv = auth_select_file(card, &tmp_path, file_out); + LOG_TEST_RET(card->ctx, rv, "select file failed"); + } +- } +- else if (path.len - offs == 0 && file_out) { ++ } else if (path.len - offs == 0 && file_out) { + if (sc_compare_path(&path, &auth_current_df->path)) + sc_file_dup(file_out, auth_current_df); + else if (auth_current_ef) +@@ -590,7 +583,7 @@ auth_list_files(struct sc_card *card, unsigned char *buf, size_t buflen) + if (apdu.resplen == 0x100 && rbuf[0]==0 && rbuf[1]==0) + LOG_FUNC_RETURN(card->ctx, 0); + +- buflen = buflen < apdu.resplen ? buflen : apdu.resplen; ++ buflen = MIN(buflen, apdu.resplen); + memcpy(buf, rbuf, buflen); + + LOG_FUNC_RETURN(card->ctx, buflen); +@@ -613,12 +606,12 @@ auth_delete_file(struct sc_card *card, const struct sc_path *path) + + sc_log(card->ctx, "path; type=%d, path=%s", path->type, pbuf); + +- if (path->len < 2) { ++ if (path->len < 2) { + sc_log(card->ctx, "Invalid path length"); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + } + +- if (path->len > 2) { ++ if (path->len > 2) { + struct sc_path parent = *path; + + parent.len -= 2; +@@ -641,7 +634,7 @@ auth_delete_file(struct sc_card *card, const struct sc_path *path) + + rv = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, rv, "APDU transmit failed"); +- if (apdu.sw1==0x6A && apdu.sw2==0x82) { ++ if (apdu.sw1 == 0x6A && apdu.sw2 == 0x82) { + /* Clean up tDF contents.*/ + struct sc_path tmp_path; + int ii, len; +@@ -657,7 +650,7 @@ auth_delete_file(struct sc_card *card, const struct sc_path *path) + len = auth_list_files(card, lbuf, sizeof(lbuf)); + LOG_TEST_RET(card->ctx, len, "list DF failed"); + +- for (ii=0; iitype == SC_FILE_TYPE_DF) { ++ if (file->type == SC_FILE_TYPE_DF) { + p[4] = 0x38; + p[5] = 0x00; +- } +- else if (file->type == SC_FILE_TYPE_WORKING_EF) { ++ } else if (file->type == SC_FILE_TYPE_WORKING_EF) { + switch (file->ef_structure) { + case SC_FILE_EF_TRANSPARENT: + p[4] = 0x01; +@@ -758,8 +750,7 @@ encode_file_structure_V5(struct sc_card *card, const struct sc_file *file, + rv = SC_ERROR_INVALID_ARGUMENTS; + break; + } +- } +- else if (file->type == SC_FILE_TYPE_INTERNAL_EF) { ++ } else if (file->type == SC_FILE_TYPE_INTERNAL_EF) { + switch (file->ef_structure) { + case SC_CARDCTL_OBERTHUR_KEY_DES: + p[4] = 0x11; +@@ -777,11 +768,10 @@ encode_file_structure_V5(struct sc_card *card, const struct sc_file *file, + rv = -1; + break; + } +- } +- else ++ } else + rv = SC_ERROR_INVALID_ARGUMENTS; + +- if (rv) { ++ if (rv) { + sc_log(card->ctx, "Invalid EF structure 0x%X/0x%X", file->type, file->ef_structure); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INCORRECT_PARAMETERS); + } +@@ -796,11 +786,10 @@ encode_file_structure_V5(struct sc_card *card, const struct sc_file *file, + + size = file->size; + +- if (file->type == SC_FILE_TYPE_DF) { ++ if (file->type == SC_FILE_TYPE_DF) { + size &= 0xFF; +- } +- else if (file->type == SC_FILE_TYPE_INTERNAL_EF && +- file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC) { ++ } else if (file->type == SC_FILE_TYPE_INTERNAL_EF && ++ file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC) { + sc_log(card->ctx, "ef %s","SC_FILE_EF_RSA_PUBLIC"); + if (file->size == PUBKEY_512_ASN1_SIZE || file->size == 512) + size = 512; +@@ -808,22 +797,21 @@ encode_file_structure_V5(struct sc_card *card, const struct sc_file *file, + size = 1024; + else if (file->size == PUBKEY_2048_ASN1_SIZE || file->size == 2048) + size = 2048; +- else { ++ else { + sc_log(card->ctx, + "incorrect RSA size %"SC_FORMAT_LEN_SIZE_T"X", + file->size); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INCORRECT_PARAMETERS); + } +- } +- else if (file->type == SC_FILE_TYPE_INTERNAL_EF && +- file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_DES) { ++ } else if (file->type == SC_FILE_TYPE_INTERNAL_EF && ++ file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_DES) { + if (file->size == 8 || file->size == 64) + size = 64; + else if (file->size == 16 || file->size == 128) + size = 128; + else if (file->size == 24 || file->size == 192) + size = 192; +- else { ++ else { + sc_log(card->ctx, + "incorrect DES size %"SC_FORMAT_LEN_SIZE_T"u", + file->size); +@@ -845,25 +833,22 @@ encode_file_structure_V5(struct sc_card *card, const struct sc_file *file, + ops[4] = SC_AC_OP_PIN_DEFINE; + ops[5] = SC_AC_OP_PIN_CHANGE; + ops[6] = SC_AC_OP_PIN_RESET; +- } +- else if (file->type == SC_FILE_TYPE_WORKING_EF) { +- if (file->ef_structure == SC_FILE_EF_TRANSPARENT) { ++ } else if (file->type == SC_FILE_TYPE_WORKING_EF) { ++ if (file->ef_structure == SC_FILE_EF_TRANSPARENT) { + sc_log(card->ctx, "SC_FILE_EF_TRANSPARENT"); + ops[0] = SC_AC_OP_WRITE; + ops[1] = SC_AC_OP_UPDATE; + ops[2] = SC_AC_OP_READ; + ops[3] = SC_AC_OP_ERASE; +- } +- else if (file->ef_structure == SC_FILE_EF_LINEAR_VARIABLE) { ++ } else if (file->ef_structure == SC_FILE_EF_LINEAR_VARIABLE) { + sc_log(card->ctx, "SC_FILE_EF_LINEAR_VARIABLE"); + ops[0] = SC_AC_OP_WRITE; + ops[1] = SC_AC_OP_UPDATE; + ops[2] = SC_AC_OP_READ; + ops[3] = SC_AC_OP_ERASE; + } +- } +- else if (file->type == SC_FILE_TYPE_INTERNAL_EF) { +- if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_DES) { ++ } else if (file->type == SC_FILE_TYPE_INTERNAL_EF) { ++ if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_DES) { + sc_log(card->ctx, "EF_DES"); + ops[0] = SC_AC_OP_UPDATE; + ops[1] = SC_AC_OP_PSO_DECRYPT; +@@ -872,15 +857,13 @@ encode_file_structure_V5(struct sc_card *card, const struct sc_file *file, + ops[4] = SC_AC_OP_PSO_VERIFY_CHECKSUM; + ops[5] = SC_AC_OP_INTERNAL_AUTHENTICATE; + ops[6] = SC_AC_OP_EXTERNAL_AUTHENTICATE; +- } +- else if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC) { ++ } else if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC) { + sc_log(card->ctx, "EF_RSA_PUBLIC"); + ops[0] = SC_AC_OP_UPDATE; + ops[2] = SC_AC_OP_PSO_ENCRYPT; + ops[4] = SC_AC_OP_PSO_VERIFY_SIGNATURE; + ops[6] = SC_AC_OP_EXTERNAL_AUTHENTICATE; +- } +- else if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_CRT) { ++ } else if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_CRT) { + sc_log(card->ctx, "EF_RSA_PRIVATE"); + ops[0] = SC_AC_OP_UPDATE; + ops[1] = SC_AC_OP_PSO_DECRYPT; +@@ -935,12 +918,12 @@ auth_create_file(struct sc_card *card, struct sc_file *file) + if (rv != SC_SUCCESS) + pbuf[0] = '\0'; + +- if (file->path.len) { ++ if (file->path.len) { + memcpy(&path, &file->path, sizeof(path)); + if (path.len>2) + path.len -= 2; + +- if (auth_select_file(card, &path, NULL)) { ++ if (auth_select_file(card, &path, NULL)) { + sc_log(card->ctx, "Cannot select parent DF."); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + } +@@ -965,7 +948,7 @@ auth_create_file(struct sc_card *card, struct sc_file *file) + LOG_TEST_RET(card->ctx, rv, "Card returned error"); + + /* select created DF. */ +- if (file->type == SC_FILE_TYPE_DF) { ++ if (file->type == SC_FILE_TYPE_DF) { + struct sc_path tmp_path; + struct sc_file *df_file = NULL; + +@@ -1014,20 +997,19 @@ auth_set_security_env(struct sc_card *card, + if (!(env->flags & SC_SEC_ENV_FILE_REF_PRESENT)) + LOG_TEST_RET(card->ctx, SC_ERROR_INTERNAL, "Key file is not selected."); + +- switch (env->algorithm) { ++ switch (env->algorithm) { + case SC_ALGORITHM_DES: + case SC_ALGORITHM_3DES: + sc_log(card->ctx, + "algo SC_ALGORITHM_xDES: ref %X, flags %lX", + env->algorithm_ref, env->flags); + +- if (env->operation == SC_SEC_OPERATION_DECIPHER) { ++ if (env->operation == SC_SEC_OPERATION_DECIPHER) { + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0xB8); + apdu.lc = 3; + apdu.data = des_sbuf; + apdu.datalen = 3; +- } +- else { ++ } else { + sc_log(card->ctx, "Invalid crypto operation: %X", env->operation); + LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "Invalid crypto operation"); + } +@@ -1039,28 +1021,26 @@ auth_set_security_env(struct sc_card *card, + LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "No support for hashes."); + } + +- if (pads & (~supported_pads)) { ++ if (pads & (~supported_pads)) { + sc_log(card->ctx, "No support for PAD %lX", pads); + LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "No padding support."); + } + +- if (env->operation == SC_SEC_OPERATION_SIGN) { ++ if (env->operation == SC_SEC_OPERATION_SIGN) { + rsa_sbuf[2] = 0x11; + + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0xB6); + apdu.lc = sizeof(rsa_sbuf); + apdu.datalen = sizeof(rsa_sbuf); + apdu.data = rsa_sbuf; +- } +- else if (env->operation == SC_SEC_OPERATION_DECIPHER) { ++ } else if (env->operation == SC_SEC_OPERATION_DECIPHER) { + rsa_sbuf[2] = 0x11; + + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0xB8); + apdu.lc = sizeof(rsa_sbuf); + apdu.datalen = sizeof(rsa_sbuf); + apdu.data = rsa_sbuf; +- } +- else { ++ } else { + sc_log(card->ctx, "Invalid crypto operation: %X", env->operation); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + } +@@ -1096,10 +1076,9 @@ auth_compute_signature(struct sc_card *card, const unsigned char *in, size_t ile + unsigned char resp[SC_MAX_APDU_BUFFER_SIZE]; + int rv; + +- if (!card || !in || !out) { ++ if (!card || !in || !out) { + return SC_ERROR_INVALID_ARGUMENTS; +- } +- else if (ilen > 96) { ++ } else if (ilen > 96) { + sc_log(card->ctx, + "Illegal input length %"SC_FORMAT_LEN_SIZE_T"u", + ilen); +@@ -1115,16 +1094,16 @@ auth_compute_signature(struct sc_card *card, const unsigned char *in, size_t ile + apdu.datalen = ilen; + apdu.data = in; + apdu.lc = ilen; +- apdu.le = olen > 256 ? 256 : olen; ++ apdu.le = MIN(olen, SC_MAX_APDU_RESP_SIZE); + apdu.resp = resp; +- apdu.resplen = olen; ++ apdu.resplen = SC_MAX_APDU_BUFFER_SIZE; + + rv = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, rv, "APDU transmit failed"); + rv = sc_check_sw(card, apdu.sw1, apdu.sw2); + LOG_TEST_RET(card->ctx, rv, "Compute signature failed"); + +- if (apdu.resplen > olen) { ++ if (apdu.resplen > olen) { + sc_log(card->ctx, + "Compute signature failed: invalid response length %"SC_FORMAT_LEN_SIZE_T"u", + apdu.resplen); +@@ -1155,20 +1134,20 @@ auth_decipher(struct sc_card *card, const unsigned char *in, size_t inlen, + sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x80, 0x86); + + sc_log(card->ctx, "algorithm SC_ALGORITHM_RSA"); +- if (inlen % 64) { ++ if (inlen % 64) { + rv = SC_ERROR_INVALID_ARGUMENTS; + goto done; + } + + _inlen = inlen; +- if (_inlen == 256) { ++ if (_inlen == SC_MAX_APDU_RESP_SIZE) { + apdu.cla |= 0x10; + apdu.data = in; + apdu.datalen = 8; + apdu.resp = resp; + apdu.resplen = SC_MAX_APDU_BUFFER_SIZE; + apdu.lc = 8; +- apdu.le = 256; ++ apdu.le = SC_MAX_APDU_RESP_SIZE; + + rv = sc_transmit_apdu(card, &apdu); + sc_log(card->ctx, "rv %i", rv); +@@ -1246,7 +1225,7 @@ auth_generate_key(struct sc_card *card, int use_sm, + + LOG_FUNC_CALLED(card->ctx); + if (data->key_bits < 512 || data->key_bits > 2048 || +- (data->key_bits%0x20)!=0) { ++ (data->key_bits % 0x20) != 0) { + LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Illegal key length"); + } + +@@ -1254,7 +1233,7 @@ auth_generate_key(struct sc_card *card, int use_sm, + sbuf[1] = data->id_pub & 0xFF; + sbuf[2] = (data->id_prv >> 8) & 0xFF; + sbuf[3] = data->id_prv & 0xFF; +- if (data->exponent != 0x10001) { ++ if (data->exponent != 0x10001) { + rv = auth_encode_exponent(data->exponent, &sbuf[5],SC_MAX_APDU_BUFFER_SIZE-6); + LOG_TEST_RET(card->ctx, rv, "Cannot encode exponent"); + +@@ -1292,7 +1271,7 @@ auth_generate_key(struct sc_card *card, int use_sm, + + apdu.resplen = rv; + +- if (data->pubkey) { ++ if (data->pubkey) { + if (data->pubkey_len < apdu.resplen) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + +@@ -1331,7 +1310,7 @@ auth_update_component(struct sc_card *card, struct auth_update_component_info *a + memcpy(sbuf + len, args->data, args->len); + len += args->len; + +- if (args->type == SC_CARDCTL_OBERTHUR_KEY_DES) { ++ if (args->type == SC_CARDCTL_OBERTHUR_KEY_DES) { + int outl; + const unsigned char in[8] = {0,0,0,0,0,0,0,0}; + unsigned char out[8]; +@@ -1359,8 +1338,7 @@ auth_update_component(struct sc_card *card, struct auth_update_component_info *a + sbuf[len++] = 0x03; + memcpy(sbuf + len, out, 3); + len += 3; +- } +- else { ++ } else { + sbuf[len++] = 0; + } + +@@ -1369,7 +1347,7 @@ auth_update_component(struct sc_card *card, struct auth_update_component_info *a + apdu.data = sbuf; + apdu.datalen = len; + apdu.lc = len; +- if (args->len == 0x100) { ++ if (args->len == 0x100) { + sbuf[0] = args->type; + sbuf[1] = 0x20; + memcpy(sbuf + 2, args->data, 0x20); +@@ -1410,7 +1388,7 @@ auth_update_key(struct sc_card *card, struct sc_cardctl_oberthur_updatekey_info + if (info->data_len != sizeof(void *) || !info->data) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + +- if (info->type == SC_CARDCTL_OBERTHUR_KEY_RSA_CRT) { ++ if (info->type == SC_CARDCTL_OBERTHUR_KEY_RSA_CRT) { + struct sc_pkcs15_prkey_rsa *rsa = (struct sc_pkcs15_prkey_rsa *)info->data; + struct sc_pkcs15_bignum bn[5]; + +@@ -1420,7 +1398,7 @@ auth_update_key(struct sc_card *card, struct sc_cardctl_oberthur_updatekey_info + bn[2] = rsa->iqmp; + bn[3] = rsa->dmp1; + bn[4] = rsa->dmq1; +- for (ii=0;ii<5;ii++) { ++ for (ii = 0; ii < 5; ii++) { + struct auth_update_component_info args; + + memset(&args, 0, sizeof(args)); +@@ -1432,11 +1410,9 @@ auth_update_key(struct sc_card *card, struct sc_cardctl_oberthur_updatekey_info + rv = auth_update_component(card, &args); + LOG_TEST_RET(card->ctx, rv, "Update RSA component failed"); + } +- } +- else if (info->type == SC_CARDCTL_OBERTHUR_KEY_DES) { ++ } else if (info->type == SC_CARDCTL_OBERTHUR_KEY_DES) { + rv = SC_ERROR_NOT_SUPPORTED; +- } +- else { ++ } else { + rv = SC_ERROR_INVALID_DATA; + } + +@@ -1477,7 +1453,7 @@ auth_read_component(struct sc_card *card, enum SC_CARDCTL_OBERTHUR_KEY_TYPE type + { + struct sc_apdu apdu; + int rv; +- unsigned char resp[256]; ++ unsigned char resp[SC_MAX_APDU_RESP_SIZE]; + + LOG_FUNC_CALLED(card->ctx); + sc_log(card->ctx, "num %i, outlen %"SC_FORMAT_LEN_SIZE_T"u, type %i", +@@ -1538,11 +1514,10 @@ auth_init_pin_info(struct sc_card *card, struct sc_pin_cmd_pin *pin, + pin->pad_char = 0xFF; + pin->encoding = SC_PIN_ENCODING_ASCII; + +- if (type == OBERTHUR_AUTH_TYPE_PIN) { ++ if (type == OBERTHUR_AUTH_TYPE_PIN) { + pin->max_length = OBERTHUR_AUTH_MAX_LENGTH_PIN; + pin->pad_length = OBERTHUR_AUTH_MAX_LENGTH_PIN; +- } +- else { ++ } else { + pin->max_length = OBERTHUR_AUTH_MAX_LENGTH_PUK; + pin->pad_length = OBERTHUR_AUTH_MAX_LENGTH_PUK; + } +@@ -1662,7 +1637,7 @@ auth_pin_is_verified(struct sc_card *card, int pin_reference, int *tries_left) + *tries_left = apdu.sw2 & 0x0F; + + /* Replace 'no tries left' with 'auth method blocked' */ +- if (apdu.sw1 == 0x63 && apdu.sw2 == 0xC0) { ++ if (apdu.sw1 == 0x63 && apdu.sw2 == 0xC0) { + apdu.sw1 = 0x69; + apdu.sw2 = 0x83; + } +@@ -1739,7 +1714,7 @@ auth_pin_change(struct sc_card *card, unsigned int type, + + LOG_FUNC_CALLED(card->ctx); + +- if (data->pin1.len && data->pin2.len) { ++ if (data->pin1.len && data->pin2.len) { + /* Direct unblock style */ + data->flags |= SC_PIN_CMD_NEED_PADDING; + data->flags &= ~SC_PIN_CMD_USE_PINPAD; +@@ -1752,13 +1727,11 @@ auth_pin_change(struct sc_card *card, unsigned int type, + + rv = iso_drv->ops->pin_cmd(card, data, tries_left); + LOG_TEST_RET(card->ctx, rv, "CMD 'PIN CHANGE' failed"); +- } +- else if (!data->pin1.len && !data->pin2.len) { ++ } else if (!data->pin1.len && !data->pin2.len) { + /* Oberthur unblock style with PIN pad. */ + rv = auth_pin_change_pinpad(card, data, tries_left); + LOG_TEST_RET(card->ctx, rv, "'PIN CHANGE' failed: SOPIN verify with pinpad failed"); +- } +- else { ++ } else { + LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "'PIN CHANGE' failed"); + } + +@@ -1821,7 +1794,7 @@ auth_pin_reset_oberthur_style(struct sc_card *card, unsigned int type, + pin_cmd.pin1.data = ffs1; + pin_cmd.pin1.len = OBERTHUR_AUTH_MAX_LENGTH_PUK; + +- if (data->pin2.data) { ++ if (data->pin2.data) { + memcpy(&pin_cmd.pin2, &data->pin2, sizeof(pin_cmd.pin2)); + rv = auth_pin_reset(card, SC_AC_CHV, &pin_cmd, tries_left); + LOG_FUNC_RETURN(card->ctx, rv); +@@ -1956,7 +1929,7 @@ auth_create_reference_data (struct sc_card *card, + len += pin_info.pad_length; + sc_log(card->ctx, "len %i", len); + +- if (args->puk && args->puk_len) { ++ if (args->puk && args->puk_len) { + sbuf[len++] = args->puk_tries; + sbuf[len++] = args->puk_len / puk_info.pad_length; + sc_log(card->ctx, "len %i", len); +@@ -1987,7 +1960,7 @@ auth_logout(struct sc_card *card) + int ii, rv = 0, pin_ref; + int reset_flag = 0x20; + +- for (ii=0; ii < 4; ii++) { ++ for (ii = 0; ii < 4; ii++) { + rv = auth_get_pin_reference (card, SC_AC_CHV, ii+1, SC_PIN_CMD_UNBLOCK, &pin_ref); + LOG_TEST_RET(card->ctx, rv, "Cannot get PIN reference"); + +@@ -1996,7 +1969,6 @@ auth_logout(struct sc_card *card) + apdu.p2 = pin_ref | reset_flag; + rv = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, rv, "APDU transmit failed"); +- + } + + LOG_FUNC_RETURN(card->ctx, rv); +@@ -2024,7 +1996,7 @@ write_publickey (struct sc_card *card, unsigned int offset, + memcpy(rsa_der + offset, buf, len); + rsa_der_len = offset + len; + +- if (rsa_der[0]==0x30) { ++ if (rsa_der[0] == 0x30) { + if (rsa_der[1] & 0x80) + for (ii=0; ii < (rsa_der[1]&0x0F); ii++) + der_size = der_size*0x100 + rsa_der[2+ii]; +@@ -2080,12 +2052,11 @@ auth_update_binary(struct sc_card *card, unsigned int offset, + if (offset & ~0x7FFF) + LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid file offset"); + +- if (auth_current_ef->magic==SC_FILE_MAGIC && +- auth_current_ef->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC) { ++ if (auth_current_ef->magic == SC_FILE_MAGIC && ++ auth_current_ef->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC) { + rv = write_publickey(card, offset, buf, count); +- } +- else if (auth_current_ef->magic==SC_FILE_MAGIC && +- auth_current_ef->ef_structure == SC_CARDCTL_OBERTHUR_KEY_DES) { ++ } else if (auth_current_ef->magic == SC_FILE_MAGIC && ++ auth_current_ef->ef_structure == SC_CARDCTL_OBERTHUR_KEY_DES) { + struct auth_update_component_info args; + + memset(&args, 0, sizeof(args)); +@@ -2093,8 +2064,7 @@ auth_update_binary(struct sc_card *card, unsigned int offset, + args.data = (unsigned char *)buf; + args.len = count; + rv = auth_update_component(card, &args); +- } +- else { ++ } else { + rv = iso_ops->update_binary(card, offset, buf, count, 0); + } + +@@ -2126,10 +2096,10 @@ auth_read_binary(struct sc_card *card, unsigned int offset, + if (offset & ~0x7FFF) + LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid file offset"); + +- if (auth_current_ef->magic==SC_FILE_MAGIC && +- auth_current_ef->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC) { ++ if (auth_current_ef->magic == SC_FILE_MAGIC && ++ auth_current_ef->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC) { + int jj; +- unsigned char resp[256]; ++ unsigned char resp[SC_MAX_APDU_RESP_SIZE]; + size_t resp_len, out_len; + struct sc_pkcs15_pubkey_rsa key; + +@@ -2180,8 +2150,7 @@ auth_read_binary(struct sc_card *card, unsigned int offset, + + sc_log_hex(card->ctx, "write_publickey", buf, rv); + } +- } +- else { ++ } else { + rv = iso_ops->read_binary(card, offset, buf, count, 0); + } + +@@ -2214,14 +2183,16 @@ auth_read_record(struct sc_card *card, unsigned int nr_rec, + if (flags & SC_RECORD_BY_REC_NR) + apdu.p2 |= 0x04; + +- apdu.le = count; +- apdu.resplen = count; ++ apdu.le = MIN(count, SC_MAX_APDU_BUFFER_SIZE); ++ apdu.resplen = SC_MAX_APDU_BUFFER_SIZE; + apdu.resp = recvbuf; + + rv = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, rv, "APDU transmit failed"); + if (apdu.resplen == 0) + LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2)); ++ if (count < apdu.resplen) ++ LOG_FUNC_RETURN(card->ctx, SC_ERROR_WRONG_LENGTH); + memcpy(buf, recvbuf, apdu.resplen); + + rv = sc_check_sw(card, apdu.sw1, apdu.sw2); +@@ -2279,8 +2250,8 @@ auth_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2) + { + int ii; + +- for (ii=0; auth_warnings[ii].SWs; ii++) { +- if (auth_warnings[ii].SWs == ((sw1 << 8) | sw2)) { ++ for (ii = 0; auth_warnings[ii].SWs; ii++) { ++ if (auth_warnings[ii].SWs == ((sw1 << 8) | sw2)) { + sc_log(card->ctx, "%s", auth_warnings[ii].errorstr); + return auth_warnings[ii].errorno; + } +-- +2.45.4 + diff --git a/SPECS/opensc/opensc.spec b/SPECS/opensc/opensc.spec index 2cf07ff1e7c..2a7934b2706 100644 --- a/SPECS/opensc/opensc.spec +++ b/SPECS/opensc/opensc.spec @@ -3,7 +3,7 @@ Summary: Smart card library and applications Name: opensc Version: 0.23.0 -Release: 5%{?dist} +Release: 6%{?dist} License: LGPLv2+ Vendor: Microsoft Corporation Distribution: Mariner @@ -17,6 +17,9 @@ Patch4: CVE-2024-1454.patch Patch5: CVE-2023-40660.patch Patch6: CVE-2023-40661.patch Patch7: CVE-2024-45619.patch +Patch8: CVE-2025-49010.patch +Patch9: CVE-2025-66037.patch +Patch10: CVE-2025-66215.patch BuildRequires: autoconf BuildRequires: automake BuildRequires: bash-completion @@ -146,6 +149,9 @@ rm %{buildroot}%{_mandir}/man1/opensc-notify.1* %{_mandir}/man5/* %changelog +* Fri Apr 03 2026 Azure Linux Security Servicing Account - 0.23.0-6 +- Patch for CVE-2025-66215, CVE-2025-66037, CVE-2025-49010 + * Fri May 16 2025 Akhila Guruju - 0.23.0-5 - Patch CVE-2023-40661 and CVE-2024-45619