Skip to content

Commit 10b80b4

Browse files
[Low] Patch opensc for CVE-2023-40661 & CVE-2024-45619 (#13819)
1 parent 0e51963 commit 10b80b4

File tree

3 files changed

+510
-1
lines changed

3 files changed

+510
-1
lines changed

SPECS/opensc/CVE-2023-40661.patch

Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
From 8bdc60b2f46a53771b02d47721502a104f577b0f Mon Sep 17 00:00:00 2001
2+
From: akhila-guruju <[email protected]>
3+
Date: Fri, 16 May 2025 06:57:40 +0000
4+
Subject: [PATCH] Address CVE-2023-40661
5+
6+
Upstream Patch reference: https://github.com/OpenSC/OpenSC/issues/2792#issuecomment-1674806651
7+
8+
---
9+
src/libopensc/card-sc-hsm.c | 84 +++++++++++++++++++-------------
10+
src/libopensc/muscle.c | 3 ++
11+
src/libopensc/pkcs15-pubkey.c | 6 +++
12+
src/libopensc/pkcs15.c | 10 ++--
13+
src/pkcs15init/pkcs15-cflex.c | 3 ++
14+
src/pkcs15init/pkcs15-lib.c | 2 +
15+
src/pkcs15init/pkcs15-oberthur.c | 3 ++
16+
src/pkcs15init/pkcs15-setcos.c | 4 ++
17+
src/pkcs15init/profile.c | 6 +++
18+
9 files changed, 84 insertions(+), 37 deletions(-)
19+
20+
diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c
21+
index 6999e71..922ae1b 100644
22+
--- a/src/libopensc/card-sc-hsm.c
23+
+++ b/src/libopensc/card-sc-hsm.c
24+
@@ -786,7 +786,7 @@ static int sc_hsm_logout(sc_card_t * card)
25+
}
26+
27+
28+
-
29+
+/* NOTE: idx is an offset into the card's file, not into buf */
30+
static int sc_hsm_read_binary(sc_card_t *card,
31+
unsigned int idx, u8 *buf, size_t count,
32+
unsigned long flags)
33+
@@ -827,7 +827,7 @@ static int sc_hsm_read_binary(sc_card_t *card,
34+
}
35+
36+
37+
-
38+
+/* NOTE: idx is an offset into the card's file, not into buf */
39+
static int sc_hsm_write_ef(sc_card_t *card,
40+
int fid,
41+
unsigned int idx, const u8 *buf, size_t count)
42+
@@ -848,41 +848,59 @@ static int sc_hsm_write_ef(sc_card_t *card,
43+
LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
44+
}
45+
46+
- p = cmdbuff;
47+
- *p++ = 0x54;
48+
- *p++ = 0x02;
49+
- *p++ = (idx >> 8) & 0xFF;
50+
- *p++ = idx & 0xFF;
51+
- *p++ = 0x53;
52+
- if (count < 128) {
53+
- *p++ = (u8) count;
54+
- len = 6;
55+
- } else if (count < 256) {
56+
- *p++ = 0x81;
57+
- *p++ = (u8) count;
58+
- len = 7;
59+
- } else {
60+
- *p++ = 0x82;
61+
- *p++ = (count >> 8) & 0xFF;
62+
- *p++ = count & 0xFF;
63+
- len = 8;
64+
- }
65+
+ size_t bytes_left = count;
66+
+ // 8 bytes are required for T54(4) and T53(4)
67+
+ size_t blk_size = card->max_send_size - 8;
68+
+ size_t to_send = 0;
69+
+ size_t file_offset = (size_t) idx;
70+
+ size_t offset = 0;
71+
72+
- if (buf != NULL)
73+
- memcpy(p, buf, count);
74+
- len += count;
75+
76+
- sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xD7, fid >> 8, fid & 0xFF);
77+
- apdu.data = cmdbuff;
78+
- apdu.datalen = len;
79+
- apdu.lc = len;
80+
+ do {
81+
+ to_send = bytes_left >= blk_size ? blk_size : bytes_left;
82+
+ p = cmdbuff;
83+
+ // ASN1 0x54 offset
84+
+ *p++ = 0x54;
85+
+ *p++ = 0x02;
86+
+ *p++ = (file_offset >> 8) & 0xFF;
87+
+ *p++ = file_offset & 0xFF;
88+
+ // ASN1 0x53 to_send
89+
+ *p++ = 0x53;
90+
+ if (to_send < 128) {
91+
+ *p++ = (u8)to_send;
92+
+ len = 6;
93+
+ } else if (to_send < 256) {
94+
+ *p++ = 0x81;
95+
+ *p++ = (u8)to_send;
96+
+ len = 7;
97+
+ } else {
98+
+ *p++ = 0x82;
99+
+ *p++ = (to_send >> 8) & 0xFF;
100+
+ *p++ = to_send & 0xFF;
101+
+ len = 8;
102+
+ }
103+
104+
- r = sc_transmit_apdu(card, &apdu);
105+
- free(cmdbuff);
106+
- LOG_TEST_RET(ctx, r, "APDU transmit failed");
107+
+ if (buf != NULL)
108+
+ memcpy(p, buf+offset, to_send);
109+
+ len += to_send;
110+
111+
- r = sc_check_sw(card, apdu.sw1, apdu.sw2);
112+
- LOG_TEST_RET(ctx, r, "Check SW error");
113+
+ sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xD7, fid >> 8, fid & 0xFF);
114+
+ apdu.data = cmdbuff;
115+
+ apdu.datalen = len;
116+
+ apdu.lc = len;
117+
+
118+
+ r = sc_transmit_apdu(card, &apdu);
119+
+ LOG_TEST_GOTO_ERR(ctx, r, "APDU transmit failed");
120+
+ r = sc_check_sw(card, apdu.sw1, apdu.sw2);
121+
+ LOG_TEST_GOTO_ERR(ctx, r, "Check SW error");
122+
+
123+
+ bytes_left -= to_send;
124+
+ offset += to_send;
125+
+ file_offset += to_send;
126+
+ } while (0 < bytes_left);
127+
+
128+
+err:
129+
+ free(cmdbuff);
130+
131+
LOG_FUNC_RETURN(ctx, count);
132+
}
133+
diff --git a/src/libopensc/muscle.c b/src/libopensc/muscle.c
134+
index 7af279a..a749657 100644
135+
--- a/src/libopensc/muscle.c
136+
+++ b/src/libopensc/muscle.c
137+
@@ -181,6 +181,9 @@ int msc_partial_update_object(sc_card_t *card, msc_id objectId, int offset, cons
138+
sc_apdu_t apdu;
139+
int r;
140+
141+
+ if (dataLength + 9 > MSC_MAX_APDU)
142+
+ return SC_ERROR_INVALID_ARGUMENTS;
143+
+
144+
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x54, 0x00, 0x00);
145+
apdu.lc = dataLength + 9;
146+
if (card->ctx->debug >= 2)
147+
diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c
148+
index ee4ee46..bc5fa45 100644
149+
--- a/src/libopensc/pkcs15-pubkey.c
150+
+++ b/src/libopensc/pkcs15-pubkey.c
151+
@@ -351,6 +351,12 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card,
152+
err:
153+
if (r < 0) {
154+
sc_pkcs15_free_pubkey_info(info);
155+
+ if (der->len) {
156+
+ free(der->value);
157+
+ /* der points to obj->content */
158+
+ obj->content.value = NULL;
159+
+ obj->content.len = 0;
160+
+ }
161+
}
162+
163+
LOG_FUNC_RETURN(ctx, r);
164+
diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c
165+
index 4054f8e..eea022d 100644
166+
--- a/src/libopensc/pkcs15.c
167+
+++ b/src/libopensc/pkcs15.c
168+
@@ -528,7 +528,7 @@ sc_pkcs15_get_lastupdate(struct sc_pkcs15_card *p15card)
169+
struct sc_context *ctx = p15card->card->ctx;
170+
struct sc_file *file = NULL;
171+
struct sc_asn1_entry asn1_last_update[C_ASN1_LAST_UPDATE_SIZE];
172+
- unsigned char *content, last_update[32];
173+
+ unsigned char *content, last_update[32] = {0};
174+
size_t lupdate_len = sizeof(last_update) - 1;
175+
int r, content_len;
176+
size_t size;
177+
@@ -564,9 +564,11 @@ sc_pkcs15_get_lastupdate(struct sc_pkcs15_card *p15card)
178+
if (r < 0)
179+
return NULL;
180+
181+
- p15card->tokeninfo->last_update.gtime = strdup((char *)last_update);
182+
- if (!p15card->tokeninfo->last_update.gtime)
183+
- return NULL;
184+
+ if (asn1_last_update[0].flags & SC_ASN1_PRESENT) {
185+
+ p15card->tokeninfo->last_update.gtime = strdup((char *)last_update);
186+
+ if (!p15card->tokeninfo->last_update.gtime)
187+
+ return NULL;
188+
+ }
189+
done:
190+
sc_log(ctx, "lastUpdate.gtime '%s'", p15card->tokeninfo->last_update.gtime);
191+
return p15card->tokeninfo->last_update.gtime;
192+
diff --git a/src/pkcs15init/pkcs15-cflex.c b/src/pkcs15init/pkcs15-cflex.c
193+
index 1cb55c1..8ea7dbd 100644
194+
--- a/src/pkcs15init/pkcs15-cflex.c
195+
+++ b/src/pkcs15init/pkcs15-cflex.c
196+
@@ -56,6 +56,9 @@ cflex_delete_file(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *d
197+
int r = 0;
198+
/* Select the parent DF */
199+
path = df->path;
200+
+ if (path.len < 2) {
201+
+ return SC_ERROR_INVALID_ARGUMENTS;
202+
+ }
203+
path.len -= 2;
204+
r = sc_select_file(p15card->card, &path, &parent);
205+
if (r < 0)
206+
diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c
207+
index 91cee37..3df03c6 100644
208+
--- a/src/pkcs15init/pkcs15-lib.c
209+
+++ b/src/pkcs15init/pkcs15-lib.c
210+
@@ -685,6 +685,8 @@ sc_pkcs15init_rmdir(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
211+
212+
path = df->path;
213+
path.len += 2;
214+
+ if (path.len > SC_MAX_PATH_SIZE)
215+
+ return SC_ERROR_INTERNAL;
216+
217+
nfids = r / 2;
218+
while (r >= 0 && nfids--) {
219+
diff --git a/src/pkcs15init/pkcs15-oberthur.c b/src/pkcs15init/pkcs15-oberthur.c
220+
index 9239541..7f48cdf 100644
221+
--- a/src/pkcs15init/pkcs15-oberthur.c
222+
+++ b/src/pkcs15init/pkcs15-oberthur.c
223+
@@ -684,6 +684,9 @@ cosm_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
224+
if (object->type != SC_PKCS15_TYPE_PRKEY_RSA)
225+
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Create key failed: RSA only supported");
226+
227+
+ if (key_info->path.len < 2)
228+
+ LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_VALID, "The path needs to be at least to bytes long");
229+
+
230+
sc_log(ctx, "create private key ID:%s", sc_pkcs15_print_id(&key_info->id));
231+
/* Here, the path of private key file should be defined.
232+
* Nevertheless, we need to instantiate private key to get the ACLs. */
233+
diff --git a/src/pkcs15init/pkcs15-setcos.c b/src/pkcs15init/pkcs15-setcos.c
234+
index 52b234f..7dfd281 100644
235+
--- a/src/pkcs15init/pkcs15-setcos.c
236+
+++ b/src/pkcs15init/pkcs15-setcos.c
237+
@@ -349,6 +349,10 @@ setcos_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
238+
239+
/* Replace the path of instantiated key template by the path from the object data. */
240+
memcpy(&file->path, &key_info->path, sizeof(file->path));
241+
+ if (file->path.len < 2) {
242+
+ sc_file_free(file);
243+
+ LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Invalid path");
244+
+ }
245+
file->id = file->path.value[file->path.len - 2] * 0x100
246+
+ file->path.value[file->path.len - 1];
247+
248+
diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c
249+
index b8b3ddb..74fbdce 100644
250+
--- a/src/pkcs15init/profile.c
251+
+++ b/src/pkcs15init/profile.c
252+
@@ -1575,7 +1575,10 @@ do_acl(struct state *cur, int argc, char **argv)
253+
while (argc--) {
254+
unsigned int op, method, id;
255+
256+
+ if (strlen(*argv) >= sizeof(oper))
257+
+ goto bad;
258+
strlcpy(oper, *argv++, sizeof(oper));
259+
+
260+
if ((what = strchr(oper, '=')) == NULL)
261+
goto bad;
262+
*what++ = '\0';
263+
@@ -2270,6 +2273,9 @@ get_authid(struct state *cur, const char *value,
264+
return get_uint(cur, value, type);
265+
}
266+
267+
+ if (strlen(value) >= sizeof(temp))
268+
+ return 1;
269+
+
270+
n = strcspn(value, "0123456789x");
271+
strlcpy(temp, value, (sizeof(temp) > n) ? n + 1 : sizeof(temp));
272+
273+
--
274+
2.45.2
275+

0 commit comments

Comments
 (0)