Compare commits
11 Commits
a525b6afb7
...
292be3dd19
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
292be3dd19 | ||
|
|
955439d2aa | ||
|
|
442fd77cf4 | ||
|
|
75204ca35d | ||
|
|
564062ac7b | ||
|
|
1d6ca8a1ff | ||
|
|
251c7db3f7 | ||
|
|
e2cd5ca55b | ||
|
|
564a9f86a4 | ||
|
|
0e0a01c0ab | ||
|
|
983b06c889 |
@ -0,0 +1,26 @@
|
|||||||
|
From ae1cf0be90396fb6c0be95829bf0d3eecbd2fd1c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jakub Jelen <jjelen@redhat.com>
|
||||||
|
Date: Thu, 11 Feb 2021 11:22:54 +0100
|
||||||
|
Subject: [PATCH] iasecc: Prevent stack buffer overflow when empty ACL is
|
||||||
|
returned
|
||||||
|
|
||||||
|
Thanks oss-fuzz
|
||||||
|
|
||||||
|
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=30800
|
||||||
|
---
|
||||||
|
src/libopensc/card-iasecc.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c
|
||||||
|
index 166bc307bc..0eec63363a 100644
|
||||||
|
--- a/src/libopensc/card-iasecc.c
|
||||||
|
+++ b/src/libopensc/card-iasecc.c
|
||||||
|
@@ -1251,7 +1251,7 @@ iasecc_process_fci(struct sc_card *card, struct sc_file *file,
|
||||||
|
else
|
||||||
|
acls = sc_asn1_find_tag(ctx, buf, buflen, IASECC_DOCP_TAG_ACLS_CONTACT, &taglen);
|
||||||
|
|
||||||
|
- if (!acls) {
|
||||||
|
+ if (!acls || taglen < 7) {
|
||||||
|
sc_log(ctx,
|
||||||
|
"ACLs not found in data(%"SC_FORMAT_LEN_SIZE_T"u) %s",
|
||||||
|
buflen, sc_dump_hex(buf, buflen));
|
||||||
50
0003-opensc-CVE-2023-40660-1of2.patch
Normal file
50
0003-opensc-CVE-2023-40660-1of2.patch
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
From 74ddc3636db18ae78de62922a74bfdefae015c76 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Frank Morgner <frankmorgner@gmail.com>
|
||||||
|
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)
|
||||||
513
0004-opensc-CVE-2023-40660-2of2.patch
Normal file
513
0004-opensc-CVE-2023-40660-2of2.patch
Normal file
@ -0,0 +1,513 @@
|
|||||||
|
From d7fadae950f6d33b32f979759c06ab78a3475c22 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Frank Morgner <frankmorgner@gmail.com>
|
||||||
|
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;
|
||||||
|
}
|
||||||
54
0005-opensc-NULL_pointer_fix.patch
Normal file
54
0005-opensc-NULL_pointer_fix.patch
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
From cde2e050ec4f2f1b7db38429aa4e9c0f4656308c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Popovec <popovec.peter@gmail.com>
|
||||||
|
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;
|
||||||
39
0006-opensc-CVE-2023-4535.patch
Normal file
39
0006-opensc-CVE-2023-4535.patch
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
From f1993dc4e0b33050b8f72a3558ee88b24c4063b2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Popovec <popovec.peter@gmail.com>
|
||||||
|
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;
|
||||||
23
0007-opensc-CVE-2023-40661-1of12.patch
Normal file
23
0007-opensc-CVE-2023-40661-1of12.patch
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
From 578aed8391ef117ca64a9e0cba8e5c264368a0ec Mon Sep 17 00:00:00 2001
|
||||||
|
From: Frank Morgner <frankmorgner@gmail.com>
|
||||||
|
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--) {
|
||||||
25
0008-opensc-CVE-2023-40661-2of12.patch
Normal file
25
0008-opensc-CVE-2023-40661-2of12.patch
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
From df5a176bfdf8c52ba89c7fef1f82f6f3b9312bc1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Veronika Hanulikova <xhanulik@fi.muni.cz>
|
||||||
|
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)
|
||||||
37
0009-opensc-CVE-2023-40661-3of12.patch
Normal file
37
0009-opensc-CVE-2023-40661-3of12.patch
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
From 5631e9843c832a99769def85b7b9b68b4e3e3959 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Veronika Hanulikova <xhanulik@fi.muni.cz>
|
||||||
|
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));
|
||||||
|
|
||||||
546
0010-opensc-CVE-2023-40661-4of12.patch
Normal file
546
0010-opensc-CVE-2023-40661-4of12.patch
Normal file
@ -0,0 +1,546 @@
|
|||||||
|
From aadd82bb071e574fc57263a103e3bf06ebbd8de7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Ingo Struck (git commits)" <gitlab@ingostruck.de>
|
||||||
|
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);
|
||||||
|
|
||||||
61
0011-opensc-CVE-2023-40661-5of12.patch
Normal file
61
0011-opensc-CVE-2023-40661-5of12.patch
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
From dd138d0600a1acd7991989127f36827e5836b24e Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Ingo Struck (git commits)" <gitlab@ingostruck.de>
|
||||||
|
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:
|
||||||
25
0012-opensc-CVE-2023-40661-6of12.patch
Normal file
25
0012-opensc-CVE-2023-40661-6of12.patch
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
From c449a181a6988cc1e8dc8764d23574e48cdc3fa6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= <vhanulik@redhat.com>
|
||||||
|
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)
|
||||||
27
0013-opensc-CVE-2023-40661-7of12.patch
Normal file
27
0013-opensc-CVE-2023-40661-7of12.patch
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
From 88880db0307a07e33cf2e1592bb029e9c170dfea Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= <vhanulik@redhat.com>
|
||||||
|
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);
|
||||||
29
0014-opensc-CVE-2023-40661-8of12.patch
Normal file
29
0014-opensc-CVE-2023-40661-8of12.patch
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
From 638a5007a5d240d6fa901aa822cfeef94fe36e85 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= <vhanulik@redhat.com>
|
||||||
|
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);
|
||||||
27
0015-opensc-CVE-2023-40661-9of12.patch
Normal file
27
0015-opensc-CVE-2023-40661-9of12.patch
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
From ce7fcdaa35196706a83fe982900228e15464f928 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jakub Jelen <jjelen@redhat.com>
|
||||||
|
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;
|
||||||
|
}
|
||||||
25
0016-opensc-CVE-2023-40661-10of12.patch
Normal file
25
0016-opensc-CVE-2023-40661-10of12.patch
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
From 440ca666eff10cc7011901252d20f3fc4ea23651 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jakub Jelen <jjelen@redhat.com>
|
||||||
|
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];
|
||||||
|
|
||||||
38
0017-opensc-CVE-2023-40661-11of12.patch
Normal file
38
0017-opensc-CVE-2023-40661-11of12.patch
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
From 245efe608d083fd4e4ec96793fdefd218e26fde7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jakub Jelen <jjelen@redhat.com>
|
||||||
|
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;
|
||||||
26
0018-opensc-CVE-2023-40661-12of12.patch
Normal file
26
0018-opensc-CVE-2023-40661-12of12.patch
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
From 41d61da8481582e12710b5858f8b635e0a71ab5e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jakub Jelen <jjelen@redhat.com>
|
||||||
|
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. */
|
||||||
824
0019-opensc-CVE-2023-5992.patch
Normal file
824
0019-opensc-CVE-2023-5992.patch
Normal file
@ -0,0 +1,824 @@
|
|||||||
|
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
|
||||||
|
index 5153428dce..9ecbffe8fd 100644
|
||||||
|
--- a/src/common/Makefile.am
|
||||||
|
+++ b/src/common/Makefile.am
|
||||||
|
@@ -8,7 +8,8 @@ dist_noinst_DATA = \
|
||||||
|
LICENSE.compat_getopt compat_getopt.txt \
|
||||||
|
compat_getopt_main.c \
|
||||||
|
README.compat_strlcpy compat_strlcpy.3
|
||||||
|
-noinst_HEADERS = compat_strlcat.h compat_strlcpy.h compat_strnlen.h compat_getpass.h compat_getopt.h simclist.h libpkcs11.h libscdl.h
|
||||||
|
+noinst_HEADERS = compat_strlcat.h compat_strlcpy.h compat_strnlen.h compat_getpass.h \
|
||||||
|
+ compat_getopt.h simclist.h libpkcs11.h libscdl.h constant-time.h
|
||||||
|
|
||||||
|
AM_CPPFLAGS = -I$(top_srcdir)/src
|
||||||
|
|
||||||
|
@@ -43,7 +44,8 @@ TIDY_FILES = \
|
||||||
|
compat_report_rangecheckfailure.c \
|
||||||
|
compat___iob_func.c \
|
||||||
|
simclist.c simclist.h \
|
||||||
|
- libpkcs11.c libscdl.c
|
||||||
|
+ libpkcs11.c libscdl.c \
|
||||||
|
+ constant-time.h
|
||||||
|
|
||||||
|
check-local:
|
||||||
|
if [ -x "$(CLANGTIDY)" ]; then clang-tidy -config='' --checks='$(TIDY_CHECKS)' -header-filter=.* $(addprefix $(srcdir)/,$(TIDY_FILES)) -- $(TIDY_FLAGS); fi
|
||||||
|
diff --git a/src/common/constant-time.h b/src/common/constant-time.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..40c3e500c2
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/common/constant-time.h
|
||||||
|
@@ -0,0 +1,134 @@
|
||||||
|
+/* Original source: https://github.com/openssl/openssl/blob/9890cc42daff5e2d0cad01ac4bf78c391f599a6e/include/internal/constant_time.h */
|
||||||
|
+
|
||||||
|
+#ifndef CONSTANT_TIME_H
|
||||||
|
+#define CONSTANT_TIME_H
|
||||||
|
+
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+
|
||||||
|
+#if !defined(inline)
|
||||||
|
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
||||||
|
+#define constant_inline inline
|
||||||
|
+#elif defined(__GNUC__) && __GNUC__ >= 2
|
||||||
|
+#elif defined(__GNUC__) && __GNUC__ >= 2
|
||||||
|
+#elif defined(_MSC_VER)
|
||||||
|
+#define constant_inline __inline
|
||||||
|
+#else
|
||||||
|
+#define constant_inline
|
||||||
|
+#endif
|
||||||
|
+#else /* use what caller wants as inline may be from config.h */
|
||||||
|
+#define constant_inline inline /* inline */
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+/*-
|
||||||
|
+ * The boolean methods return a bitmask of all ones (0xff...f) for true
|
||||||
|
+ * and 0 for false. For example,
|
||||||
|
+ * if (a < b) {
|
||||||
|
+ * c = a;
|
||||||
|
+ * } else {
|
||||||
|
+ * c = b;
|
||||||
|
+ * }
|
||||||
|
+ * can be written as
|
||||||
|
+ * unsigned int lt = constant_time_lt(a, b);
|
||||||
|
+ * c = constant_time_select(lt, a, b);
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+static constant_inline unsigned int
|
||||||
|
+value_barrier(unsigned int a)
|
||||||
|
+{
|
||||||
|
+ volatile unsigned int r = a;
|
||||||
|
+ return r;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static constant_inline size_t
|
||||||
|
+value_barrier_s(size_t a)
|
||||||
|
+{
|
||||||
|
+ volatile size_t r = a;
|
||||||
|
+ return r;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* MSB */
|
||||||
|
+static constant_inline size_t
|
||||||
|
+constant_time_msb_s(size_t a)
|
||||||
|
+{
|
||||||
|
+ return 0 - (a >> (sizeof(a) * 8 - 1));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static constant_inline unsigned int
|
||||||
|
+constant_time_msb(unsigned int a)
|
||||||
|
+{
|
||||||
|
+ return 0 - (a >> (sizeof(a) * 8 - 1));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Select */
|
||||||
|
+static constant_inline unsigned int
|
||||||
|
+constant_time_select(unsigned int mask, unsigned int a, unsigned int b)
|
||||||
|
+{
|
||||||
|
+ return (value_barrier(mask) & a) | (value_barrier(~mask) & b);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static constant_inline unsigned char
|
||||||
|
+constant_time_select_8(unsigned char mask, unsigned char a, unsigned char b)
|
||||||
|
+{
|
||||||
|
+ return (unsigned char)constant_time_select(mask, a, b);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static constant_inline size_t
|
||||||
|
+constant_time_select_s(size_t mask, size_t a, size_t b)
|
||||||
|
+{
|
||||||
|
+ return (value_barrier_s(mask) & a) | (value_barrier_s(~mask) & b);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Zero */
|
||||||
|
+static constant_inline unsigned int
|
||||||
|
+constant_time_is_zero(unsigned int a)
|
||||||
|
+{
|
||||||
|
+ return constant_time_msb(~a & (a - 1));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static constant_inline size_t
|
||||||
|
+constant_time_is_zero_s(size_t a)
|
||||||
|
+{
|
||||||
|
+ return constant_time_msb_s(~a & (a - 1));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Comparison*/
|
||||||
|
+static constant_inline size_t
|
||||||
|
+constant_time_lt_s(size_t a, size_t b)
|
||||||
|
+{
|
||||||
|
+ return constant_time_msb_s(a ^ ((a ^ b) | ((a - b) ^ b)));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static constant_inline unsigned int
|
||||||
|
+constant_time_lt(unsigned int a, unsigned int b)
|
||||||
|
+{
|
||||||
|
+ return constant_time_msb(a ^ ((a ^ b) | ((a - b) ^ b)));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static constant_inline unsigned int
|
||||||
|
+constant_time_ge(unsigned int a, unsigned int b)
|
||||||
|
+{
|
||||||
|
+ return ~constant_time_lt(a, b);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Equality*/
|
||||||
|
+
|
||||||
|
+static constant_inline unsigned int
|
||||||
|
+constant_time_eq(unsigned int a, unsigned int b)
|
||||||
|
+{
|
||||||
|
+ return constant_time_is_zero(a ^ b);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static constant_inline size_t
|
||||||
|
+constant_time_eq_s(size_t a, size_t b)
|
||||||
|
+{
|
||||||
|
+ return constant_time_is_zero_s(a ^ b);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static constant_inline unsigned int
|
||||||
|
+constant_time_eq_i(int a, int b)
|
||||||
|
+{
|
||||||
|
+ return constant_time_eq((unsigned int)a, (unsigned int)b);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#endif /* CONSTANT_TIME_H */
|
||||||
|
diff --git a/src/libopensc/internal.h b/src/libopensc/internal.h
|
||||||
|
index 7531260c14..2a98f0e966 100644
|
||||||
|
--- a/src/libopensc/internal.h
|
||||||
|
+++ b/src/libopensc/internal.h
|
||||||
|
@@ -175,8 +175,8 @@ int _sc_card_add_xeddsa_alg(struct sc_card *card, size_t key_length,
|
||||||
|
|
||||||
|
int sc_pkcs1_strip_01_padding(struct sc_context *ctx, const u8 *in_dat, size_t in_len,
|
||||||
|
u8 *out_dat, size_t *out_len);
|
||||||
|
-int sc_pkcs1_strip_02_padding(struct sc_context *ctx, const u8 *data, size_t len,
|
||||||
|
- u8 *out_dat, size_t *out_len);
|
||||||
|
+int sc_pkcs1_strip_02_padding_constant_time(sc_context_t *ctx, unsigned int n, const u8 *data,
|
||||||
|
+ unsigned int data_len, u8 *out, unsigned int *out_len);
|
||||||
|
int sc_pkcs1_strip_digest_info_prefix(unsigned int *algorithm,
|
||||||
|
const u8 *in_dat, size_t in_len, u8 *out_dat, size_t *out_len);
|
||||||
|
#ifdef ENABLE_OPENSSL
|
||||||
|
diff --git a/src/libopensc/padding.c b/src/libopensc/padding.c
|
||||||
|
index ca47733a4e..ddb3061134 100644
|
||||||
|
--- a/src/libopensc/padding.c
|
||||||
|
+++ b/src/libopensc/padding.c
|
||||||
|
@@ -32,10 +32,13 @@
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
+#include "common/constant-time.h"
|
||||||
|
#include "internal.h"
|
||||||
|
#include "pkcs11/pkcs11.h"
|
||||||
|
/* TODO doxygen comments */
|
||||||
|
|
||||||
|
+#define SC_PKCS1_PADDING_MIN_SIZE 11
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Prefixes for pkcs-v1 signatures
|
||||||
|
*/
|
||||||
|
@@ -144,44 +147,82 @@ sc_pkcs1_strip_01_padding(struct sc_cont
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
-/* remove pkcs1 BT02 padding (adding BT02 padding is currently not
|
||||||
|
- * needed/implemented) */
|
||||||
|
+/* Remove pkcs1 BT02 padding (adding BT02 padding is currently not
|
||||||
|
+ * needed/implemented) in constant-time.
|
||||||
|
+ * Original source: https://github.com/openssl/openssl/blob/9890cc42daff5e2d0cad01ac4bf78c391f599a6e/crypto/rsa/rsa_pk1.c#L171 */
|
||||||
|
int
|
||||||
|
-sc_pkcs1_strip_02_padding(sc_context_t *ctx, const u8 *data, size_t len, u8 *out, size_t *out_len)
|
||||||
|
+sc_pkcs1_strip_02_padding_constant_time(sc_context_t *ctx, unsigned int n, const u8 *data, unsigned int data_len, u8 *out, unsigned int *out_len)
|
||||||
|
{
|
||||||
|
- unsigned int n = 0;
|
||||||
|
-
|
||||||
|
+ unsigned int i = 0;
|
||||||
|
+ u8 *msg, *msg_orig = NULL;
|
||||||
|
+ unsigned int good, found_zero_byte, mask;
|
||||||
|
+ unsigned int zero_index = 0, msg_index, mlen = -1, len = 0;
|
||||||
|
LOG_FUNC_CALLED(ctx);
|
||||||
|
- if (data == NULL || len < 3)
|
||||||
|
+
|
||||||
|
+ if (data == NULL || data_len <= 0 || data_len > n || n < SC_PKCS1_PADDING_MIN_SIZE)
|
||||||
|
LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
|
||||||
|
|
||||||
|
- /* skip leading zero byte */
|
||||||
|
- if (*data == 0) {
|
||||||
|
- data++;
|
||||||
|
- len--;
|
||||||
|
+ msg = msg_orig = calloc(n, sizeof(u8));
|
||||||
|
+ if (msg == NULL)
|
||||||
|
+ LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * We can not check length of input data straight away and still we need to read
|
||||||
|
+ * from input even when the input is not as long as needed to keep the time constant.
|
||||||
|
+ * If data has wrong size, it is padded by zeroes from left and the following checks
|
||||||
|
+ * do not pass.
|
||||||
|
+ */
|
||||||
|
+ len = data_len;
|
||||||
|
+ for (data += len, msg += n, i = 0; i < n; i++) {
|
||||||
|
+ mask = ~constant_time_is_zero(len);
|
||||||
|
+ len -= 1 & mask;
|
||||||
|
+ data -= 1 & mask;
|
||||||
|
+ *--msg = *data & mask;
|
||||||
|
+ }
|
||||||
|
+ // check first byte to be 0x00
|
||||||
|
+ good = constant_time_is_zero(msg[0]);
|
||||||
|
+ // check second byte to be 0x02
|
||||||
|
+ good &= constant_time_eq(msg[1], 2);
|
||||||
|
+
|
||||||
|
+ // find zero byte after random data in padding
|
||||||
|
+ found_zero_byte = 0;
|
||||||
|
+ for (i = 2; i < n; i++) {
|
||||||
|
+ unsigned int equals0 = constant_time_is_zero(msg[i]);
|
||||||
|
+ zero_index = constant_time_select(~found_zero_byte & equals0, i, zero_index);
|
||||||
|
+ found_zero_byte |= equals0;
|
||||||
|
}
|
||||||
|
- if (data[0] != 0x02)
|
||||||
|
- LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_PADDING);
|
||||||
|
- /* skip over padding bytes */
|
||||||
|
- for (n = 1; n < len && data[n]; n++)
|
||||||
|
- ;
|
||||||
|
- /* Must be at least 8 pad bytes */
|
||||||
|
- if (n >= len || n < 9)
|
||||||
|
- LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_PADDING);
|
||||||
|
- n++;
|
||||||
|
- if (out == NULL)
|
||||||
|
- /* just check the padding */
|
||||||
|
- LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||||
|
|
||||||
|
- /* Now move decrypted contents to head of buffer */
|
||||||
|
- if (*out_len < len - n)
|
||||||
|
- LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
|
||||||
|
- *out_len = len - n;
|
||||||
|
- memmove(out, data + n, *out_len);
|
||||||
|
+ // zero_index stands for index of last found zero
|
||||||
|
+ good &= constant_time_ge(zero_index, 2 + 8);
|
||||||
|
+
|
||||||
|
+ // start of the actual message in data
|
||||||
|
+ msg_index = zero_index + 1;
|
||||||
|
+
|
||||||
|
+ // length of message
|
||||||
|
+ mlen = data_len - msg_index;
|
||||||
|
+
|
||||||
|
+ // check that message fits into out buffer
|
||||||
|
+ good &= constant_time_ge(*out_len, mlen);
|
||||||
|
+
|
||||||
|
+ // move the result in-place by |num|-SC_PKCS1_PADDING_MIN_SIZE-|mlen| bytes to the left.
|
||||||
|
+ *out_len = constant_time_select(constant_time_lt(n - SC_PKCS1_PADDING_MIN_SIZE, *out_len),
|
||||||
|
+ n - SC_PKCS1_PADDING_MIN_SIZE, *out_len);
|
||||||
|
+ for (msg_index = 1; msg_index < n - SC_PKCS1_PADDING_MIN_SIZE; msg_index <<= 1) {
|
||||||
|
+ mask = ~constant_time_eq(msg_index & (n - SC_PKCS1_PADDING_MIN_SIZE - mlen), 0);
|
||||||
|
+ for (i = SC_PKCS1_PADDING_MIN_SIZE; i < n - msg_index; i++)
|
||||||
|
+ msg[i] = constant_time_select_8(mask, msg[i + msg_index], msg[i]);
|
||||||
|
+ }
|
||||||
|
+ // move message into out buffer, if good
|
||||||
|
+ for (i = 0; i < *out_len; i++) {
|
||||||
|
+ unsigned int msg_index;
|
||||||
|
+ // when out is longer than message in data, use some bogus index in msg
|
||||||
|
+ mask = good & constant_time_lt(i, mlen);
|
||||||
|
+ msg_index = constant_time_select(mask, i + SC_PKCS1_PADDING_MIN_SIZE, 0); // to now overflow msg buffer
|
||||||
|
+ out[i] = constant_time_select_8(mask, msg[msg_index], out[i]);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- sc_log(ctx, "stripped output(%"SC_FORMAT_LEN_SIZE_T"u): %s", len - n,
|
||||||
|
- sc_dump_hex(out, len - n));
|
||||||
|
- LOG_FUNC_RETURN(ctx, len - n);
|
||||||
|
+ free(msg_orig);
|
||||||
|
+ return constant_time_select(good, mlen, SC_ERROR_WRONG_PADDING);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_OPENSSL
|
||||||
|
diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c
|
||||||
|
index 3391994abe..5248d9758a 100644
|
||||||
|
--- a/src/minidriver/minidriver.c
|
||||||
|
+++ b/src/minidriver/minidriver.c
|
||||||
|
@@ -4653,9 +4653,9 @@ DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData,
|
||||||
|
"sc_pkcs15_decipher: DECRYPT-INFO dwVersion=%lu\n",
|
||||||
|
(unsigned long)pInfo->dwVersion);
|
||||||
|
if (pInfo->dwPaddingType == CARD_PADDING_PKCS1) {
|
||||||
|
- size_t temp = pInfo->cbData;
|
||||||
|
+ unsigned int temp = pInfo->cbData;
|
||||||
|
logprintf(pCardData, 2, "sc_pkcs15_decipher: stripping PKCS1 padding\n");
|
||||||
|
- r = sc_pkcs1_strip_02_padding(vs->ctx, pbuf2, pInfo->cbData, pbuf2, &temp);
|
||||||
|
+ r = sc_pkcs1_strip_02_padding_constant_time(vs->ctx, prkey_info->modulus_length / 8, pbuf2, pInfo->cbData, pbuf2, &temp);
|
||||||
|
pInfo->cbData = (DWORD) temp;
|
||||||
|
if (r < 0) {
|
||||||
|
logprintf(pCardData, 2, "Cannot strip PKCS1 padding: %i\n", r);
|
||||||
|
|
||||||
|
diff --git a/src/tests/unittests/Makefile.am b/src/tests/unittests/Makefile.am
|
||||||
|
index 7019ca7ba8..4c73911e48 100644
|
||||||
|
--- a/src/tests/unittests/Makefile.am
|
||||||
|
+++ b/src/tests/unittests/Makefile.am
|
||||||
|
@@ -6,8 +6,10 @@ include $(top_srcdir)/aminclude_static.a
|
||||||
|
clean-local: code-coverage-clean
|
||||||
|
distclean-local: code-coverage-dist-clean
|
||||||
|
|
||||||
|
-noinst_PROGRAMS = asn1 simpletlv cachedir pkcs15filter openpgp-tool hextobin decode_ecdsa_signature
|
||||||
|
-TESTS = asn1 simpletlv cachedir pkcs15filter openpgp-tool hextobin decode_ecdsa_signature
|
||||||
|
+noinst_PROGRAMS = asn1 simpletlv cachedir pkcs15filter openpgp-tool hextobin \
|
||||||
|
+ decode_ecdsa_signature strip_pkcs1_2_padding
|
||||||
|
+TESTS = asn1 simpletlv cachedir pkcs15filter openpgp-tool hextobin \
|
||||||
|
+ decode_ecdsa_signature strip_pkcs1_2_padding
|
||||||
|
|
||||||
|
noinst_HEADERS = torture.h
|
||||||
|
|
||||||
|
@@ -28,6 +30,7 @@ pkcs15filter_SOURCES = pkcs15-emulator-f
|
||||||
|
openpgp_tool_SOURCES = openpgp-tool.c $(top_builddir)/src/tools/openpgp-tool-helpers.c
|
||||||
|
hextobin_SOURCES = hextobin.c
|
||||||
|
decode_ecdsa_signature_SOURCES = decode_ecdsa_signature.c
|
||||||
|
+strip_pkcs1_2_paddingSOURCES = strip_pkcs1_2_padding.c
|
||||||
|
|
||||||
|
if ENABLE_ZLIB
|
||||||
|
noinst_PROGRAMS += compression
|
||||||
|
diff --git a/src/tests/unittests/Makefile.mak b/src/tests/unittests/Makefile.mak
|
||||||
|
index 2607546f57..6284b51af9 100644
|
||||||
|
--- a/src/tests/unittests/Makefile.mak
|
||||||
|
+++ b/src/tests/unittests/Makefile.mak
|
||||||
|
@@ -1,10 +1,11 @@
|
||||||
|
TOPDIR = ..\..\..
|
||||||
|
|
||||||
|
-TARGETS = asn1 compression pkcs15filter
|
||||||
|
+TARGETS = asn1 compression pkcs15filter strip_pkcs1_2_padding
|
||||||
|
|
||||||
|
OBJECTS = asn1.obj \
|
||||||
|
compression.obj \
|
||||||
|
- pkcs15-emulator-filter.obj
|
||||||
|
+ pkcs15-emulator-filter.obj \
|
||||||
|
+ strip_pkcs1_2_padding.obj \
|
||||||
|
$(TOPDIR)\win32\versioninfo.res
|
||||||
|
|
||||||
|
all: $(TARGETS)
|
||||||
|
diff --git a/src/tests/unittests/strip_pkcs1_2_padding.c b/src/tests/unittests/strip_pkcs1_2_padding.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..f9561b936d
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/tests/unittests/strip_pkcs1_2_padding.c
|
||||||
|
@@ -0,0 +1,204 @@
|
||||||
|
+#include "common/compat_strlcpy.c"
|
||||||
|
+#include "libopensc/log.c"
|
||||||
|
+#include "libopensc/padding.c"
|
||||||
|
+#include "torture.h"
|
||||||
|
+#include <cmocka.h>
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+torture_long_output_buffer(void **state)
|
||||||
|
+{
|
||||||
|
+ unsigned int n = 14;
|
||||||
|
+ unsigned int in_len = 14;
|
||||||
|
+ unsigned char in[] = {0x00, 0x02,
|
||||||
|
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
||||||
|
+ 0x00,
|
||||||
|
+ 'm', 's', 'g'};
|
||||||
|
+ unsigned int out_len = 3;
|
||||||
|
+ unsigned char *out = calloc(out_len, sizeof(unsigned char));
|
||||||
|
+ unsigned char result_msg[] = {'m', 's', 'g'};
|
||||||
|
+ int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
|
||||||
|
+ assert_int_equal(r, 3);
|
||||||
|
+ assert_memory_equal(out, result_msg, r);
|
||||||
|
+ free(out);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+torture_short_output_buffer(void **state)
|
||||||
|
+{
|
||||||
|
+ unsigned int n = 14;
|
||||||
|
+ unsigned int in_len = 14;
|
||||||
|
+ unsigned char in[] = {0x00, 0x02,
|
||||||
|
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
||||||
|
+ 0x00,
|
||||||
|
+ 'm', 's', 'g'};
|
||||||
|
+ unsigned int out_len = 1;
|
||||||
|
+ unsigned char *out = calloc(out_len, sizeof(unsigned char));
|
||||||
|
+ int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
|
||||||
|
+ assert_int_equal(r, SC_ERROR_WRONG_PADDING);
|
||||||
|
+ free(out);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+torture_short_message_correct_padding(void **state)
|
||||||
|
+{
|
||||||
|
+ unsigned int n = 14;
|
||||||
|
+ unsigned int in_len = 14;
|
||||||
|
+ unsigned char in[] = {0x00, 0x02,
|
||||||
|
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
||||||
|
+ 0x00,
|
||||||
|
+ 'm', 's', 'g'};
|
||||||
|
+ unsigned int out_len = 3;
|
||||||
|
+ unsigned char *out = calloc(out_len, sizeof(unsigned char));
|
||||||
|
+ unsigned char result_msg[] = {'m', 's', 'g'};
|
||||||
|
+ int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
|
||||||
|
+ assert_int_equal(r, 3);
|
||||||
|
+ assert_memory_equal(out, result_msg, r);
|
||||||
|
+ free(out);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+torture_missing_first_zero(void **state)
|
||||||
|
+{
|
||||||
|
+ unsigned int n = 13;
|
||||||
|
+ unsigned int in_len = 13;
|
||||||
|
+ unsigned char in[] = {0x02,
|
||||||
|
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
||||||
|
+ 0x00,
|
||||||
|
+ 'm', 's', 'g'};
|
||||||
|
+ unsigned int out_len = 10;
|
||||||
|
+ unsigned char *out = calloc(out_len, sizeof(unsigned char));
|
||||||
|
+ int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
|
||||||
|
+ assert_int_equal(r, SC_ERROR_WRONG_PADDING);
|
||||||
|
+ free(out);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+torture_missing_two(void **state)
|
||||||
|
+{
|
||||||
|
+ unsigned int n = 13;
|
||||||
|
+ unsigned int in_len = 13;
|
||||||
|
+ unsigned char in[] = {0x00,
|
||||||
|
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
||||||
|
+ 0x00,
|
||||||
|
+ 'm', 's', 'g'};
|
||||||
|
+ unsigned int out_len = 10;
|
||||||
|
+ unsigned char *out = calloc(out_len, sizeof(unsigned char));
|
||||||
|
+ int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
|
||||||
|
+ assert_int_equal(r, SC_ERROR_WRONG_PADDING);
|
||||||
|
+ free(out);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+torture_short_padding(void **state)
|
||||||
|
+{
|
||||||
|
+ unsigned int n = 13;
|
||||||
|
+ unsigned int in_len = 13;
|
||||||
|
+ unsigned char in[] = {0x00, 0x02,
|
||||||
|
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||||
|
+ 0x00,
|
||||||
|
+ 'm', 's', 'g'};
|
||||||
|
+ unsigned int out_len = 10;
|
||||||
|
+ unsigned char *out = calloc(out_len, sizeof(unsigned char));
|
||||||
|
+ int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
|
||||||
|
+ assert_int_equal(r, SC_ERROR_WRONG_PADDING);
|
||||||
|
+ free(out);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+torture_missing_second_zero(void **state)
|
||||||
|
+{
|
||||||
|
+ unsigned int n = 13;
|
||||||
|
+ unsigned int in_len = 13;
|
||||||
|
+ unsigned char in[] = {0x00, 0x02,
|
||||||
|
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
||||||
|
+ 'm', 's', 'g'};
|
||||||
|
+ unsigned int out_len = 10;
|
||||||
|
+ unsigned char *out = calloc(out_len, sizeof(unsigned char));
|
||||||
|
+ int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
|
||||||
|
+ assert_int_equal(r, SC_ERROR_WRONG_PADDING);
|
||||||
|
+ free(out);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+torture_missing_message(void **state)
|
||||||
|
+{
|
||||||
|
+ unsigned int n = 20;
|
||||||
|
+ unsigned int in_len = 11;
|
||||||
|
+ unsigned char in[] = {0x00, 0x02,
|
||||||
|
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
||||||
|
+ 0x00};
|
||||||
|
+ unsigned int out_len = 11;
|
||||||
|
+ unsigned char *out = calloc(out_len, sizeof(unsigned char));
|
||||||
|
+ int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
|
||||||
|
+ assert_int_equal(r, SC_ERROR_WRONG_PADDING);
|
||||||
|
+ free(out);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+torture_one_byte_message(void **state)
|
||||||
|
+{
|
||||||
|
+ unsigned int n = 12;
|
||||||
|
+ unsigned int in_len = 12;
|
||||||
|
+ unsigned char in[] = {0x00, 0x02,
|
||||||
|
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
||||||
|
+ 0x00,
|
||||||
|
+ 'm'};
|
||||||
|
+ unsigned int out_len = 1;
|
||||||
|
+ unsigned char *out = calloc(out_len, sizeof(unsigned char));
|
||||||
|
+ unsigned char result_msg[] = {'m'};
|
||||||
|
+ int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
|
||||||
|
+ assert_int_equal(r, 1);
|
||||||
|
+ assert_memory_equal(out, result_msg, r);
|
||||||
|
+ free(out);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+torture_longer_padding(void **state)
|
||||||
|
+{
|
||||||
|
+ unsigned int n = 26;
|
||||||
|
+ unsigned int in_len = 26;
|
||||||
|
+ unsigned char in[] = {0x00, 0x02,
|
||||||
|
+ 0x0e, 0x38, 0x97, 0x18, 0x16, 0x57, 0x9e, 0x30, 0xb6, 0xa5, 0x78, 0x13, 0x20, 0xca, 0x11,
|
||||||
|
+ 0x00,
|
||||||
|
+ 0x9d, 0x98, 0x3d, 0xca, 0xa9, 0xa7, 0x11, 0x0a};
|
||||||
|
+ unsigned int out_len = 8;
|
||||||
|
+ unsigned char *out = calloc(out_len, sizeof(unsigned char));
|
||||||
|
+ unsigned char result_msg[] = {0x9d, 0x98, 0x3d, 0xca, 0xa9, 0xa7, 0x11, 0x0a};
|
||||||
|
+ int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
|
||||||
|
+ assert_int_equal(r, 8);
|
||||||
|
+ assert_memory_equal(out, result_msg, r);
|
||||||
|
+ free(out);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+torture_empty_message(void **state)
|
||||||
|
+{
|
||||||
|
+ unsigned int n = 18;
|
||||||
|
+ unsigned int in_len = 18;
|
||||||
|
+ unsigned char in[] = {0x00, 0x02,
|
||||||
|
+ 0x0e, 0x38, 0x97, 0x18, 0x16, 0x57, 0x9e, 0x30, 0xb6, 0xa5, 0x78, 0x13, 0x20, 0xca, 0x11,
|
||||||
|
+ 0x00};
|
||||||
|
+ unsigned int out_len = 8;
|
||||||
|
+ unsigned char *out = calloc(out_len, sizeof(unsigned char));
|
||||||
|
+ int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
|
||||||
|
+ assert_int_equal(r, 0);
|
||||||
|
+ free(out);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+main(void)
|
||||||
|
+{
|
||||||
|
+ const struct CMUnitTest tests[] = {
|
||||||
|
+ cmocka_unit_test(torture_long_output_buffer),
|
||||||
|
+ cmocka_unit_test(torture_short_output_buffer),
|
||||||
|
+ cmocka_unit_test(torture_short_message_correct_padding),
|
||||||
|
+ cmocka_unit_test(torture_missing_first_zero),
|
||||||
|
+ cmocka_unit_test(torture_missing_two),
|
||||||
|
+ cmocka_unit_test(torture_short_padding),
|
||||||
|
+ cmocka_unit_test(torture_missing_second_zero),
|
||||||
|
+ cmocka_unit_test(torture_missing_message),
|
||||||
|
+ cmocka_unit_test(torture_one_byte_message),
|
||||||
|
+ cmocka_unit_test(torture_longer_padding),
|
||||||
|
+ cmocka_unit_test(torture_empty_message)};
|
||||||
|
+ return cmocka_run_group_tests(tests, NULL, NULL);
|
||||||
|
+}
|
||||||
|
|
||||||
|
diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c
|
||||||
|
index a019af460f..f7ee819d65 100644
|
||||||
|
--- a/src/libopensc/pkcs15-sec.c
|
||||||
|
+++ b/src/libopensc/pkcs15-sec.c
|
||||||
|
@@ -308,9 +308,10 @@ int sc_pkcs15_decipher(struct sc_pkcs15_
|
||||||
|
|
||||||
|
/* Strip any padding */
|
||||||
|
if (pad_flags & SC_ALGORITHM_RSA_PAD_PKCS1) {
|
||||||
|
- size_t s = r;
|
||||||
|
- r = sc_pkcs1_strip_02_padding(ctx, out, s, out, &s);
|
||||||
|
- LOG_TEST_RET(ctx, r, "Invalid PKCS#1 padding");
|
||||||
|
+ unsigned int s = r;
|
||||||
|
+ unsigned int key_size = (unsigned int)alg_info->key_length;
|
||||||
|
+ r = sc_pkcs1_strip_02_padding_constant_time(ctx, key_size / 8, out, s, out, &s);
|
||||||
|
+ /* for keeping PKCS#1 v1.5 depadding constant-time, do not log error here */
|
||||||
|
}
|
||||||
|
#ifdef ENABLE_OPENSSL
|
||||||
|
if (pad_flags & SC_ALGORITHM_RSA_PAD_OAEP)
|
||||||
|
@@ -332,7 +333,8 @@ int sc_pkcs15_decipher(struct sc_pkcs15_
|
||||||
|
LOG_TEST_RET(ctx, r, "Invalid OAEP padding");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
- LOG_FUNC_RETURN(ctx, r);
|
||||||
|
+ /* do not log error code to prevent side channel attack */
|
||||||
|
+ return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* derive one key from another. RSA can use decipher, so this is for only ECDH
|
||||||
|
|
||||||
|
diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c
|
||||||
|
index f75a3dbaec..632681df63 100644
|
||||||
|
--- a/src/pkcs11/framework-pkcs15.c
|
||||||
|
+++ b/src/pkcs11/framework-pkcs15.c
|
||||||
|
@@ -18,6 +18,7 @@
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
+#include "common/constant-time.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
@@ -4395,7 +4396,8 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_se
|
||||||
|
struct pkcs15_fw_data *fw_data = NULL;
|
||||||
|
struct pkcs15_prkey_object *prkey;
|
||||||
|
unsigned char decrypted[512]; /* FIXME: Will not work for keys above 4096 bits */
|
||||||
|
- int buff_too_small, rv, flags = 0, prkey_has_path = 0;
|
||||||
|
+ int rv, flags = 0, prkey_has_path = 0;
|
||||||
|
+ CK_ULONG mask, good, rv_pkcs11;
|
||||||
|
|
||||||
|
if (pulDataLen == NULL) {
|
||||||
|
/* This is call from the C_DecyptInit function */
|
||||||
|
@@ -4484,27 +4486,53 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_se
|
||||||
|
rv = sc_pkcs15_decipher(fw_data->p15_card, prkey->prv_p15obj, flags,
|
||||||
|
pEncryptedData, ulEncryptedDataLen, decrypted, sizeof(decrypted), pMechanism);
|
||||||
|
|
||||||
|
- if (rv < 0 && !sc_pkcs11_conf.lock_login && !prkey_has_path)
|
||||||
|
+ /* skip for PKCS#1 v1.5 padding prevent side channel attack */
|
||||||
|
+ if (!(flags & SC_ALGORITHM_RSA_PAD_PKCS1) &&
|
||||||
|
+ rv < 0 && !sc_pkcs11_conf.lock_login && !prkey_has_path)
|
||||||
|
if (reselect_app_df(fw_data->p15_card) == SC_SUCCESS)
|
||||||
|
rv = sc_pkcs15_decipher(fw_data->p15_card, prkey->prv_p15obj, flags,
|
||||||
|
pEncryptedData, ulEncryptedDataLen, decrypted, sizeof(decrypted), pMechanism);
|
||||||
|
|
||||||
|
sc_unlock(p11card->card);
|
||||||
|
|
||||||
|
- sc_log(context, "Decryption complete. Result %d.", rv);
|
||||||
|
+ sc_log(context, "Decryption complete.");
|
||||||
|
|
||||||
|
- if (rv < 0)
|
||||||
|
- return sc_to_cryptoki_error(rv, "C_Decrypt");
|
||||||
|
+ /* Handle following code in constant-time
|
||||||
|
+ * to prevent Marvin attack for PKCS#1 v1.5 padding. */
|
||||||
|
|
||||||
|
- buff_too_small = (*pulDataLen < (CK_ULONG)rv);
|
||||||
|
- *pulDataLen = rv;
|
||||||
|
- if (pData == NULL_PTR)
|
||||||
|
- return CKR_OK;
|
||||||
|
- if (buff_too_small)
|
||||||
|
- return CKR_BUFFER_TOO_SMALL;
|
||||||
|
- memcpy(pData, decrypted, *pulDataLen);
|
||||||
|
+ /* only padding error must be handled in constant-time way,
|
||||||
|
+ * other error can be returned straight away */
|
||||||
|
+ if ((~constant_time_eq_i(rv, SC_ERROR_WRONG_PADDING) & constant_time_lt_s(sizeof(decrypted), (size_t)rv)))
|
||||||
|
+ return sc_to_cryptoki_error(rv, "C_Decrypt");
|
||||||
|
|
||||||
|
- return CKR_OK;
|
||||||
|
+ /* check rv for padding error */
|
||||||
|
+ good = ~constant_time_eq_i(rv, SC_ERROR_WRONG_PADDING);
|
||||||
|
+ rv_pkcs11 = sc_to_cryptoki_error(SC_ERROR_WRONG_PADDING, "C_Decrypt");
|
||||||
|
+ rv_pkcs11 = constant_time_select_s(good, CKR_OK, rv_pkcs11);
|
||||||
|
+
|
||||||
|
+ if (pData == NULL_PTR) {
|
||||||
|
+ /* set length only if no error */
|
||||||
|
+ *pulDataLen = constant_time_select_s(good, rv, *pulDataLen);
|
||||||
|
+ /* return error only if original rv < 0 */
|
||||||
|
+ return rv_pkcs11;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* check whether *pulDataLen < rv and set return value for small output buffer */
|
||||||
|
+ mask = good & constant_time_lt_s(*pulDataLen, rv);
|
||||||
|
+ rv_pkcs11 = constant_time_select_s(mask, CKR_BUFFER_TOO_SMALL, rv_pkcs11);
|
||||||
|
+ good &= ~mask;
|
||||||
|
+
|
||||||
|
+ /* move everything from decrypted into out buffer constant-time, if rv is ok */
|
||||||
|
+ for (CK_ULONG i = 0; i < *pulDataLen; i++) { /* iterate over whole pData to not disclose real depadded length */
|
||||||
|
+ CK_ULONG msg_index;
|
||||||
|
+ mask = good & constant_time_lt_s(i, sizeof(decrypted)); /* i should be in the bounds of decrypted */
|
||||||
|
+ mask &= constant_time_lt_s(i, constant_time_select_s(good, rv, 0)); /* check that is in bounds of depadded message */
|
||||||
|
+ msg_index = constant_time_select_s(mask, i, 0);
|
||||||
|
+ pData[i] = constant_time_select_8(mask, decrypted[msg_index], pData[i]);
|
||||||
|
+ }
|
||||||
|
+ *pulDataLen = constant_time_select_s(good, rv, *pulDataLen);
|
||||||
|
+ /* do not log error code to prevent side channel attack */
|
||||||
|
+ return rv_pkcs11;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c
|
||||||
|
index 03495265a4..d3f0434231 100644
|
||||||
|
--- a/src/pkcs11/mechanism.c
|
||||||
|
+++ b/src/pkcs11/mechanism.c
|
||||||
|
@@ -23,6 +23,7 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
+#include "common/constant-time.h"
|
||||||
|
#include "sc-pkcs11.h"
|
||||||
|
|
||||||
|
/* Also used for verification data */
|
||||||
|
@@ -1089,7 +1090,9 @@ sc_pkcs11_decr(struct sc_pkcs11_session
|
||||||
|
rv = op->type->decrypt(op, pEncryptedData, ulEncryptedDataLen,
|
||||||
|
pData, pulDataLen);
|
||||||
|
|
||||||
|
- if (rv != CKR_BUFFER_TOO_SMALL && pData != NULL)
|
||||||
|
+ /* terminate session for any return value except CKR_BUFFER_TOO_SMALL,
|
||||||
|
+ * perform check in time side-channel free way to prevent Marvin attack */
|
||||||
|
+ if (!constant_time_eq_s(rv, CKR_BUFFER_TOO_SMALL) && pData != NULL)
|
||||||
|
session_stop_operation(session, SC_PKCS11_OPERATION_DECRYPT);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
@@ -1110,10 +1113,12 @@ sc_pkcs11_decr_update(struct sc_pkcs11_s
|
||||||
|
rv = op->type->decrypt_update(op, pEncryptedData, ulEncryptedDataLen,
|
||||||
|
pData, pulDataLen);
|
||||||
|
|
||||||
|
- /* terminate session for any error except CKR_BUFFER_TOO_SMALL */
|
||||||
|
- if (rv != CKR_OK && rv != CKR_BUFFER_TOO_SMALL)
|
||||||
|
+ /* terminate session for any return value except CKR_BUFFER_TOO_SMALL,
|
||||||
|
+ * perform check in time side-channel free way to prevent Marvin attack */
|
||||||
|
+ if (~constant_time_eq_s(rv, CKR_OK) & ~constant_time_eq_s(rv, CKR_BUFFER_TOO_SMALL))
|
||||||
|
session_stop_operation(session, SC_PKCS11_OPERATION_DECRYPT);
|
||||||
|
- LOG_FUNC_RETURN(context, (int)rv);
|
||||||
|
+ /* do not log error code to prevent side channel attack */
|
||||||
|
+ return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
CK_RV
|
||||||
|
@@ -1530,6 +1535,10 @@ sc_pkcs11_decrypt(sc_pkcs11_operation_t
|
||||||
|
if (pulDataLen)
|
||||||
|
*pulDataLen = ulDataLen;
|
||||||
|
|
||||||
|
+ /* Skip DecryptFinalize for PKCS#1 v1.5 padding to prevent time side-channel leakage */
|
||||||
|
+ if (((CK_MECHANISM_PTR)&operation->mechanism)->mechanism == CKM_RSA_PKCS)
|
||||||
|
+ return rv;
|
||||||
|
+
|
||||||
|
if (rv != CKR_OK)
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/src/pkcs11/pkcs11-object.c b/src/pkcs11/pkcs11-object.c
|
||||||
|
index f04c0b4c56..b023911213 100644
|
||||||
|
--- a/src/pkcs11/pkcs11-object.c
|
||||||
|
+++ b/src/pkcs11/pkcs11-object.c
|
||||||
|
@@ -1034,7 +1034,8 @@ C_Decrypt(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||||
|
rv = reset_login_state(session->slot, rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
- SC_LOG_RV("C_Decrypt() = %s", rv);
|
||||||
|
+ /* do not log error code to prevent side channel attack */
|
||||||
|
+ SC_LOG("C_Decrypt()");
|
||||||
|
sc_pkcs11_unlock();
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
@@ -1058,7 +1059,8 @@ C_DecryptUpdate(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||||
|
rv = sc_pkcs11_decr_update(session, pEncryptedPart, ulEncryptedPartLen,
|
||||||
|
pPart, pulPartLen);
|
||||||
|
|
||||||
|
- SC_LOG_RV("C_DecryptUpdate() = %s", rv);
|
||||||
|
+ /* do not log error code to prevent side channel attack */
|
||||||
|
+ SC_LOG("C_DecryptUpdate()");
|
||||||
|
sc_pkcs11_unlock();
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
@@ -1086,7 +1088,8 @@ C_DecryptFinal(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||||
|
rv = reset_login_state(session->slot, rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
- SC_LOG_RV("C_DecryptFinal() = %s", rv);
|
||||||
|
+ /* do not log error code to prevent side channel attack */
|
||||||
|
+ SC_LOG("C_DecryptFinal()");
|
||||||
|
sc_pkcs11_unlock();
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h
|
||||||
|
index 66dfcdde67..510017ed2a 100644
|
||||||
|
--- a/src/pkcs11/sc-pkcs11.h
|
||||||
|
+++ b/src/pkcs11/sc-pkcs11.h
|
||||||
|
@@ -246,6 +246,11 @@ do {\
|
||||||
|
}\
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
+#define SC_LOG(fmt) \
|
||||||
|
+ do { \
|
||||||
|
+ sc_log(context, (fmt)); \
|
||||||
|
+ } while (0)
|
||||||
|
+
|
||||||
|
/* Debug virtual slots. S is slot to be highlighted or NULL
|
||||||
|
* C is a comment format string and args It will be preceded by "VSS " */
|
||||||
|
#define DEBUG_VSS(S, ...) do { sc_log(context,"VSS " __VA_ARGS__); _debug_virtual_slots(S); } while (0)
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/src/pkcs11/misc.c b/src/pkcs11/misc.c
|
||||||
|
index 5ca1176b1d..1d893d6181 100644
|
||||||
|
--- a/src/pkcs11/misc.c
|
||||||
|
+++ b/src/pkcs11/misc.c
|
||||||
|
@@ -23,6 +23,7 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
+#include "common/constant-time.h"
|
||||||
|
#include "sc-pkcs11.h"
|
||||||
|
|
||||||
|
#define DUMP_TEMPLATE_MAX 32
|
||||||
|
@@ -174,7 +175,7 @@ CK_RV reset_login_state(struct sc_pkcs11_slot *slot, CK_RV rv)
|
||||||
|
slot->p11card->framework->logout(slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (rv == CKR_USER_NOT_LOGGED_IN) {
|
||||||
|
+ if (constant_time_eq_s(rv, CKR_USER_NOT_LOGGED_IN)) {
|
||||||
|
slot->login_user = -1;
|
||||||
|
pop_all_login_states(slot);
|
||||||
|
}
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
From 17c6c80de8edd5d08db5bc2f914af6473a6f0f46 Mon Sep 17 00:00:00 2001
|
||||||
|
From: yuncang123 <1050706328@qq.com>
|
||||||
|
Date: Sun, 1 Sep 2024 16:08:07 +0800
|
||||||
|
Subject: [PATCH] backport-pgp-avoid calling functions without prototype
|
||||||
|
|
||||||
|
---
|
||||||
|
src/libopensc/card-openpgp.c | 12 ++++++------
|
||||||
|
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c
|
||||||
|
index fad32f0..e4e6cc4 100644
|
||||||
|
--- a/src/libopensc/card-openpgp.c
|
||||||
|
+++ b/src/libopensc/card-openpgp.c
|
||||||
|
@@ -129,7 +129,7 @@ static pgp_ec_curves_t ec_curves_gnuk[] = {
|
||||||
|
|
||||||
|
static int pgp_get_card_features(sc_card_t *card);
|
||||||
|
static int pgp_finish(sc_card_t *card);
|
||||||
|
-static void pgp_iterate_blobs(pgp_blob_t *, void (*func)());
|
||||||
|
+static void pgp_free_blobs(pgp_blob_t *);
|
||||||
|
|
||||||
|
static int pgp_get_blob(sc_card_t *card, pgp_blob_t *blob,
|
||||||
|
unsigned int id, pgp_blob_t **ret);
|
||||||
|
@@ -947,7 +947,7 @@ pgp_finish(sc_card_t *card)
|
||||||
|
|
||||||
|
if (priv != NULL) {
|
||||||
|
/* delete fake file hierarchy */
|
||||||
|
- pgp_iterate_blobs(priv->mf, pgp_free_blob);
|
||||||
|
+ pgp_free_blobs(priv->mf);
|
||||||
|
|
||||||
|
/* delete private data */
|
||||||
|
free(priv);
|
||||||
|
@@ -1147,10 +1147,10 @@ pgp_free_blob(pgp_blob_t *blob)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
- * Internal: iterate through the blob tree, calling a function for each blob.
|
||||||
|
+ * Internal: iterate through the blob tree, calling pgp_free_blob for each blob.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
-pgp_iterate_blobs(pgp_blob_t *blob, void (*func)())
|
||||||
|
+pgp_free_blobs(pgp_blob_t *blob)
|
||||||
|
{
|
||||||
|
if (blob) {
|
||||||
|
pgp_blob_t *child = blob->files;
|
||||||
|
@@ -1158,10 +1158,10 @@ pgp_iterate_blobs(pgp_blob_t *blob, void (*func)())
|
||||||
|
while (child != NULL) {
|
||||||
|
pgp_blob_t *next = child->next;
|
||||||
|
|
||||||
|
- pgp_iterate_blobs(child, func);
|
||||||
|
+ pgp_free_blobs(child);
|
||||||
|
child = next;
|
||||||
|
}
|
||||||
|
- func(blob);
|
||||||
|
+ pgp_free_blob(blob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.43.0
|
||||||
|
|
||||||
111
opensc-CVE-2024-45615.patch
Normal file
111
opensc-CVE-2024-45615.patch
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
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.23.0/src/libopensc/card-cac.c
|
||||||
|
===================================================================
|
||||||
|
--- opensc-0.23.0.orig/src/libopensc/card-cac.c
|
||||||
|
+++ opensc-0.23.0/src/libopensc/card-cac.c
|
||||||
|
@@ -255,7 +255,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;
|
||||||
|
@@ -392,13 +392,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;
|
||||||
|
@@ -461,7 +461,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;
|
||||||
|
|
||||||
|
@@ -1528,7 +1528,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.23.0/src/libopensc/card-piv.c
|
||||||
|
===================================================================
|
||||||
|
--- opensc-0.23.0.orig/src/libopensc/card-piv.c
|
||||||
|
+++ opensc-0.23.0/src/libopensc/card-piv.c
|
||||||
|
@@ -2202,7 +2202,7 @@ static int piv_get_challenge(sc_card_t *
|
||||||
|
const u8 *p;
|
||||||
|
size_t out_len = 0;
|
||||||
|
int r;
|
||||||
|
- unsigned int tag, cla;
|
||||||
|
+ unsigned int tag = 0, cla = 0;
|
||||||
|
piv_private_data_t * priv = PIV_DATA(card);
|
||||||
|
|
||||||
|
LOG_FUNC_CALLED(card->ctx);
|
||||||
|
Index: opensc-0.23.0/src/libopensc/pkcs15-cert.c
|
||||||
|
===================================================================
|
||||||
|
--- opensc-0.23.0.orig/src/libopensc/pkcs15-cert.c
|
||||||
|
+++ opensc-0.23.0/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.23.0/src/libopensc/pkcs15-sc-hsm.c
|
||||||
|
===================================================================
|
||||||
|
--- opensc-0.23.0.orig/src/libopensc/pkcs15-sc-hsm.c
|
||||||
|
+++ opensc-0.23.0/src/libopensc/pkcs15-sc-hsm.c
|
||||||
|
@@ -277,7 +277,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.23.0/src/pkcs15init/profile.c
|
||||||
|
===================================================================
|
||||||
|
--- opensc-0.23.0.orig/src/pkcs15init/profile.c
|
||||||
|
+++ opensc-0.23.0/src/pkcs15init/profile.c
|
||||||
|
@@ -1695,7 +1695,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)
|
||||||
287
opensc-CVE-2024-45616.patch
Normal file
287
opensc-CVE-2024-45616.patch
Normal file
@ -0,0 +1,287 @@
|
|||||||
|
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.23.0/src/libopensc/card-cardos.c
|
||||||
|
===================================================================
|
||||||
|
--- opensc-0.23.0.orig/src/libopensc/card-cardos.c
|
||||||
|
+++ opensc-0.23.0/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.23.0/src/libopensc/card-cac1.c
|
||||||
|
===================================================================
|
||||||
|
--- opensc-0.23.0.orig/src/libopensc/card-cac1.c
|
||||||
|
+++ opensc-0.23.0/src/libopensc/card-cac1.c
|
||||||
|
@@ -95,12 +95,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.23.0/src/libopensc/card-oberthur.c
|
||||||
|
===================================================================
|
||||||
|
--- opensc-0.23.0.orig/src/libopensc/card-oberthur.c
|
||||||
|
+++ opensc-0.23.0/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.23.0/src/libopensc/card-gids.c
|
||||||
|
===================================================================
|
||||||
|
--- opensc-0.23.0.orig/src/libopensc/card-gids.c
|
||||||
|
+++ opensc-0.23.0/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.23.0/src/libopensc/card-mcrd.c
|
||||||
|
===================================================================
|
||||||
|
--- opensc-0.23.0.orig/src/libopensc/card-mcrd.c
|
||||||
|
+++ opensc-0.23.0/src/libopensc/card-mcrd.c
|
||||||
|
@@ -634,23 +634,25 @@ do_select(sc_card_t * card, u8 kind,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (p2 == 0x04 && apdu.resp[0] == 0x62) {
|
||||||
|
- *file = sc_file_new();
|
||||||
|
- if (!*file)
|
||||||
|
- LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
|
||||||
|
- /* EstEID v3.0 cards are buggy and sometimes return a double 0x62 tag */
|
||||||
|
- if (card->type == SC_CARD_TYPE_MCRD_ESTEID_V30 && apdu.resp[2] == 0x62)
|
||||||
|
- process_fcp(card, *file, apdu.resp + 4, apdu.resp[3]);
|
||||||
|
- else
|
||||||
|
- process_fcp(card, *file, apdu.resp + 2, apdu.resp[1]);
|
||||||
|
- return SC_SUCCESS;
|
||||||
|
- }
|
||||||
|
+ if (p2 == 0x04 && apdu.resplen > 2 && apdu.resp[0] == 0x62) {
|
||||||
|
+ *file = sc_file_new();
|
||||||
|
+ if (!*file)
|
||||||
|
+ LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
|
||||||
|
+ if (apdu.resp[1] > apdu.resplen - 2)
|
||||||
|
+ LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA);
|
||||||
|
+ /* EstEID v3.0 cards are buggy and sometimes return a double 0x62 tag */
|
||||||
|
+ if (card->type == SC_CARD_TYPE_MCRD_ESTEID_V30 && apdu.resp[2] == 0x62)
|
||||||
|
+ process_fcp(card, *file, apdu.resp + 4, apdu.resp[3]);
|
||||||
|
+ else
|
||||||
|
+ process_fcp(card, *file, apdu.resp + 2, apdu.resp[1]);
|
||||||
|
+ return SC_SUCCESS;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if (p2 != 0x0C && apdu.resp[0] == 0x6F) {
|
||||||
|
+ if (p2 != 0x0C && apdu.resplen > 2 && apdu.resp[0] == 0x6F) {
|
||||||
|
*file = sc_file_new();
|
||||||
|
if (!*file)
|
||||||
|
LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
|
||||||
|
- if (apdu.resp[1] <= apdu.resplen)
|
||||||
|
+ if (apdu.resp[1] > apdu.resplen - 2)
|
||||||
|
process_fcp(card, *file, apdu.resp + 2, apdu.resp[1]);
|
||||||
|
return SC_SUCCESS;
|
||||||
|
}
|
||||||
|
Index: opensc-0.23.0/src/libopensc/asn1.c
|
||||||
|
===================================================================
|
||||||
|
--- opensc-0.23.0.orig/src/libopensc/asn1.c
|
||||||
|
+++ opensc-0.23.0/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.23.0/src/libopensc/card-dnie.c
|
||||||
|
===================================================================
|
||||||
|
--- opensc-0.23.0.orig/src/libopensc/card-dnie.c
|
||||||
|
+++ opensc-0.23.0/src/libopensc/card-dnie.c
|
||||||
|
@@ -1185,12 +1185,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);
|
||||||
|
}
|
||||||
|
@@ -1949,7 +1953,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.23.0/src/libopensc/muscle.c
|
||||||
|
===================================================================
|
||||||
|
--- opensc-0.23.0.orig/src/libopensc/muscle.c
|
||||||
|
+++ opensc-0.23.0/src/libopensc/muscle.c
|
||||||
|
@@ -94,33 +94,35 @@ int msc_partial_read_object(sc_card_t *c
|
||||||
|
apdu.resp = data;
|
||||||
|
r = sc_transmit_apdu(card, &apdu);
|
||||||
|
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||||
|
- if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00)
|
||||||
|
- return dataLength;
|
||||||
|
- if(apdu.sw1 == 0x9C) {
|
||||||
|
- if(apdu.sw2 == 0x07) {
|
||||||
|
+ if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00 && dataLength <= apdu.resplen)
|
||||||
|
+ return dataLength;
|
||||||
|
+ if (apdu.sw1 == 0x9C) {
|
||||||
|
+ if (apdu.sw2 == 0x07) {
|
||||||
|
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_FILE_NOT_FOUND);
|
||||||
|
- } else if(apdu.sw2 == 0x06) {
|
||||||
|
+ } else if (apdu.sw2 == 0x06) {
|
||||||
|
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_ALLOWED);
|
||||||
|
- } else if(apdu.sw2 == 0x0F) {
|
||||||
|
+ } else if (apdu.sw2 == 0x0F) {
|
||||||
|
/* GUESSED */
|
||||||
|
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sc_log(card->ctx,
|
||||||
|
"got strange SWs: 0x%02X 0x%02X\n", apdu.sw1, apdu.sw2);
|
||||||
|
- return dataLength;
|
||||||
|
-
|
||||||
|
-}
|
||||||
|
+
|
||||||
|
+ SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_UNKNOWN_DATA_RECEIVED);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
int msc_read_object(sc_card_t *card, msc_id objectId, int offset, u8 *data, size_t dataLength)
|
||||||
|
{
|
||||||
|
- int r;
|
||||||
|
+ int r = 0;
|
||||||
|
size_t 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 dataLength;
|
||||||
|
}
|
||||||
|
Index: opensc-0.23.0/src/libopensc/card-entersafe.c
|
||||||
|
===================================================================
|
||||||
|
--- opensc-0.23.0.orig/src/libopensc/card-entersafe.c
|
||||||
|
+++ opensc-0.23.0/src/libopensc/card-entersafe.c
|
||||||
|
@@ -1453,7 +1453,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);
|
||||||
55
opensc-CVE-2024-45617.patch
Normal file
55
opensc-CVE-2024-45617.patch
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
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.23.0/src/libopensc/card-cac.c
|
||||||
|
===================================================================
|
||||||
|
--- opensc-0.23.0.orig/src/libopensc/card-cac.c
|
||||||
|
+++ opensc-0.23.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.23.0/src/libopensc/card-cardos.c
|
||||||
|
===================================================================
|
||||||
|
--- opensc-0.23.0.orig/src/libopensc/card-cardos.c
|
||||||
|
+++ opensc-0.23.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.23.0/src/libopensc/card-jpki.c
|
||||||
|
===================================================================
|
||||||
|
--- opensc-0.23.0.orig/src/libopensc/card-jpki.c
|
||||||
|
+++ opensc-0.23.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);
|
||||||
67
opensc-CVE-2024-45618.patch
Normal file
67
opensc-CVE-2024-45618.patch
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
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));
|
||||||
221
opensc-CVE-2024-45619.patch
Normal file
221
opensc-CVE-2024-45619.patch
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
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.23.0/src/libopensc/pkcs15-tcos.c
|
||||||
|
===================================================================
|
||||||
|
--- opensc-0.23.0.orig/src/libopensc/pkcs15-tcos.c
|
||||||
|
+++ opensc-0.23.0/src/libopensc/pkcs15-tcos.c
|
||||||
|
@@ -45,6 +45,7 @@ static int insert_cert(
|
||||||
|
struct sc_pkcs15_cert_info cert_info;
|
||||||
|
struct sc_pkcs15_object cert_obj;
|
||||||
|
unsigned char cert[20];
|
||||||
|
+ size_t cert_len = 0;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
memset(&cert_info, 0, sizeof(cert_info));
|
||||||
|
@@ -57,24 +58,31 @@ static int insert_cert(
|
||||||
|
strlcpy(cert_obj.label, label, sizeof(cert_obj.label));
|
||||||
|
cert_obj.flags = writable ? SC_PKCS15_CO_FLAG_MODIFIABLE : 0;
|
||||||
|
|
||||||
|
- if(sc_select_file(card, &cert_info.path, NULL)!=SC_SUCCESS){
|
||||||
|
- sc_log(ctx,
|
||||||
|
- "Select(%s) failed\n", path);
|
||||||
|
+ if (sc_select_file(card, &cert_info.path, NULL) != SC_SUCCESS) {
|
||||||
|
+ sc_log(ctx, "Select(%s) failed", path);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
- if(sc_read_binary(card, 0, cert, sizeof(cert), 0)<0){
|
||||||
|
- sc_log(ctx,
|
||||||
|
- "ReadBinary(%s) failed\n", path);
|
||||||
|
+ r = sc_read_binary(card, 0, cert, sizeof(cert), 0);
|
||||||
|
+ if (r <= 0) {
|
||||||
|
+ sc_log(ctx, "ReadBinary(%s) failed\n", path);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
- if(cert[0]!=0x30 || cert[1]!=0x82){
|
||||||
|
- sc_log(ctx,
|
||||||
|
- "Invalid Cert: %02X:%02X:...\n", cert[0], cert[1]);
|
||||||
|
+ cert_len = r; /* actual number of read bytes */
|
||||||
|
+ if (cert_len < 7 || (size_t)(7 + cert[5]) > cert_len) {
|
||||||
|
+ sc_log(ctx, "Invalid certificate length");
|
||||||
|
+ return 3;
|
||||||
|
+ }
|
||||||
|
+ if (cert[0] != 0x30 || cert[1] != 0x82) {
|
||||||
|
+ sc_log(ctx, "Invalid Cert: %02X:%02X:...\n", cert[0], cert[1]);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* some certificates are prefixed by an OID */
|
||||||
|
- if(cert[4]==0x06 && cert[5]<10 && cert[6+cert[5]]==0x30 && cert[7+cert[5]]==0x82){
|
||||||
|
+ if (cert[4] == 0x06 && cert[5] < 10 && cert[6 + cert[5]] == 0x30 && cert[7 + cert[5]] == 0x82) {
|
||||||
|
+ if ((size_t)(9 + cert[5]) > cert_len) {
|
||||||
|
+ sc_log(ctx, "Invalid certificate length");
|
||||||
|
+ return 3;
|
||||||
|
+ }
|
||||||
|
cert_info.path.index=6+cert[5];
|
||||||
|
cert_info.path.count=(cert[8+cert[5]]<<8) + cert[9+cert[5]] + 4;
|
||||||
|
} else {
|
||||||
|
@@ -82,12 +90,12 @@ static int insert_cert(
|
||||||
|
cert_info.path.count=(cert[2]<<8) + cert[3] + 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
- r=sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info);
|
||||||
|
- if(r!=SC_SUCCESS){
|
||||||
|
- sc_log(ctx, "sc_pkcs15emu_add_x509_cert(%s) failed\n", path);
|
||||||
|
+ r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info);
|
||||||
|
+ if (r != SC_SUCCESS) {
|
||||||
|
+ sc_log(ctx, "sc_pkcs15emu_add_x509_cert(%s) failed", path);
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
- sc_log(ctx, "%s: OK, Index=%d, Count=%d\n", path, cert_info.path.index, cert_info.path.count);
|
||||||
|
+ sc_log(ctx, "%s: OK, Index=%d, Count=%d", path, cert_info.path.index, cert_info.path.count);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Index: opensc-0.23.0/src/libopensc/pkcs15-gemsafeV1.c
|
||||||
|
===================================================================
|
||||||
|
--- opensc-0.23.0.orig/src/libopensc/pkcs15-gemsafeV1.c
|
||||||
|
+++ opensc-0.23.0/src/libopensc/pkcs15-gemsafeV1.c
|
||||||
|
@@ -168,6 +168,7 @@ static int gemsafe_get_cert_len(sc_card_
|
||||||
|
struct sc_file *file;
|
||||||
|
size_t objlen, certlen;
|
||||||
|
unsigned int ind, i=0;
|
||||||
|
+ int read_len;
|
||||||
|
|
||||||
|
sc_format_path(GEMSAFE_PATH, &path);
|
||||||
|
r = sc_select_file(card, &path, &file);
|
||||||
|
@@ -176,9 +177,11 @@ static int gemsafe_get_cert_len(sc_card_
|
||||||
|
sc_file_free(file);
|
||||||
|
|
||||||
|
/* Initial read */
|
||||||
|
- r = sc_read_binary(card, 0, ibuf, GEMSAFE_READ_QUANTUM, 0);
|
||||||
|
- if (r < 0)
|
||||||
|
+ read_len = sc_read_binary(card, 0, ibuf, GEMSAFE_READ_QUANTUM, 0);
|
||||||
|
+ if (read_len <= 2) {
|
||||||
|
+ sc_log(card->ctx, "Invalid size of object data: %d", read_len);
|
||||||
|
return SC_ERROR_INTERNAL;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/* Actual stored object size is encoded in first 2 bytes
|
||||||
|
* (allocated EF space is much greater!)
|
||||||
|
@@ -207,7 +210,7 @@ static int gemsafe_get_cert_len(sc_card_
|
||||||
|
* the private key.
|
||||||
|
*/
|
||||||
|
ind = 2; /* skip length */
|
||||||
|
- while (ibuf[ind] == 0x01 && i < gemsafe_cert_max) {
|
||||||
|
+ while (ind + 1 < (size_t)read_len && ibuf[ind] == 0x01 && i < gemsafe_cert_max) {
|
||||||
|
if (ibuf[ind+1] == 0xFE) {
|
||||||
|
gemsafe_prkeys[i].ref = ibuf[ind+4];
|
||||||
|
sc_log(card->ctx, "Key container %d is allocated and uses key_ref %d",
|
||||||
|
@@ -234,7 +237,7 @@ static int gemsafe_get_cert_len(sc_card_
|
||||||
|
/* Read entire file, then dissect in memory.
|
||||||
|
* Gemalto ClassicClient seems to do it the same way.
|
||||||
|
*/
|
||||||
|
- iptr = ibuf + GEMSAFE_READ_QUANTUM;
|
||||||
|
+ iptr = ibuf + read_len;
|
||||||
|
while ((size_t)(iptr - ibuf) < objlen) {
|
||||||
|
r = sc_read_binary(card, iptr - ibuf, iptr,
|
||||||
|
MIN(GEMSAFE_READ_QUANTUM, objlen - (iptr - ibuf)), 0);
|
||||||
|
@@ -242,7 +245,14 @@ static int gemsafe_get_cert_len(sc_card_
|
||||||
|
sc_log(card->ctx, "Could not read cert object");
|
||||||
|
return SC_ERROR_INTERNAL;
|
||||||
|
}
|
||||||
|
- iptr += GEMSAFE_READ_QUANTUM;
|
||||||
|
+ if (r == 0)
|
||||||
|
+ break;
|
||||||
|
+ read_len += r;
|
||||||
|
+ iptr += r;
|
||||||
|
+ }
|
||||||
|
+ if ((size_t)read_len < objlen) {
|
||||||
|
+ sc_log(card->ctx, "Could not read cert object");
|
||||||
|
+ return SC_ERROR_INTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Search buffer for certificates, they start with 0x3082. */
|
||||||
|
Index: opensc-0.23.0/src/pkcs15init/pkcs15-setcos.c
|
||||||
|
===================================================================
|
||||||
|
--- opensc-0.23.0.orig/src/pkcs15init/pkcs15-setcos.c
|
||||||
|
+++ opensc-0.23.0/src/pkcs15init/pkcs15-setcos.c
|
||||||
|
@@ -488,6 +488,9 @@ setcos_generate_key(struct sc_profile *p
|
||||||
|
r = sc_card_ctl(p15card->card, SC_CARDCTL_SETCOS_GETDATA, &data_obj);
|
||||||
|
LOG_TEST_RET(ctx, r, "Cannot get key modulus: 'SETCOS_GETDATA' failed");
|
||||||
|
|
||||||
|
+ if (data_obj.DataLen < 3 || data_obj.DataLen < pubkey->u.rsa.modulus.len)
|
||||||
|
+ LOG_TEST_RET(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED, "Cannot get key modulus: wrong length of raw key");
|
||||||
|
+
|
||||||
|
keybits = ((raw_pubkey[0] * 256) + raw_pubkey[1]); /* modulus bit length */
|
||||||
|
if (keybits != key_info->modulus_length) {
|
||||||
|
sc_log(ctx,
|
||||||
|
@@ -495,7 +498,7 @@ setcos_generate_key(struct sc_profile *p
|
||||||
|
keybits, key_info->modulus_length);
|
||||||
|
LOG_TEST_RET(ctx, SC_ERROR_PKCS15INIT, "Failed to generate key");
|
||||||
|
}
|
||||||
|
- memcpy (pubkey->u.rsa.modulus.data, &raw_pubkey[2], pubkey->u.rsa.modulus.len);
|
||||||
|
+ memcpy(pubkey->u.rsa.modulus.data, &raw_pubkey[2], pubkey->u.rsa.modulus.len);
|
||||||
|
}
|
||||||
|
|
||||||
|
sc_file_free(file);
|
||||||
|
Index: opensc-0.23.0/src/pkcs15init/pkcs15-sc-hsm.c
|
||||||
|
===================================================================
|
||||||
|
--- opensc-0.23.0.orig/src/pkcs15init/pkcs15-sc-hsm.c
|
||||||
|
+++ opensc-0.23.0/src/pkcs15init/pkcs15-sc-hsm.c
|
||||||
|
@@ -140,7 +140,7 @@ static int sc_hsm_determine_free_id(stru
|
||||||
|
LOG_TEST_RET(card->ctx, filelistlength, "Could not enumerate file and key identifier");
|
||||||
|
|
||||||
|
for (j = 0; j < 256; j++) {
|
||||||
|
- for (i = 0; i < filelistlength; i += 2) {
|
||||||
|
+ for (i = 0; i + 1 < filelistlength; i += 2) {
|
||||||
|
if ((filelist[i] == range) && (filelist[i + 1] == j)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Index: opensc-0.23.0/src/libopensc/card-coolkey.c
|
||||||
|
===================================================================
|
||||||
|
--- opensc-0.23.0.orig/src/libopensc/card-coolkey.c
|
||||||
|
+++ opensc-0.23.0/src/libopensc/card-coolkey.c
|
||||||
|
@@ -1684,6 +1684,7 @@ static int coolkey_rsa_op(sc_card_t *car
|
||||||
|
u8 key_number;
|
||||||
|
size_t params_len;
|
||||||
|
u8 buf[MAX_COMPUTE_BUF + 2];
|
||||||
|
+ size_t buf_len;
|
||||||
|
u8 *buf_out;
|
||||||
|
|
||||||
|
SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
|
||||||
|
@@ -1724,8 +1725,6 @@ static int coolkey_rsa_op(sc_card_t *car
|
||||||
|
ushort2bebytes(params.init.buf_len, 0);
|
||||||
|
} else {
|
||||||
|
/* The data fits in APDU. Copy it to the params object */
|
||||||
|
- size_t buf_len;
|
||||||
|
-
|
||||||
|
params.init.location = COOLKEY_CRYPT_LOCATION_APDU;
|
||||||
|
|
||||||
|
params_len = sizeof(params.init) + datalen;
|
||||||
|
@@ -1745,6 +1744,7 @@ static int coolkey_rsa_op(sc_card_t *car
|
||||||
|
if (r < 0) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
+ buf_len = crypt_out_len_p;
|
||||||
|
|
||||||
|
if (datalen > MAX_COMPUTE_BUF) {
|
||||||
|
u8 len_buf[2];
|
||||||
|
@@ -1763,7 +1763,12 @@ static int coolkey_rsa_op(sc_card_t *car
|
||||||
|
priv->nonce, sizeof(priv->nonce));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
- size_t out_length = bebytes2ushort(buf);
|
||||||
|
+ size_t out_length;
|
||||||
|
+ if (buf_len < 2) {
|
||||||
|
+ r = SC_ERROR_WRONG_LENGTH;
|
||||||
|
+ goto done;
|
||||||
|
+ }
|
||||||
|
+ out_length = bebytes2ushort(buf);
|
||||||
|
if (out_length > sizeof buf - 2) {
|
||||||
|
r = SC_ERROR_WRONG_LENGTH;
|
||||||
|
goto done;
|
||||||
73
opensc-CVE-2024-45620.patch
Normal file
73
opensc-CVE-2024-45620.patch
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
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.23.0/src/pkcs15init/pkcs15-starcos.c
|
||||||
|
===================================================================
|
||||||
|
--- opensc-0.23.0.orig/src/pkcs15init/pkcs15-starcos.c
|
||||||
|
+++ opensc-0.23.0/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;
|
||||||
|
@@ -682,7 +684,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.23.0/src/libopensc/iasecc-sdo.c
|
||||||
|
===================================================================
|
||||||
|
--- opensc-0.23.0.orig/src/libopensc/iasecc-sdo.c
|
||||||
|
+++ opensc-0.23.0/src/libopensc/iasecc-sdo.c
|
||||||
|
@@ -324,16 +324,25 @@ 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, &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 %"SC_FORMAT_LEN_SIZE_T"u",
|
||||||
|
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);
|
||||||
|
|
||||||
|
@@ -728,6 +737,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, &size);
|
||||||
|
|
||||||
78
opensc-CVE-2024-8443.patch
Normal file
78
opensc-CVE-2024-8443.patch
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
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.23.0/src/libopensc/card-openpgp.c
|
||||||
|
===================================================================
|
||||||
|
--- opensc-0.23.0.orig/src/libopensc/card-openpgp.c
|
||||||
|
+++ opensc-0.23.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 */
|
||||||
53
opensc.spec
53
opensc.spec
@ -3,12 +3,44 @@
|
|||||||
|
|
||||||
Name: opensc
|
Name: opensc
|
||||||
Version: 0.23.0
|
Version: 0.23.0
|
||||||
Release: 2
|
Release: 7
|
||||||
License: LGPL-2.1-or-later
|
License: LGPL-2.1-or-later
|
||||||
Summary: Smart card library and applications
|
Summary: Smart card library and applications
|
||||||
URL: https://github.com/OpenSC/OpenSC/wiki
|
URL: https://github.com/OpenSC/OpenSC/wiki
|
||||||
Source0: https://github.com/OpenSC/OpenSC/releases/download/%{version}/%{name}-%{version}.tar.gz
|
Source0: https://github.com/OpenSC/OpenSC/releases/download/%{version}/%{name}-%{version}.tar.gz
|
||||||
Patch0: 0001-correct_left_length_calculation_to_fix_buffer.patch
|
Patch0: 0001-correct_left_length_calculation_to_fix_buffer.patch
|
||||||
|
Patch1: 0002-Prevent_stack_buffer_overflow_when_empty_ACL_is_returned.patch
|
||||||
|
# PATCH-FIX-UPSTREAM: CVE-2023-40660: PIN bypass when card tracks its own login state
|
||||||
|
Patch2: 0003-opensc-CVE-2023-40660-1of2.patch
|
||||||
|
Patch3: 0004-opensc-CVE-2023-40660-2of2.patch
|
||||||
|
# PATCH-FIX-UPSTREAM: CVE-2023-4535: out-of-bounds read in MyEID driver handling encryption using symmetric keys
|
||||||
|
Patch4: 0005-opensc-NULL_pointer_fix.patch
|
||||||
|
Patch5: 0006-opensc-CVE-2023-4535.patch
|
||||||
|
# PATCH-FIX-UPSTREAM: CVE-2023-40661: multiple memory issues with pkcs15-init (enrollment tool)
|
||||||
|
Patch6: 0007-opensc-CVE-2023-40661-1of12.patch
|
||||||
|
Patch7: 0008-opensc-CVE-2023-40661-2of12.patch
|
||||||
|
Patch8: 0009-opensc-CVE-2023-40661-3of12.patch
|
||||||
|
Patch9: 0010-opensc-CVE-2023-40661-4of12.patch
|
||||||
|
Patch10: 0011-opensc-CVE-2023-40661-5of12.patch
|
||||||
|
Patch11: 0012-opensc-CVE-2023-40661-6of12.patch
|
||||||
|
Patch12: 0013-opensc-CVE-2023-40661-7of12.patch
|
||||||
|
Patch13: 0014-opensc-CVE-2023-40661-8of12.patch
|
||||||
|
Patch14: 0015-opensc-CVE-2023-40661-9of12.patch
|
||||||
|
Patch15: 0016-opensc-CVE-2023-40661-10of12.patch
|
||||||
|
Patch16: 0017-opensc-CVE-2023-40661-11of12.patch
|
||||||
|
Patch17: 0018-opensc-CVE-2023-40661-12of12.patch
|
||||||
|
#CVE-2023-5992 constant-time-pkcs1.5.patch
|
||||||
|
# https://github.com/OpenSC/OpenSC/pull/2948
|
||||||
|
# https://github.com/OpenSC/OpenSC/pull/3016
|
||||||
|
Patch18: 0019-opensc-CVE-2023-5992.patch
|
||||||
|
Patch19: 0020-backport-avoid-calling-functions-without-prototype.patch
|
||||||
|
Patch20: opensc-CVE-2024-45615.patch
|
||||||
|
Patch21: opensc-CVE-2024-45616.patch
|
||||||
|
Patch22: opensc-CVE-2024-45617.patch
|
||||||
|
Patch23: opensc-CVE-2024-45618.patch
|
||||||
|
Patch24: opensc-CVE-2024-45619.patch
|
||||||
|
Patch25: opensc-CVE-2024-45620.patch
|
||||||
|
Patch26: opensc-CVE-2024-8443.patch
|
||||||
|
|
||||||
BuildRequires: openssl-devel pcsc-lite-devel bash-completion docbook-style-xsl readline-devel
|
BuildRequires: openssl-devel pcsc-lite-devel bash-completion docbook-style-xsl readline-devel
|
||||||
BuildRequires: desktop-file-utils /usr/bin/xsltproc autoconf automake libtool gcc
|
BuildRequires: desktop-file-utils /usr/bin/xsltproc autoconf automake libtool gcc
|
||||||
@ -40,6 +72,9 @@ cp -p src/pkcs15init/README ./README.pkcs15init
|
|||||||
cp -p src/scconf/README.scconf .
|
cp -p src/scconf/README.scconf .
|
||||||
|
|
||||||
%build
|
%build
|
||||||
|
%if "%toolchain" == "clang"
|
||||||
|
CFLAGS="$CFLAGS -Wno-error=unused-command-line-argument -Wno-error=unused-but-set-variable"
|
||||||
|
%endif
|
||||||
autoreconf -fvi
|
autoreconf -fvi
|
||||||
sed -i -e 's/opensc.conf/opensc-%{_arch}.conf/g' src/libopensc/Makefile.in
|
sed -i -e 's/opensc.conf/opensc-%{_arch}.conf/g' src/libopensc/Makefile.in
|
||||||
sed -i -e 's|"/lib /usr/lib\b|"/%{_lib} %{_libdir}|' configure # lib64 rpaths
|
sed -i -e 's|"/lib /usr/lib\b|"/%{_lib} %{_libdir}|' configure # lib64 rpaths
|
||||||
@ -139,6 +174,22 @@ make check
|
|||||||
%{_datadir}/opensc/
|
%{_datadir}/opensc/
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Oct 07 2024 Funda Wang <fundawang@yeah.net> - 0.23.0-7
|
||||||
|
- fix CVE-2024-8443, CVE-2024-45615, CVE-2024-45616,
|
||||||
|
CVE-2024-45617, CVE-2024-45618, CVE-2024-45619, CVE-2024-45620
|
||||||
|
|
||||||
|
* Sun Sep 1 2024 yuanchao <1050706328@qq.com> - 0.23.0-6
|
||||||
|
- backport:avoid calling functions without prototype,and add compiler flags to support clang build
|
||||||
|
|
||||||
|
* Fri Jun 28 2024 dillon chen <dillon.chen@gmail.com> - 0.23.0-5
|
||||||
|
- fix CVE-2023-5992
|
||||||
|
|
||||||
|
* Fri Oct 20 2023 dillon chen <dillon.chen@gmail.com> - 0.23.0-4
|
||||||
|
- fix CVE-2023-40660 CVE-2023-4535 CVE-2023-40661
|
||||||
|
|
||||||
|
* Wed Sep 6 2023 Zhengxin Guo <guozhengxin@kylinos.cn> - 0.23.0-3
|
||||||
|
- fix CVE-2021-34193
|
||||||
|
|
||||||
* Tue Sep 5 2023 Zhengxin Guo <guozhengxin@kylinos.cn> - 0.23.0-2
|
* Tue Sep 5 2023 Zhengxin Guo <guozhengxin@kylinos.cn> - 0.23.0-2
|
||||||
- fix CVE-2023-2977
|
- fix CVE-2023-2977
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user