Compare commits

..

No commits in common. "c9-beta" and "c8" have entirely different histories.
c9-beta ... c8

24 changed files with 7512 additions and 3649 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/opensc-0.23.0.tar.gz
SOURCES/opensc-0.20.0.tar.gz

View File

@ -1 +1 @@
5a5367ef33efcc35ed420b191b4d1bc3aa34a538 SOURCES/opensc-0.23.0.tar.gz
86bf24a556837fa94d8f9b5aa4be3c9e55d4d94d SOURCES/opensc-0.20.0.tar.gz

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@ diff -up opensc-0.19.0/etc/opensc.conf.pinpad opensc-0.19.0/etc/opensc.conf
+++ opensc-0.19.0/etc/opensc.conf 2018-10-22 14:33:59.939410701 +0200
@@ -4,4 +4,9 @@ app default {
framework pkcs15 {
# use_file_caching = public;
# use_file_caching = true;
}
+ reader_driver pcsc {
+ # The pinpad is disabled by default,

View File

@ -0,0 +1,31 @@
commit 6903aebfddc466d966c7b865fae34572bf3ed23e
Author: Frank Morgner <frankmorgner@gmail.com>
Date: Thu Jul 30 02:21:17 2020 +0200
Heap-buffer-overflow WRITE
fixes https://oss-fuzz.com/testcase-detail/5088104168554496
diff --git a/src/libopensc/pkcs15-oberthur.c b/src/libopensc/pkcs15-oberthur.c
index a873aaa0..2fb32b8d 100644
--- a/src/libopensc/pkcs15-oberthur.c
+++ b/src/libopensc/pkcs15-oberthur.c
@@ -271,11 +271,15 @@ sc_oberthur_read_file(struct sc_pkcs15_card *p15card, const char *in_path,
rv = sc_read_binary(card, 0, *out, sz, 0);
}
else {
- int rec;
- int offs = 0;
- int rec_len = file->record_length;
+ size_t rec;
+ size_t offs = 0;
+ size_t rec_len = file->record_length;
for (rec = 1; ; rec++) {
+ if (rec > file->record_count) {
+ rv = 0;
+ break;
+ }
rv = sc_read_record(card, rec, *out + offs + 2, rec_len, SC_RECORD_BY_REC_NR);
if (rv == SC_ERROR_RECORD_NOT_FOUND) {
rv = 0;

View File

@ -0,0 +1,42 @@
commit ed55fcd2996930bf58b9bb57e9ba7b1f3a753c43
Author: Frank Morgner <frankmorgner@gmail.com>
Date: Mon May 18 17:25:32 2020 +0200
fixed invalid read
fixes https://oss-fuzz.com/testcase-detail/5765246676631552
diff --git a/src/libopensc/pkcs15-gemsafeGPK.c b/src/libopensc/pkcs15-gemsafeGPK.c
index e13f3b87..4b80daf2 100644
--- a/src/libopensc/pkcs15-gemsafeGPK.c
+++ b/src/libopensc/pkcs15-gemsafeGPK.c
@@ -205,7 +205,7 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card)
u8 sysrec[7];
int num_keyinfo = 0;
- keyinfo kinfo[8]; /* will loook for 8 keys */
+ keyinfo kinfo[9]; /* will look for 9 keys */
u8 modulus_buf[ 1 + 1024 / 8]; /* tag+modulus */
u8 *cp;
char buf[256];
@@ -255,9 +255,9 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card)
/* There may be more then one key in the directory. */
/* we need to find them so we can associate them with the */
- /* the certificate. The files are 0007 to 000f */
+ /* the certificate. The files are 0007 to 000F */
- for (i = 7; i < 16; i++) {
+ for (i = 0x7; i <= 0xF; i++) {
path.value[0] = 0x00;
path.value[1] = i;
path.len = 2;
@@ -297,7 +297,7 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card)
while (j--)
*cp++ = modulus_buf[j + 1];
num_keyinfo++;
- }
+ }
/* Get the gemsafe data with the cert */
sc_format_path("3F000200004", &path);

View File

@ -0,0 +1,21 @@
commit 9d294de90d1cc66956389856e60b6944b27b4817
Author: Frank Morgner <frankmorgner@gmail.com>
Date: Thu Jun 4 10:04:10 2020 +0200
prevent out of bounds write
fixes https://oss-fuzz.com/testcase-detail/5226571123392512
diff --git a/src/libopensc/card-tcos.c b/src/libopensc/card-tcos.c
index 673c2493..e88c80bd 100644
--- a/src/libopensc/card-tcos.c
+++ b/src/libopensc/card-tcos.c
@@ -623,6 +623,8 @@ static int tcos_decipher(sc_card_t *card, const u8 * crgram, size_t crgram_len,
apdu.data = sbuf;
apdu.lc = apdu.datalen = crgram_len+1;
sbuf[0] = tcos3 ? 0x00 : ((data->pad_flags & SC_ALGORITHM_RSA_PAD_PKCS1) ? 0x81 : 0x02);
+ if (sizeof sbuf - 1 < crgram_len)
+ return SC_ERROR_INVALID_ARGUMENTS;
memcpy(sbuf+1, crgram, crgram_len);
r = sc_transmit_apdu(card, &apdu);

View File

@ -0,0 +1,102 @@
diff --git a/src/libopensc/card-cac.c b/src/libopensc/card-cac.c
index 099923e5..61e69c88 100644
--- a/src/libopensc/card-cac.c
+++ b/src/libopensc/card-cac.c
@@ -1793,7 +1793,7 @@ static int cac_find_and_initialize(sc_card_t *card, int initialize)
}
r = cac_process_ACA(card, priv);
if (r == SC_SUCCESS) {
- card->type = SC_CARD_TYPE_CAC_II;
+ card->type = SC_CARD_TYPE_CAC_ALT_HID;
card->drv_data = priv;
return r;
}
@@ -1869,6 +1869,8 @@ static int cac_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries
* FIPS 201 4.1.6.1 (numeric only) and * FIPS 140-2
* (6 character minimum) requirements.
*/
+ sc_apdu_t apdu;
+ u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
if (data->cmd == SC_PIN_CMD_CHANGE) {
@@ -1881,6 +1883,18 @@ static int cac_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries
return SC_ERROR_INVALID_DATA;
}
}
+
+ /* We can change the PIN of Giesecke & Devrient CAC ALT tokens
+ * with a bit non-standard APDU */
+ if (card->type == SC_CARD_TYPE_CAC_ALT_HID) {
+ int r = 0;
+ r = iso7816_build_pin_apdu(card, &apdu, data, sbuf, sizeof(sbuf));
+ if (r < 0)
+ return r;
+ /* it requires P1 = 0x01 completely against the ISO specs */
+ apdu.p1 = 0x01;
+ data->apdu = &apdu;
+ }
}
return iso_drv->ops->pin_cmd(card, data, tries_left);
diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h
index 0ec25a46..16846d15 100644
--- a/src/libopensc/cards.h
+++ b/src/libopensc/cards.h
@@ -244,6 +244,7 @@ enum {
SC_CARD_TYPE_CAC_GENERIC,
SC_CARD_TYPE_CAC_I,
SC_CARD_TYPE_CAC_II,
+ SC_CARD_TYPE_CAC_ALT_HID,
/* nPA cards */
SC_CARD_TYPE_NPA = 34000,
diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c
index b1a0e88f..d41613b2 100644
--- a/src/libopensc/iso7816.c
+++ b/src/libopensc/iso7816.c
@@ -1017,7 +1017,7 @@ iso7816_decipher(struct sc_card *card,
}
-static int
+int
iso7816_build_pin_apdu(struct sc_card *card, struct sc_apdu *apdu,
struct sc_pin_cmd_data *data, u8 *buf, size_t buf_len)
{
diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h
index b519c5d5..8ebf9fbd 100644
--- a/src/libopensc/opensc.h
+++ b/src/libopensc/opensc.h
@@ -1664,6 +1664,19 @@ int iso7816_update_binary_sfid(sc_card_t *card, unsigned char sfid,
* */
int iso7816_logout(sc_card_t *card, unsigned char pin_reference);
+/*
+ * @brief Format PIN APDU for modifiction by card driver
+ *
+ * @param[in] card card
+ * @param[in] apdu apdu structure to update with PIN APDU
+ * @param[in] data pin command data to set into the APDU
+ * @param[in] buf buffer for APDU data field
+ * @param[in] buf_len maximum buffer length
+ */
+int
+iso7816_build_pin_apdu(struct sc_card *card, struct sc_apdu *apdu,
+ struct sc_pin_cmd_data *data, u8 *buf, size_t buf_len);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/libopensc/pkcs15-cac.c b/src/libopensc/pkcs15-cac.c
index ccb27994..05056ea9 100644
--- a/src/libopensc/pkcs15-cac.c
+++ b/src/libopensc/pkcs15-cac.c
@@ -79,6 +79,7 @@ static const char * cac_get_name(int type)
switch (type) {
case SC_CARD_TYPE_CAC_I: return ("CAC I");
case SC_CARD_TYPE_CAC_II: return ("CAC II");
+ case SC_CARD_TYPE_CAC_ALT_HID: return ("CAC ALT HID");
default: break;
}
return ("CAC");

View File

@ -0,0 +1,102 @@
From f1bcadfbe9d156adbe509b0860511ee41add0c67 Mon Sep 17 00:00:00 2001
From: Frank Morgner <frankmorgner@gmail.com>
Date: Tue, 10 Mar 2020 12:13:29 +0100
Subject: [PATCH] pkcs11: don't try to allocate 0 byte with calloc
fixes #1978
---
src/pkcs11/pkcs11-global.c | 7 ++++++-
win32/Make.rules.mak | 4 ++--
win32/winconfig.h.in | 2 ++
3 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c
index a3260314f8..671890309f 100644
--- a/src/pkcs11/pkcs11-global.c
+++ b/src/pkcs11/pkcs11-global.c
@@ -456,6 +456,13 @@ CK_RV C_GetSlotList(CK_BBOOL tokenPresent, /* only slots with token prese
card_detect_all();
+ if (list_empty(&virtual_slots)) {
+ sc_log(context, "returned 0 slots\n");
+ *pulCount = 0;
+ rv = CKR_OK;
+ goto out;
+ }
+
found = calloc(list_size(&virtual_slots), sizeof(CK_SLOT_ID));
if (found == NULL) {
diff --git a/win32/Make.rules.mak b/win32/Make.rules.mak
index 4f4971a72d..c6b1aac340 100644
--- a/win32/Make.rules.mak
+++ b/win32/Make.rules.mak
@@ -1,7 +1,7 @@
OPENSC_FEATURES = pcsc
#Include support for minidriver
-MINIDRIVER_DEF = /DENABLE_MINIDRIVER
+#MINIDRIVER_DEF = /DENABLE_MINIDRIVER
#Build MSI with the Windows Installer XML (WIX) toolkit, requires WIX >= 3.9
!IF "$(WIX)" == ""
@@ -33,7 +33,7 @@ WIX_LIBS = "$(WIX)\SDK\$(WIXVSVER)\lib\$(PLATFORM)\dutil.lib" "$(WIX)\SDK\$(WIXV
SM_DEF = /DENABLE_SM
#Build with debugging support
-#DEBUG_DEF = /DDEBUG
+DEBUG_DEF = /DDEBUG
# If you want support for OpenSSL (needed for pkcs15-init tool, software hashing in PKCS#11 library and verification):
# - download and build OpenSSL
diff --git a/win32/winconfig.h.in b/win32/winconfig.h.in
index 94ed9b5475..fa682c5bcc 100644
--- a/win32/winconfig.h.in
+++ b/win32/winconfig.h.in
@@ -103,6 +103,8 @@
#define DEFAULT_ONEPIN_PKCS11_PROVIDER "@DEFAULT_ONEPIN_PKCS11_PROVIDER@"
#endif
+#define PKCS11_THREAD_LOCKING
+
#ifndef DEFAULT_SM_MODULE
#define DEFAULT_SM_MODULE "@DEFAULT_SM_MODULE@"
#endif
commit 500ecd3d127975379e2310626c3ce94c3e7035ea
Author: Jakub Jelen <jjelen@redhat.com>
Date: Wed Nov 25 13:49:08 2020 +0100
pkcs11-tool: Avoid calloc with 0 argument
diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c
index 4015aaf1..89244795 100644
--- a/src/tools/pkcs11-tool.c
+++ b/src/tools/pkcs11-tool.c
@@ -1270,15 +1270,18 @@ static void list_slots(int tokens, int refresh, int print)
if (rv != CKR_OK)
p11_fatal("C_GetSlotList(NULL)", rv);
free(p11_slots);
- p11_slots = calloc(p11_num_slots, sizeof(CK_SLOT_ID));
- if (p11_slots == NULL) {
- perror("calloc failed");
- exit(1);
+ p11_slots = NULL;
+ if (p11_num_slots > 0) {
+ p11_slots = calloc(p11_num_slots, sizeof(CK_SLOT_ID));
+ if (p11_slots == NULL) {
+ perror("calloc failed");
+ exit(1);
+ }
+ rv = p11->C_GetSlotList(tokens, p11_slots, &p11_num_slots);
+ if (rv != CKR_OK)
+ p11_fatal("C_GetSlotList()", rv);
}
- rv = p11->C_GetSlotList(tokens, p11_slots, &p11_num_slots);
- if (rv != CKR_OK)
- p11_fatal("C_GetSlotList()", rv);
}
if (!print)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,85 @@
From 2a28dcd3f6e4af7a5b2d7d7810b26b6321dd1bf1 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Tue, 10 Nov 2020 14:44:43 +0100
Subject: [PATCH 1/3] ctx: Use more standard cache directory
https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
---
src/libopensc/ctx.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c
index 6b57170f01..d6058c070e 100644
--- a/src/libopensc/ctx.c
+++ b/src/libopensc/ctx.c
@@ -1008,7 +1008,12 @@ int sc_get_cache_dir(sc_context_t *ctx, char *buf, size_t bufsize)
}
#ifndef _WIN32
- cache_dir = ".eid/cache";
+ cache_dir = getenv("XDG_CACHE_HOME");
+ if (cache_dir != NULL && cache_dir[0] != '\0') {
+ snprintf(buf, bufsize, "%s/%s", cache_dir, "opensc");
+ return SC_SUCCESS;
+ }
+ cache_dir = ".cache/opensc";
homedir = getenv("HOME");
#else
cache_dir = "eid-cache";
@@ -1020,7 +1025,7 @@ int sc_get_cache_dir(sc_context_t *ctx, char *buf, size_t bufsize)
homedir = temp_path;
}
#endif
- if (homedir == NULL)
+ if (homedir == NULL || homedir[0] == '\0')
return SC_ERROR_INTERNAL;
if (snprintf(buf, bufsize, "%s/%s", homedir, cache_dir) < 0)
return SC_ERROR_BUFFER_TOO_SMALL;
From 7c1c6f6be47f55693647827259edcacc98761371 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Tue, 10 Nov 2020 15:07:42 +0100
Subject: [PATCH 3/3] doc: Update documentation about the cache location
---
doc/files/opensc.conf.5.xml.in | 9 +++++++--
2 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in
index 118922a877..791f11669a 100644
--- a/doc/files/opensc.conf.5.xml.in
+++ b/doc/files/opensc.conf.5.xml.in
@@ -1116,12 +1116,17 @@ app <replaceable>application</replaceable> {
<itemizedlist>
<listitem>
<para>
- <filename><envar>HOME</envar>/.eid/cache/</filename> (Unix)
+ <filename><envar>$XDG_CACHE_HOME</envar>/opensc/</filename> (If <envar>$XDG_CACHE_HOME</envar> is defined)
</para>
</listitem>
<listitem>
<para>
- <filename><envar>USERPROFILE</envar>\.eid-cache\</filename> (Windows)
+ <filename><envar>$HOME</envar>/.cache/opensc/</filename> (Unix)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <filename><envar>$USERPROFILE</envar>\.eid-cache\</filename> (Windows)
</para>
</listitem>
</itemizedlist>
diff -up opensc-0.20.0/etc/opensc.conf.file-cache opensc-0.20.0/etc/opensc.conf
--- opensc-0.20.0/etc/opensc.conf.file-cache 2020-11-20 16:49:30.995526825 +0100
+++ opensc-0.20.0/etc/opensc.conf 2020-11-20 16:50:07.665053280 +0100
@@ -2,7 +2,7 @@ app default {
# debug = 3;
# debug_file = opensc-debug.txt;
framework pkcs15 {
- # use_file_caching = true;
+ use_file_caching = true;
}
reader_driver pcsc {
# The pinpad is disabled by default,

View File

@ -0,0 +1,25 @@
From 34dad7f543f006ad269ce1f935a9e8d3e3a83db7 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Mon, 3 Feb 2020 16:40:51 +0100
Subject: [PATCH] idprime: Add missing terminator in ATR list
Thanks oss-fuzz
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=20510
---
src/libopensc/card-idprime.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c
index 744d5189b9..9f5adde9d2 100644
--- a/src/libopensc/card-idprime.c
+++ b/src/libopensc/card-idprime.c
@@ -52,6 +52,7 @@ static const struct sc_atr_table idprime_atrs[] = {
"ff:ff:00:ff:ff:ff:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:ff",
"Gemalto IDPrime MD 8840, 3840, 3810, 840 and 830 Cards",
SC_CARD_TYPE_IDPRIME_GENERIC, 0, NULL },
+ { NULL, NULL, NULL, 0, 0, NULL }
};
static const sc_path_t idprime_path = {

View File

@ -0,0 +1,24 @@
commit 8d4af9eb0b799f22b25783e8e1b7af329b5a917b
Author: Frank Morgner <frankmorgner@gmail.com>
Date: Fri Jan 31 12:15:53 2020 +0100
pkcs11: fixed right padding of token label with ' '
fixes https://github.com/OpenSC/OpenSC/issues/1922
diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c
index e94eeeff..a1951c2e 100644
--- a/src/pkcs11/framework-pkcs15.c
+++ b/src/pkcs11/framework-pkcs15.c
@@ -1122,9 +1122,10 @@ pkcs15_init_slot(struct sc_pkcs15_card *p15card, struct sc_pkcs11_slot *slot,
max_tokeninfo_len);
slot->token_info.label[max_tokeninfo_len] = ' ';
slot->token_info.label[max_tokeninfo_len+1] = '(';
- slot->token_info.label[max_tokeninfo_len+2+pin_len] = ')';
strcpy_bp(slot->token_info.label+max_tokeninfo_len+2,
auth->label, pin_len);
+ strcpy_bp(slot->token_info.label+max_tokeninfo_len+2+pin_len,
+ ")", 32 - max_tokeninfo_len-2-pin_len);
}
} else {
/* PIN label is empty or just says non-useful "PIN",

File diff suppressed because it is too large Load Diff

View File

@ -1,23 +0,0 @@
diff -up opensc-0.22.0/etc/opensc.conf.file-cache opensc-0.22.0/etc/opensc.conf
--- opensc-0.22.0/etc/opensc.conf.file-cache 2021-10-08 13:14:44.091772071 +0200
+++ opensc-0.22.0/etc/opensc.conf 2021-10-08 13:19:27.339051951 +0200
@@ -2,7 +2,7 @@ app default {
# debug = 3;
# debug_file = opensc-debug.txt;
framework pkcs15 {
- # use_file_caching = public;
+ use_file_caching = public;
}
reader_driver pcsc {
# The pinpad is disabled by default,
@@ -10,3 +10,10 @@ app default {
enable_pinpad = false;
}
}
+# the pkcs15-init is used for card initialization when the file caching
+# brings more trouble than use so disable that:
+app pkcs15-init {
+ framework pkcs15 {
+ use_file_caching = no;
+ }
+}

View File

@ -0,0 +1,96 @@
From bff98ff078a99e6864ba1a598fd7dc9af4a9476b Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Thu, 7 Sep 2023 13:23:04 +0200
Subject: [PATCH] cache: Honor the file offset when writing cache
When the reads are not consecutive, avoid caching anything after the gaps.
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
---
src/libopensc/pkcs15-cache.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/src/libopensc/pkcs15-cache.c b/src/libopensc/pkcs15-cache.c
index 6ebe35a8af..61af35fc5a 100644
--- a/src/libopensc/pkcs15-cache.c
+++ b/src/libopensc/pkcs15-cache.c
@@ -195,6 +195,7 @@ int sc_pkcs15_cache_file(struct sc_pkcs15_card *p15card,
{
char fname[PATH_MAX];
int r;
+ long len;
FILE *f;
size_t c;
@@ -202,22 +203,33 @@ int sc_pkcs15_cache_file(struct sc_pkcs15_card *p15card,
if (r != 0)
return r;
- f = fopen(fname, "wb");
+ f = fopen(fname, "ab");
/* If the open failed because the cache directory does
* not exist, create it and a re-try the fopen() call.
*/
if (f == NULL && errno == ENOENT) {
if ((r = sc_make_cache_dir(p15card->card->ctx)) < 0)
return r;
- f = fopen(fname, "wb");
+ f = fopen(fname, "ab");
}
if (f == NULL)
return 0;
+ /* we opened the file for appending so we should be at the end of file.
+ * The ftell() will give use the length of the file */
+ len = ftell(f);
+ if (len > path->index) {
+ /* override previous cache records on this location */
+ fseek(f, path->index, SEEK_SET);
+ } else if (path->index > len) {
+ /* We miss some bytes so we will not cache this chunk */
+ return 0;
+ }
+
c = fwrite(buf, 1, bufsize, f);
fclose(f);
if (c != bufsize) {
- sc_log(p15card->card->ctx,
+ sc_log(p15card->card->ctx,
"fwrite() wrote only %"SC_FORMAT_LEN_SIZE_T"u bytes",
c);
unlink(fname);
From 0875c69295ef28b45fb682b37cede58fc36b7a1a Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Fri, 15 Sep 2023 19:17:53 +0200
Subject: [PATCH] pkcs15-cache: Avoid fd leaks and check return values
CID 401725
CID 401726
Thanks coverity
---
src/libopensc/pkcs15-cache.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/libopensc/pkcs15-cache.c b/src/libopensc/pkcs15-cache.c
index 61af35fc5a..bae5797fe2 100644
--- a/src/libopensc/pkcs15-cache.c
+++ b/src/libopensc/pkcs15-cache.c
@@ -220,9 +220,14 @@ int sc_pkcs15_cache_file(struct sc_pkcs15_card *p15card,
len = ftell(f);
if (len > path->index) {
/* override previous cache records on this location */
- fseek(f, path->index, SEEK_SET);
+ r = fseek(f, path->index, SEEK_SET);
+ if (r != 0) {
+ fclose(f);
+ return 0;
+ }
} else if (path->index > len) {
/* We miss some bytes so we will not cache this chunk */
+ fclose(f);
return 0;
}

View File

@ -0,0 +1,485 @@
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index 5153428dc..9ecbffe8f 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='' -header-filter=.* $(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 74014235a..13eccfa1a 100644
--- a/src/libopensc/internal.h
+++ b/src/libopensc/internal.h
@@ -168,6 +168,8 @@ int sc_pkcs1_strip_01_padding(struct sc_context *ctx, const u8 *in_dat, size_t i
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);
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"
/* 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);
}
/* add/remove DigestInfo prefix */
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
@@ -286,12 +286,14 @@ 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 */
}
- 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>
@@ -4174,7 +4175,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;
sc_log(context, "Initiating decryption.");
@@ -4246,27 +4248,54 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_se
rv = sc_pkcs15_decipher(fw_data->p15_card, prkey->prv_p15obj, flags,
pEncryptedData, ulEncryptedDataLen, decrypted, sizeof(decrypted));
- 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));
sc_unlock(p11card->card);
- sc_log(context, "Decryption complete. Result %d.", rv);
+ sc_log(context, "Decryption complete.");
- if (rv < 0)
+ /* Handle following code in constant-time
return sc_to_cryptoki_error(rv, "C_Decrypt");
+ * 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);
-
- return CKR_OK;
+ /* 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");
+
+ /* 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;
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
@@ -926,7 +926,8 @@ CK_RV C_Decrypt(CK_SESSION_HANDLE hSessi
rv = reset_login_state(session->slot, rv);
}
- sc_log(context, "C_Decrypt() = %s", lookup_enum ( RV_T, rv ));
+ /* do not log error code to prevent side channel attack */
+ sc_log(context, "C_Decrypt() finished");
sc_pkcs11_unlock();
return rv;
}
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);
}

View File

@ -1,225 +0,0 @@
From 3b580b6fff9ac463ecc6e996cfaf573f62749368 Mon Sep 17 00:00:00 2001
From: Frank Morgner <frankmorgner@gmail.com>
Date: Fri, 14 Apr 2023 12:02:54 +0200
Subject: [PATCH 1/2] openpgp: identify OpenPGP compliance with bcd_version
rather than card type
---
src/libopensc/card-openpgp.c | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c
index fad32f0ce7..2ea5dc9d36 100644
--- a/src/libopensc/card-openpgp.c
+++ b/src/libopensc/card-openpgp.c
@@ -1780,13 +1780,18 @@ pgp_get_pubkey_pem(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len)
* p1: number of an instance (DO 7F21: 0x00 for AUT, 0x01 for DEC and 0x02 for SIG)
*/
static int
-pgp_select_data(sc_card_t *card, u8 p1){
+pgp_select_data(sc_card_t *card, u8 p1)
+{
sc_apdu_t apdu;
u8 apdu_data[6];
int r;
+ struct pgp_priv_data *priv = DRVDATA(card);
LOG_FUNC_CALLED(card->ctx);
+ if (priv->bcd_version < OPENPGP_CARD_3_0)
+ LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
+
sc_log(card->ctx, "select data with: %u", p1);
// create apdu data (taken from spec: SELECT DATA 7.2.5.)
@@ -2179,8 +2184,7 @@ pgp_set_security_env(sc_card_t *card,
/* The SC_SEC_ENV_ALG_PRESENT is set always so let it pass for GNUK */
if ((env->flags & SC_SEC_ENV_ALG_PRESENT)
&& (env->algorithm != SC_ALGORITHM_RSA)
- && (priv->bcd_version < OPENPGP_CARD_3_0)
- && (card->type != SC_CARD_TYPE_OPENPGP_GNUK))
+ && (priv->bcd_version < OPENPGP_CARD_3_0))
LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS,
"only RSA algorithm supported");
@@ -2944,13 +2948,13 @@ pgp_update_card_algorithms(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *ke
{
sc_algorithm_info_t *algo;
u8 id = key_info->key_id;
+ struct pgp_priv_data *priv = DRVDATA(card);
LOG_FUNC_CALLED(card->ctx);
/* protect incompatible cards against non-RSA */
if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA
- && card->type < SC_CARD_TYPE_OPENPGP_V3
- && card->type != SC_CARD_TYPE_OPENPGP_GNUK)
+ && priv->bcd_version < OPENPGP_CARD_3_0)
LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
if (id > card->algorithm_count) {
@@ -2992,13 +2996,13 @@ pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info)
size_t apdu_le;
size_t resplen = 0;
int r = SC_SUCCESS;
+ struct pgp_priv_data *priv = DRVDATA(card);
LOG_FUNC_CALLED(card->ctx);
/* protect incompatible cards against non-RSA */
if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA
- && card->type < SC_CARD_TYPE_OPENPGP_V3
- && card->type != SC_CARD_TYPE_OPENPGP_GNUK)
+ && priv->bcd_version < OPENPGP_CARD_3_0)
LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
if (key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA
&& card->type != SC_CARD_TYPE_OPENPGP_GNUK)
@@ -3358,13 +3362,13 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info)
u8 *data = NULL;
size_t len = 0;
int r;
+ struct pgp_priv_data *priv = DRVDATA(card);
LOG_FUNC_CALLED(card->ctx);
/* protect incompatible cards against non-RSA */
if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA
- && card->type < SC_CARD_TYPE_OPENPGP_V3
- && card->type != SC_CARD_TYPE_OPENPGP_GNUK)
+ && priv->bcd_version < OPENPGP_CARD_3_0)
LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
/* Validate */
From 9eccc1494d8303ffe42beb772732df218875e3ac Mon Sep 17 00:00:00 2001
From: Frank Morgner <frankmorgner@gmail.com>
Date: Fri, 14 Apr 2023 12:09:55 +0200
Subject: [PATCH 2/2] openpgp: ignore errors on SELECT DATA for OpenPGP 2 and
below
fixes https://github.com/OpenSC/OpenSC/issues/2752
---
src/libopensc/pkcs15-openpgp.c | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/src/libopensc/pkcs15-openpgp.c b/src/libopensc/pkcs15-openpgp.c
index e2f3442238..9d3fd746a0 100644
--- a/src/libopensc/pkcs15-openpgp.c
+++ b/src/libopensc/pkcs15-openpgp.c
@@ -556,14 +556,9 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card)
memset(&cert_info, 0, sizeof(cert_info));
memset(&cert_obj, 0, sizeof(cert_obj));
- /* only try to SELECT DATA for OpenPGP >= v3 */
- if (card->type >= SC_CARD_TYPE_OPENPGP_V3) {
- r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_SELECT_DATA, &i);
- if (r < 0) {
- free(buffer);
- LOG_TEST_RET(card->ctx, r, "Failed OpenPGP - select data");
- }
- }
+ /* try to SELECT DATA. Will only work for OpenPGP >= v3, errors are non-critical */
+ sc_card_ctl(card, SC_CARDCTL_OPENPGP_SELECT_DATA, &i);
+
sc_format_path(certs[i].path, &cert_info.path);
/* Certificate ID. We use the same ID as the authentication key */
commit e8fba322a2f4d06ec5c74fe80f9e2b0e9fdefec6
Author: Jakub Jelen <jjelen@redhat.com>
Date: Fri May 19 16:49:00 2023 +0200
openpgp: Fix fingerprint calculation
fixes https://github.com/OpenSC/OpenSC/issues/2775
diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c
index cc454cef..496e38e6 100644
--- a/src/libopensc/card-openpgp.c
+++ b/src/libopensc/card-openpgp.c
@@ -2697,15 +2697,23 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime,
/* RSA */
if (key_info->algorithm == SC_OPENPGP_KEYALGO_RSA) {
+ unsigned short bytes_length = 0;
+
*p = 1; /* Algorithm ID, RSA */
p += 1;
+
+ /* Modulus */
+ bytes_length = BYTES4BITS(key_info->u.rsa.modulus_len);
ushort2bebytes(p, (unsigned short)key_info->u.rsa.modulus_len);
p += 2;
- memcpy(p, key_info->u.rsa.modulus, (BYTES4BITS(key_info->u.rsa.modulus_len)));
- p += (key_info->u.rsa.modulus_len >> 3);
- ushort2bebytes(++p, (unsigned short)key_info->u.rsa.exponent_len);
+ memcpy(p, key_info->u.rsa.modulus, bytes_length);
+ p += bytes_length;
+
+ /* Exponent */
+ bytes_length = BYTES4BITS(key_info->u.rsa.exponent_len);
+ ushort2bebytes(p, (unsigned short)key_info->u.rsa.exponent_len);
p += 2;
- memcpy(p, key_info->u.rsa.exponent, (BYTES4BITS(key_info->u.rsa.exponent_len)));
+ memcpy(p, key_info->u.rsa.exponent, bytes_length);
}
/* ECC */
else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH
commit 891f10e49de1a5ee038b1cb2fb59dce40429e6c2
Author: Jakub Jelen <jjelen@redhat.com>
Date: Fri May 19 17:53:35 2023 +0200
openpgp: Fix modulus length calculation in pkc15init layer
diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h
index 5a0a19c5..ba685a30 100644
--- a/src/libopensc/pkcs15.h
+++ b/src/libopensc/pkcs15.h
@@ -373,7 +373,7 @@ struct sc_pkcs15_prkey_info {
unsigned int usage, access_flags;
int native, key_reference;
/* convert to union if other types are supported */
- size_t modulus_length; /* RSA */
+ size_t modulus_length; /* RSA, in bits */
size_t field_length; /* EC in bits */
unsigned int algo_refs[SC_MAX_SUPPORTED_ALGORITHMS];
diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c
index c75bcbda..3e060be5 100644
--- a/src/pkcs15init/pkcs15-openpgp.c
+++ b/src/pkcs15init/pkcs15-openpgp.c
@@ -235,7 +235,7 @@ static int openpgp_generate_key_rsa(sc_card_t *card, sc_pkcs15_object_t *obj,
/* Prepare buffer */
key_info.u.rsa.modulus_len = required->modulus_length;
- key_info.u.rsa.modulus = calloc(required->modulus_length >> 3, 1);
+ key_info.u.rsa.modulus = calloc(BYTES4BITS(required->modulus_length), 1);
if (key_info.u.rsa.modulus == NULL)
LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_ENOUGH_MEMORY);
@@ -252,18 +252,18 @@ static int openpgp_generate_key_rsa(sc_card_t *card, sc_pkcs15_object_t *obj,
pubkey->algorithm = SC_ALGORITHM_RSA;
sc_log(ctx, "Set output modulus info");
- pubkey->u.rsa.modulus.len = key_info.u.rsa.modulus_len;
- pubkey->u.rsa.modulus.data = calloc(key_info.u.rsa.modulus_len, 1);
+ pubkey->u.rsa.modulus.len = BYTES4BITS(key_info.u.rsa.modulus_len);
+ pubkey->u.rsa.modulus.data = calloc(pubkey->u.rsa.modulus.len, 1);
if (pubkey->u.rsa.modulus.data == NULL)
goto err;
- memcpy(pubkey->u.rsa.modulus.data, key_info.u.rsa.modulus, key_info.u.rsa.modulus_len);
+ memcpy(pubkey->u.rsa.modulus.data, key_info.u.rsa.modulus, BYTES4BITS(key_info.u.rsa.modulus_len));
sc_log(ctx, "Set output exponent info");
- pubkey->u.rsa.exponent.len = key_info.u.rsa.exponent_len;
- pubkey->u.rsa.exponent.data = calloc(BYTES4BITS(key_info.u.rsa.exponent_len), 1);
+ pubkey->u.rsa.exponent.len = BYTES4BITS(key_info.u.rsa.exponent_len);
+ pubkey->u.rsa.exponent.data = calloc(pubkey->u.rsa.exponent.len, 1);
if (pubkey->u.rsa.exponent.data == NULL)
goto err;
- memcpy(pubkey->u.rsa.exponent.data, key_info.u.rsa.exponent, BYTES4BITS(key_info.u.rsa.exponent_len));
+ memcpy(pubkey->u.rsa.exponent.data, key_info.u.rsa.exponent, pubkey->u.rsa.exponent.len);
err:
free(key_info.u.rsa.modulus);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,107 @@
From 868f76fb31255fd3fdacfc3e476452efeb61c3e7 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 80a185fecd..393234efe4 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)
From 80cc5d30635f0d2c92b5099c0f9dc680d0ffce2f Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Tue, 24 Oct 2023 11:13:08 +0200
Subject: [PATCH] pkcs15init: Check login status before asking for a pin
The original code block from e6f7373 is still needed when pkcs15init
layer checks ACLs for PKCS#15 objects, but it should be kept out of
the libopensc, which is used for more authentication code paths
and can be used for PIN bypass.
---
src/libopensc/pkcs15-pin.c | 1 +
src/pkcs15init/pkcs15-lib.c | 16 ++++++++++++++++
2 files changed, 17 insertions(+)
diff --git a/src/libopensc/pkcs15-pin.c b/src/libopensc/pkcs15-pin.c
index 393234efe..b26e57236 100644
--- a/src/libopensc/pkcs15-pin.c
+++ b/src/libopensc/pkcs15-pin.c
@@ -307,6 +307,7 @@ 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;
+ /* Check the provided pin matches pin requirements */
r = _validate_pin(p15card, auth_info, pinlen);
if (r)
diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c
index 9148b83b5..cca11d1f1 100644
--- a/src/pkcs15init/pkcs15-lib.c
+++ b/src/pkcs15init/pkcs15-lib.c
@@ -3958,6 +3958,22 @@ sc_pkcs15init_verify_secret(struct sc_profile *profile, struct sc_pkcs15_card *p
found:
if (pin_obj) {
+ /*
+ * If pin cache is disabled or the reader is using pinpad, we can get here
+ * with no PIN data. This is ok as we can not asynchronously invoke the prompt
+ * (unless the pinpad is in use).
+ * In this case, check if the PIN has been already verified and
+ * the access condition is still open on card.
+ */
+ if (pinsize == 0) {
+ r = sc_pkcs15_get_pin_info(p15card, pin_obj);
+ /* update local copy of auth info */
+ memcpy(&auth_info, pin_obj->data, sizeof(auth_info));
+
+ if (r == SC_SUCCESS && auth_info.logged_in == SC_PIN_STATE_LOGGED_IN)
+ LOG_FUNC_RETURN(ctx, r);
+ }
+
r = sc_pkcs15_verify_pin(p15card, pin_obj, use_pinpad || pinsize == 0 ? NULL : pinbuf, use_pinpad ? 0 : pinsize);
LOG_TEST_RET(ctx, r, "Cannot validate pkcs15 PIN");
}
--
2.43.0

View File

@ -1,212 +0,0 @@
From 99f7b82f187ca3512ceae6270c391243d018fdac Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Thu, 1 Dec 2022 20:08:53 +0100
Subject: [PATCH 1/4] pkcs11-tool: Fix private key import
---
src/tools/pkcs11-tool.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c
index aae205fe2c..cfee8526d5 100644
--- a/src/tools/pkcs11-tool.c
+++ b/src/tools/pkcs11-tool.c
@@ -3669,13 +3669,13 @@ parse_rsa_pkey(EVP_PKEY *pkey, int private, struct rsakey_info *rsa)
RSA_get0_factors(r, &r_p, &r_q);
RSA_get0_crt_params(r, &r_dmp1, &r_dmq1, &r_iqmp);
#else
- if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR1, &r_d) != 1 ||
+ if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_D, &r_d) != 1 ||
EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR1, &r_p) != 1 ||
EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR2, &r_q) != 1 ||
EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT1, &r_dmp1) != 1 ||
EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT2, &r_dmq1) != 1 ||
- EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT3, &r_iqmp) != 1) {
util_fatal("OpenSSL error during RSA private key parsing");
+ EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_COEFFICIENT1, &r_iqmp) != 1) {
}
#endif
RSA_GET_BN(rsa, private_exponent, r_d);
From 4a6e1d1dcd18757502027b1c5d2fb2cbaca28407 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Thu, 1 Dec 2022 20:11:41 +0100
Subject: [PATCH 2/4] pkcs11-tool: Log more information on OpenSSL errors
---
src/tools/pkcs11-tool.c | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c
index cfee8526d5..f2e6b1dd91 100644
--- a/src/tools/pkcs11-tool.c
+++ b/src/tools/pkcs11-tool.c
@@ -3641,10 +3641,8 @@ parse_rsa_pkey(EVP_PKEY *pkey, int private, struct rsakey_info *rsa)
const BIGNUM *r_dmp1, *r_dmq1, *r_iqmp;
r = EVP_PKEY_get1_RSA(pkey);
if (!r) {
- if (private)
- util_fatal("OpenSSL error during RSA private key parsing");
- else
- util_fatal("OpenSSL error during RSA public key parsing");
+ util_fatal("OpenSSL error during RSA %s key parsing: %s", private ? "private" : "public",
+ ERR_error_string(ERR_peek_last_error(), NULL));
}
RSA_get0_key(r, &r_n, &r_e, NULL);
@@ -3654,10 +3652,8 @@ parse_rsa_pkey(EVP_PKEY *pkey, int private, struct rsakey_info *rsa)
BIGNUM *r_dmp1 = NULL, *r_dmq1 = NULL, *r_iqmp = NULL;
if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_N, &r_n) != 1 ||
EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_E, &r_e) != 1) {
- if (private)
- util_fatal("OpenSSL error during RSA private key parsing");
- else
- util_fatal("OpenSSL error during RSA public key parsing");
+ util_fatal("OpenSSL error during RSA %s key parsing: %s", private ? "private" : "public",
+ ERR_error_string(ERR_peek_last_error(), NULL));
}
#endif
RSA_GET_BN(rsa, modulus, r_n);
@@ -3674,8 +3670,9 @@ parse_rsa_pkey(EVP_PKEY *pkey, int private, struct rsakey_info *rsa)
EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR2, &r_q) != 1 ||
EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT1, &r_dmp1) != 1 ||
EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT2, &r_dmq1) != 1 ||
- util_fatal("OpenSSL error during RSA private key parsing");
EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_COEFFICIENT1, &r_iqmp) != 1) {
+ util_fatal("OpenSSL error during RSA private key parsing: %s",
+ ERR_error_string(ERR_peek_last_error(), NULL));
}
#endif
RSA_GET_BN(rsa, private_exponent, r_d);
From 267da3e81f1fc23a9ccce1462ab5deb1a4d4aec5 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Thu, 1 Dec 2022 20:38:31 +0100
Subject: [PATCH 3/4] Reproducer for broken pkcs11-tool key import
---
tests/Makefile.am | 10 ++++---
tests/test-pkcs11-tool-import.sh | 48 ++++++++++++++++++++++++++++++++
2 files changed, 54 insertions(+), 4 deletions(-)
create mode 100755 tests/test-pkcs11-tool-import.sh
diff --git a/tests/Makefile.am b/tests/Makefile.am
index d378e2ee00..9d8a24c321 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -14,8 +14,9 @@ dist_noinst_SCRIPTS = common.sh \
test-pkcs11-tool-test-threads.sh \
test-pkcs11-tool-sign-verify.sh \
test-pkcs11-tool-allowed-mechanisms.sh \
- test-pkcs11-tool-sym-crypt-test.sh\
- test-pkcs11-tool-unwrap-wrap-test.sh
+ test-pkcs11-tool-sym-crypt-test.sh \
+ test-pkcs11-tool-unwrap-wrap-test.sh \
+ test-pkcs11-tool-import.sh
.NOTPARALLEL:
TESTS = \
@@ -25,8 +26,9 @@ TESTS = \
test-pkcs11-tool-test.sh \
test-pkcs11-tool-test-threads.sh \
test-pkcs11-tool-allowed-mechanisms.sh \
- test-pkcs11-tool-sym-crypt-test.sh\
- test-pkcs11-tool-unwrap-wrap-test.sh
+ test-pkcs11-tool-sym-crypt-test.sh \
+ test-pkcs11-tool-unwrap-wrap-test.sh \
+ test-pkcs11-tool-import.sh
XFAIL_TESTS = \
test-pkcs11-tool-test-threads.sh \
test-pkcs11-tool-test.sh
diff --git a/tests/test-pkcs11-tool-import.sh b/tests/test-pkcs11-tool-import.sh
new file mode 100755
index 0000000000..76ff8e51be
--- /dev/null
+++ b/tests/test-pkcs11-tool-import.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+SOURCE_PATH=${SOURCE_PATH:-..}
+
+source $SOURCE_PATH/tests/common.sh
+
+echo "======================================================="
+echo "Setup SoftHSM"
+echo "======================================================="
+if [[ ! -f $P11LIB ]]; then
+ echo "WARNING: The SoftHSM is not installed. Can not run this test"
+ exit 77;
+fi
+card_setup
+
+ID="0100"
+OPTS=""
+for KEYTYPE in "RSA" "EC"; do
+ echo "======================================================="
+ echo "Generate and import $KEYTYPE keys"
+ echo "======================================================="
+ if [ "$KEYTYPE" == "RSA" ]; then
+ ID="0100"
+ elif [ "$KEYTYPE" == "EC" ]; then
+ ID="0200"
+ OPTS="-pkeyopt ec_paramgen_curve:P-521"
+ fi
+ openssl genpkey -out "${KEYTYPE}_private.der" -outform DER -algorithm $KEYTYPE $OPTS
+ assert $? "Failed to generate private $KEYTYPE key"
+ $PKCS11_TOOL --write-object "${KEYTYPE}_private.der" --id "$ID" --type privkey \
+ --label "$KEYTYPE" -p "$PIN" --module "$P11LIB"
+ assert $? "Failed to write private $KEYTYPE key"
+
+ openssl pkey -in "${KEYTYPE}_private.der" -out "${KEYTYPE}_public.der" -pubout -inform DER -outform DER
+ assert $? "Failed to convert private $KEYTYPE key to public"
+ $PKCS11_TOOL --write-object "${KEYTYPE}_public.der" --id "$ID" --type pubkey --label "$KEYTYPE" \
+ -p $PIN --module $P11LIB
+ assert $? "Failed to write public $KEYTYPE key"
+ # certificate import already tested in all other tests
+
+ rm "${KEYTYPE}_private.der" "${KEYTYPE}_public.der"
+done
+
+echo "======================================================="
+echo "Cleanup"
+echo "======================================================="
+card_cleanup
+
+exit $ERRORS
From 63a7bceeca43ece1eee201ef7a974b20b294ba4e Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jakuje@gmail.com>
Date: Fri, 2 Dec 2022 18:07:43 +0100
Subject: [PATCH 4/4] Simplify the new test
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Veronika Hanulíková <61348757+xhanulik@users.noreply.github.com>
---
tests/test-pkcs11-tool-import.sh | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/tests/test-pkcs11-tool-import.sh b/tests/test-pkcs11-tool-import.sh
index 76ff8e51be..c90b3b4926 100755
--- a/tests/test-pkcs11-tool-import.sh
+++ b/tests/test-pkcs11-tool-import.sh
@@ -12,15 +12,13 @@ if [[ ! -f $P11LIB ]]; then
fi
card_setup
-ID="0100"
-OPTS=""
for KEYTYPE in "RSA" "EC"; do
echo "======================================================="
echo "Generate and import $KEYTYPE keys"
echo "======================================================="
- if [ "$KEYTYPE" == "RSA" ]; then
- ID="0100"
- elif [ "$KEYTYPE" == "EC" ]; then
+ ID="0100"
+ OPTS=""
+ if [ "$KEYTYPE" == "EC" ]; then
ID="0200"
OPTS="-pkeyopt ec_paramgen_curve:P-521"
fi

View File

@ -0,0 +1,855 @@
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 | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c
index eb7fc6afc..4215b733a 100644
--- a/src/libopensc/pkcs15.c
+++ b/src/libopensc/pkcs15.c
@@ -532,7 +532,7 @@ sc_pkcs15_get_lastupdate(struct sc_pkcs15_card *p15card)
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;
@@ -569,9 +569,11 @@ sc_pkcs15_get_lastupdate(struct sc_pkcs15_card *p15card)
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;
2.41.0
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(+)
diff --git a/src/pkcs15init/pkcs15-setcos.c b/src/pkcs15init/pkcs15-setcos.c
index 1b56afe6d..1907b47f9 100644
--- a/src/pkcs15init/pkcs15-setcos.c
+++ b/src/pkcs15init/pkcs15-setcos.c
@@ -349,6 +349,10 @@ setcos_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
/* 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];
--
2.41.0
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 ad2cabd53..c441ab1e7 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. */
--
2.41.0
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 4a0ddffbe..7107c47cb 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);
--
2.41.0
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 7107c47cb..49b514968 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);
--
2.41.0
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 d06568073..ce1d48e62 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)
--
2.41.0
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 2b793b028..3bad1e853 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));
--
2.41.0
From e7f81d86dcdc751f4737f4b29a99bfc54d29c5c9 Mon Sep 17 00:00:00 2001
From: Frank Morgner <frankmorgner@gmail.com>
Date: Thu, 8 Dec 2022 00:45:31 +0100
Subject: [PATCH] muscle: prevent out of bounds write
fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=53631
---
src/libopensc/muscle.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/libopensc/muscle.c b/src/libopensc/muscle.c
index 7af279a0a..61a4ec24d 100644
--- a/src/libopensc/muscle.c
+++ b/src/libopensc/muscle.c
@@ -127,7 +127,7 @@ int msc_zero_object(sc_card_t *card, msc_id objectId, size_t dataLength)
{
u8 zeroBuffer[MSC_MAX_APDU];
size_t i;
- size_t max_write_unit = MSC_MAX_SEND - 9; /* - 9 for object ID+length */
+ size_t max_write_unit = MIN(MSC_MAX_APDU, MSC_MAX_SEND - 9); /* - 9 for object ID+length */
memset(zeroBuffer, 0, max_write_unit);
for(i = 0; i < dataLength; i += max_write_unit) {
--
2.41.0
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 61a4ec24d..9d01e0c11 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)
--
2.41.0
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 91cee3731..3df03c6e1 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--) {
--
2.41.0
From 4013a807492568bf9907cfb3df41f130ac83c7b9 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Wed, 15 Nov 2023 10:53:46 +0100
Subject: [PATCH] setcos: Avoid writing behind the path buffer end
The path->value buffer is fixed to 16 bytes so it is not always possible
to append 2 more bytes. Doing so overruns the buffer, writing into the
ACL block, crashing during the cleanup.
Thanks oss-fuzz
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=64181
---
src/pkcs15init/pkcs15-setcos.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/pkcs15init/pkcs15-setcos.c b/src/pkcs15init/pkcs15-setcos.c
index 70a28048b..1eeeda064 100644
--- a/src/pkcs15init/pkcs15-setcos.c
+++ b/src/pkcs15init/pkcs15-setcos.c
@@ -287,6 +287,10 @@ setcos_new_file(sc_profile_t *profile, sc_card_t *card,
file->id += num;
p = &file->path;
*p = profile->df_info->file->path;
+ if (p->len + 2 > SC_MAX_PATH_SIZE) {
+ sc_file_free(file);
+ return SC_ERROR_INVALID_DATA;
+ }
p->value[p->len++] = (u8) (file->id / 256);
p->value[p->len++] = (u8) (file->id % 256);
--
2.42.0
From 8fc2c20c3f895569eeb58328bb882aec07325d3b Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Tue, 7 Nov 2023 17:48:27 +0100
Subject: [PATCH] iasecc: Avoid another buffer overflow
thanks oss-fuzz
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=63949
---
src/libopensc/iasecc-sdo.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/libopensc/iasecc-sdo.c b/src/libopensc/iasecc-sdo.c
index a41c3c2d3..86032f5a8 100644
--- a/src/libopensc/iasecc-sdo.c
+++ b/src/libopensc/iasecc-sdo.c
@@ -44,7 +44,8 @@ iasecc_parse_acls(struct sc_card *card, struct iasecc_sdo_docp *docp, int flags)
{
struct sc_context *ctx = card->ctx;
struct iasecc_extended_tlv *acls = &docp->acls_contact;
- int ii, offs;
+ int ii;
+ size_t offs;
unsigned char mask = 0x40;
if (flags)
@@ -56,8 +57,12 @@ iasecc_parse_acls(struct sc_card *card, struct iasecc_sdo_docp *docp, int flags)
docp->amb = *(acls->value + 0);
memset(docp->scbs, 0xFF, sizeof(docp->scbs));
for (ii=0, offs = 1; ii<7; ii++, mask >>= 1)
- if (mask & docp->amb)
+ if (mask & docp->amb) {
+ if (offs >= acls->size) {
+ LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
+ }
docp->scbs[ii] = *(acls->value + offs++);
+ }
sc_log(ctx, "iasecc_parse_docp() SCBs %02X:%02X:%02X:%02X:%02X:%02X:%02X",
docp->scbs[0],docp->scbs[1],docp->scbs[2],docp->scbs[3],
--
2.42.0
From 83b9129bd3cfc6ac57d5554e015c3df85f5076dc Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Wed, 11 Oct 2023 08:57:45 +0200
Subject: [PATCH] iassecc: Verify buffer lengths before use
Thanks oss-fuzz
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=63163
---
src/libopensc/iasecc-sdo.c | 55 +++++++++++++++++++++-----------------
1 file changed, 31 insertions(+), 24 deletions(-)
diff --git a/src/libopensc/iasecc-sdo.c b/src/libopensc/iasecc-sdo.c
index 3eeb03b91..a6e6c2677 100644
--- a/src/libopensc/iasecc-sdo.c
+++ b/src/libopensc/iasecc-sdo.c
@@ -36,7 +36,7 @@
#include "iasecc.h"
#include "iasecc-sdo.h"
-static int iasecc_parse_size(unsigned char *data, size_t *out);
+static int iasecc_parse_size(unsigned char *data, size_t data_len, size_t *out);
static int
@@ -330,7 +330,7 @@ iasecc_se_parse(struct sc_card *card, unsigned char *data, size_t data_len, stru
LOG_FUNC_CALLED(ctx);
if (*data == IASECC_SDO_TEMPLATE_TAG) {
- size_size = iasecc_parse_size(data + 1, &size);
+ size_size = iasecc_parse_size(data + 1, data_len - 1, &size);
LOG_TEST_RET(ctx, size_size, "parse error: invalid size data of IASECC_SDO_TEMPLATE");
data += size_size + 1;
@@ -345,7 +345,7 @@ iasecc_se_parse(struct sc_card *card, unsigned char *data, size_t data_len, stru
if ((*(data + 1) & 0x7F) != IASECC_SDO_CLASS_SE)
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
- size_size = iasecc_parse_size(data + 3, &size);
+ size_size = iasecc_parse_size(data + 3, data_len - 3, &size);
LOG_TEST_RET(ctx, size_size, "parse error: invalid SDO SE data size");
if (data_len != size + size_size + 3)
@@ -365,7 +365,7 @@ iasecc_se_parse(struct sc_card *card, unsigned char *data, size_t data_len, stru
LOG_FUNC_RETURN(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
}
- size_size = iasecc_parse_size(data + 1, &size);
+ size_size = iasecc_parse_size(data + 1, data_len - 1, &size);
LOG_TEST_RET(ctx, size_size, "parse error: invalid size data");
if (data_len != size + size_size + 1)
@@ -387,17 +387,17 @@ iasecc_se_parse(struct sc_card *card, unsigned char *data, size_t data_len, stru
static int
-iasecc_parse_size(unsigned char *data, size_t *out)
+iasecc_parse_size(unsigned char *data, size_t data_len, size_t *out)
{
- if (*data < 0x80) {
+ if (*data < 0x80 && data_len > 0) {
*out = *data;
return 1;
}
- else if (*data == 0x81) {
+ else if (*data == 0x81 && data_len > 1) {
*out = *(data + 1);
return 2;
}
- else if (*data == 0x82) {
+ else if (*data == 0x82 && data_len > 2) {
*out = *(data + 1) * 0x100 + *(data + 2);
return 3;
}
@@ -407,14 +407,18 @@ iasecc_parse_size(unsigned char *data, size_t *out)
static int
-iasecc_parse_get_tlv(struct sc_card *card, unsigned char *data, struct iasecc_extended_tlv *tlv)
+iasecc_parse_get_tlv(struct sc_card *card, unsigned char *data, size_t data_len, struct iasecc_extended_tlv *tlv)
{
struct sc_context *ctx = card->ctx;
size_t size_len, tag_len;
memset(tlv, 0, sizeof(*tlv));
sc_log(ctx, "iasecc_parse_get_tlv() called for tag 0x%X", *data);
+ if (data_len < 1)
+ LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
if ((*data == 0x7F) || (*data == 0x5F)) {
+ if (data_len < 2)
+ LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
tlv->tag = *data * 0x100 + *(data + 1);
tag_len = 2;
}
@@ -424,8 +428,11 @@ iasecc_parse_get_tlv(struct sc_card *card, unsigned char *data, struct iasecc_ex
}
sc_log(ctx, "iasecc_parse_get_tlv() tlv->tag 0x%X", tlv->tag);
- size_len = iasecc_parse_size(data + tag_len, &tlv->size);
+ size_len = iasecc_parse_size(data + tag_len, data_len - tag_len, &tlv->size);
LOG_TEST_RET(ctx, size_len, "parse error: invalid size data");
+ if (tag_len + size_len + tlv->size > data_len) {
+ LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
+ }
tlv->value = calloc(1, tlv->size);
if (!tlv->value)
@@ -452,7 +459,7 @@ iasecc_parse_chv(struct sc_card *card, unsigned char *data, size_t data_len, str
while(offs < data_len) {
struct iasecc_extended_tlv tlv;
- rv = iasecc_parse_get_tlv(card, data + offs, &tlv);
+ rv = iasecc_parse_get_tlv(card, data + offs, data_len - offs, &tlv);
LOG_TEST_RET(ctx, rv, "iasecc_parse_chv() get and parse TLV error");
sc_log(ctx,
@@ -486,7 +493,7 @@ iasecc_parse_prvkey(struct sc_card *card, unsigned char *data, size_t data_len,
while(offs < data_len) {
struct iasecc_extended_tlv tlv;
- rv = iasecc_parse_get_tlv(card, data + offs, &tlv);
+ rv = iasecc_parse_get_tlv(card, data + offs, data_len - offs, &tlv);
LOG_TEST_RET(ctx, rv, "iasecc_parse_prvkey() get and parse TLV error");
sc_log(ctx,
@@ -516,7 +523,7 @@ iasecc_parse_pubkey(struct sc_card *card, unsigned char *data, size_t data_len,
while(offs < data_len) {
struct iasecc_extended_tlv tlv;
- rv = iasecc_parse_get_tlv(card, data + offs, &tlv);
+ rv = iasecc_parse_get_tlv(card, data + offs, data_len - offs, &tlv);
LOG_TEST_RET(ctx, rv, "iasecc_parse_pubkey() get and parse TLV error");
sc_log(ctx,
@@ -554,7 +561,7 @@ iasecc_parse_keyset(struct sc_card *card, unsigned char *data, size_t data_len,
while(offs < data_len) {
struct iasecc_extended_tlv tlv;
- rv = iasecc_parse_get_tlv(card, data + offs, &tlv);
+ rv = iasecc_parse_get_tlv(card, data + offs, data_len - offs, &tlv);
LOG_TEST_RET(ctx, rv, "iasecc_parse_keyset() get and parse TLV error");
sc_log(ctx,
@@ -586,7 +593,7 @@ iasecc_parse_docp(struct sc_card *card, unsigned char *data, size_t data_len, st
while(offs < data_len) {
struct iasecc_extended_tlv tlv;
- rv = iasecc_parse_get_tlv(card, data + offs, &tlv);
+ rv = iasecc_parse_get_tlv(card, data + offs, data_len - offs, &tlv);
LOG_TEST_RET(ctx, rv, "iasecc_parse_get_tlv() get and parse TLV error");
sc_log(ctx,
@@ -641,7 +648,7 @@ iasecc_parse_docp(struct sc_card *card, unsigned char *data, size_t data_len, st
static int
-iasecc_sdo_parse_data(struct sc_card *card, unsigned char *data, struct iasecc_sdo *sdo)
+iasecc_sdo_parse_data(struct sc_card *card, unsigned char *data, size_t data_len, struct iasecc_sdo *sdo)
{
struct sc_context *ctx = card->ctx;
struct iasecc_extended_tlv tlv;
@@ -650,7 +657,7 @@ iasecc_sdo_parse_data(struct sc_card *card, unsigned char *data, struct iasecc_s
LOG_FUNC_CALLED(ctx);
sc_log(ctx, "iasecc_sdo_parse_data() class %X; ref %X", sdo->sdo_class, sdo->sdo_ref);
- tlv_size = iasecc_parse_get_tlv(card, data, &tlv);
+ tlv_size = iasecc_parse_get_tlv(card, data, data_len, &tlv);
LOG_TEST_RET(ctx, tlv_size, "parse error: get TLV");
sc_log(ctx, "iasecc_sdo_parse_data() tlv.tag 0x%X", tlv.tag);
@@ -735,7 +742,7 @@ iasecc_sdo_parse(struct sc_card *card, unsigned char *data, size_t data_len, str
LOG_FUNC_CALLED(ctx);
if (*data == IASECC_SDO_TEMPLATE_TAG) {
- size_size = iasecc_parse_size(data + 1, &size);
+ size_size = iasecc_parse_size(data + 1, data_len - 1, &size);
LOG_TEST_RET(ctx, size_size, "parse error: invalid size data of IASECC_SDO_TEMPLATE");
data += size_size + 1;
@@ -754,7 +761,7 @@ iasecc_sdo_parse(struct sc_card *card, unsigned char *data, size_t data_len, str
if (sdo->sdo_ref != (*(data + 2) & 0x3F))
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
- size_size = iasecc_parse_size(data + 3, &size);
+ size_size = iasecc_parse_size(data + 3, data_len - 3, &size);
LOG_TEST_RET(ctx, size_size, "parse error: invalid size data");
if (data_len != size + size_size + 3)
@@ -766,7 +773,7 @@ iasecc_sdo_parse(struct sc_card *card, unsigned char *data, size_t data_len, str
offs = 3 + size_size;
for (; offs < data_len;) {
- rv = iasecc_sdo_parse_data(card, data + offs, sdo);
+ rv = iasecc_sdo_parse_data(card, data + offs, data_len - offs, sdo);
LOG_TEST_RET(ctx, rv, "parse error: invalid SDO data");
offs += rv;
@@ -812,7 +819,7 @@ iasecc_sdo_allocate_and_parse(struct sc_card *card, unsigned char *data, size_t
if (data_len == 3)
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
- size_size = iasecc_parse_size(data + 3, &size);
+ size_size = iasecc_parse_size(data + 3, data_len - 3, &size);
LOG_TEST_RET(ctx, size_size, "parse error: invalid size data");
if (data_len != size + size_size + 3)
@@ -824,7 +831,7 @@ iasecc_sdo_allocate_and_parse(struct sc_card *card, unsigned char *data, size_t
offs = 3 + size_size;
for (; offs < data_len;) {
- rv = iasecc_sdo_parse_data(card, data + offs, sdo);
+ rv = iasecc_sdo_parse_data(card, data + offs, data_len - offs, sdo);
LOG_TEST_RET(ctx, rv, "parse error: invalid SDO data");
offs += rv;
@@ -1222,7 +1229,7 @@ iasecc_sdo_parse_card_answer(struct sc_context *ctx, unsigned char *data, size_t
memset(out, 0, sizeof(*out));
for (offs=0; offs<data_len; ) {
- size_size = iasecc_parse_size(data + 1, &size);
+ size_size = iasecc_parse_size(data + 1, data_len - 1, &size);
if (*(data + offs) == IASECC_CARD_ANSWER_TAG_DATA ) {
if (size > sizeof(out->data))
@@ -1293,7 +1300,7 @@ iasecc_docp_copy(struct sc_context *ctx, struct iasecc_sdo_docp *in, struct iase
int rv;
LOG_FUNC_CALLED(ctx);
- if (!in || !out)
+ if (!in || !out)
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
memset(out, 0, sizeof(struct iasecc_sdo_docp));
--
2.42.0
From fbda61d0d276dc98b9d1d1e6810bbd21d19e3859 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Fri, 27 Oct 2023 13:23:18 +0200
Subject: [PATCH] iasecc: Avoid buffer overflow with invalid data
Thanks oss-fuzz
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=63587
---
src/libopensc/iasecc-sdo.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/libopensc/iasecc-sdo.c b/src/libopensc/iasecc-sdo.c
index 1e01c0df5..479b3c23b 100644
--- a/src/libopensc/iasecc-sdo.c
+++ b/src/libopensc/iasecc-sdo.c
@@ -371,15 +371,15 @@ iasecc_se_parse(struct sc_card *card, unsigned char *data, size_t data_len, stru
static int
iasecc_parse_size(unsigned char *data, size_t data_len, size_t *out)
{
- if (*data < 0x80 && data_len > 0) {
+ if (data_len > 0 && *data < 0x80) {
*out = *data;
return 1;
}
- else if (*data == 0x81 && data_len > 1) {
+ else if (data_len > 1 && *data == 0x81) {
*out = *(data + 1);
return 2;
}
- else if (*data == 0x82 && data_len > 2) {
+ else if (data_len > 2 && *data == 0x82) {
*out = *(data + 1) * 0x100 + *(data + 2);
return 3;
}
--
2.42.0
From 2a4921ab23fd0853f327517636c50de947548161 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Veronika=20Hanul=C3=ADkov=C3=A1?= <vhanulik@redhat.com>
Date: Tue, 29 Aug 2023 14:40:21 +0200
Subject: [PATCH] iasecc: Check length of data when parsing crt
Thanks OSS-Fuzz
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=61797
---
src/libopensc/iasecc-sdo.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/libopensc/iasecc-sdo.c b/src/libopensc/iasecc-sdo.c
index b3e567dd5..3eeb03b91 100644
--- a/src/libopensc/iasecc-sdo.c
+++ b/src/libopensc/iasecc-sdo.c
@@ -204,7 +204,7 @@ iasecc_sdo_free(struct sc_card *card, struct iasecc_sdo *sdo)
static int
-iasecc_crt_parse(struct sc_card *card, unsigned char *data, struct iasecc_se_info *se)
+iasecc_crt_parse(struct sc_card *card, unsigned char *data, size_t data_len, struct iasecc_se_info *se)
{
struct sc_context *ctx = card->ctx;
struct sc_crt crt;
@@ -212,11 +212,16 @@ iasecc_crt_parse(struct sc_card *card, unsigned char *data, struct iasecc_se_inf
sc_log(ctx, "iasecc_crt_parse(0x%X) called", *data);
+ if (data_len < 2)
+ LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
+
memset(&crt, 0, sizeof(crt));
crt.tag = *(data + 0);
len = *(data + 1);
for(offs = 2; offs < len + 2; offs += 3) {
+ if ((size_t) offs + 2 >= data_len)
+ LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
sc_log(ctx, "iasecc_crt_parse(0x%X) CRT %X -> %X", *data, *(data + offs), *(data + offs + 2));
if (*(data + offs) == IASECC_CRT_TAG_USAGE) {
crt.usage = *(data + offs + 2);
@@ -368,7 +373,7 @@ iasecc_se_parse(struct sc_card *card, unsigned char *data, size_t data_len, stru
offs = 1 + size_size;
for (; offs < data_len;) {
- rv = iasecc_crt_parse(card, data + offs, se);
+ rv = iasecc_crt_parse(card, data + offs, data_len - offs, se);
LOG_TEST_RET(ctx, rv, "parse error: invalid SE data");
offs += rv;
--
2.42.0
From 6085994384a7171c5c68f6718d9db10ed77c5af1 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 13:56:24 +0200
Subject: [PATCH] card-entersafe.c: Free modulus buffer in case of error
Thanks OSS-Fuzz
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60680
---
src/libopensc/card-entersafe.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c
index eb31f7146..168894abd 100644
--- a/src/libopensc/card-entersafe.c
+++ b/src/libopensc/card-entersafe.c
@@ -1423,12 +1423,18 @@ static int entersafe_gen_key(sc_card_t *card, sc_entersafe_gen_key_data *data)
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_OUT_OF_MEMORY);
p=rbuf;
- if (*p!='E')
+ if (*p!='E') {
+ free(data->modulus);
+ data->modulus = NULL;
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA);
+ }
p+=2+p[1];
/* N */
- if (*p!='N')
+ if (*p!='N') {
+ free(data->modulus);
+ data->modulus = NULL;
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA);
+ }
++p;
if(*p++>0x80)
{
--
2.42.0
From 50f0985f6343eeac4044661d56807ee9286db42c Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Sun, 8 Oct 2023 19:08:39 +0200
Subject: [PATCH] entersafe: Avoid buffer overflow during keygen
Thanks oss-fuzz
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=63104
---
src/libopensc/card-entersafe.c | 54 ++++++++++++++++++++--------------
1 file changed, 32 insertions(+), 22 deletions(-)
diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c
index 168894abd..feb9ebe18 100644
--- a/src/libopensc/card-entersafe.c
+++ b/src/libopensc/card-entersafe.c
@@ -1374,8 +1374,9 @@ static int entersafe_gen_key(sc_card_t *card, sc_entersafe_gen_key_data *data)
int r;
size_t len = data->key_length >> 3;
sc_apdu_t apdu;
- u8 rbuf[300];
+ u8 rbuf[300] = {0};
u8 sbuf[4],*p;
+ size_t plen = 0;
SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
@@ -1418,40 +1419,49 @@ static int entersafe_gen_key(sc_card_t *card, sc_entersafe_gen_key_data *data)
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
LOG_TEST_RET(card->ctx, sc_check_sw(card,apdu.sw1,apdu.sw2),"EnterSafe get pukey failed");
- data->modulus = malloc(len);
- if (!data->modulus)
- SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_OUT_OF_MEMORY);
-
- p=rbuf;
- if (*p!='E') {
- free(data->modulus);
- data->modulus = NULL;
+ p = rbuf;
+ plen = apdu.resplen;
+ if (*p != 'E') {
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA);
}
- p+=2+p[1];
+ if ((size_t)(p - rbuf) + 2 + p[1] >= plen) {
+ SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA);
+ }
+ p += 2 + p[1];
/* N */
- if (*p!='N') {
- free(data->modulus);
- data->modulus = NULL;
+ if (*p != 'N') {
+ SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA);
+ }
+ if ((size_t)(p - rbuf) + 2 >= plen) {
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA);
}
++p;
- if(*p++>0x80)
+ if (*p++ > 0x80)
{
- u8 len_bytes=(*(p-1))&0x0f;
- size_t module_len=0;
- while(len_bytes!=0)
+ u8 len_bytes = (*(p - 1)) & 0x0f;
+ size_t module_len = 0;
+ if ((size_t)(p - rbuf) + len_bytes >= plen) {
+ SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA);
+ }
+ while (len_bytes != 0)
{
- module_len=module_len<<8;
- module_len+=*p++;
+ module_len = module_len << 8;
+ module_len += *p++;
--len_bytes;
}
}
- entersafe_reverse_buffer(p,len);
- memcpy(data->modulus,p,len);
+ if ((p - rbuf) + len >= plen) {
+ SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA);
+ }
- SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_SUCCESS);
+ data->modulus = malloc(len);
+ if (!data->modulus)
+ SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_OUT_OF_MEMORY);
+ entersafe_reverse_buffer(p, len);
+ memcpy(data->modulus, p, len);
+
+ SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS);
}
static int entersafe_get_serialnr(sc_card_t *card, sc_serial_number_t *serial)
--
2.42.0

View File

@ -2,51 +2,100 @@
%define nssdb %{_sysconfdir}/pki/nssdb
Name: opensc
Version: 0.23.0
Release: 2%{?dist}
Version: 0.20.0
Release: 8%{?dist}
Summary: Smart card library and applications
Group: System Environment/Libraries
License: LGPLv2+
URL: https://github.com/OpenSC/OpenSC/wiki
Source0: https://github.com/OpenSC/OpenSC/releases/download/%{version}/%{name}-%{version}.tar.gz
Source1: opensc.module
Patch1: opensc-0.19.0-pinpad.patch
# File caching by default (#2000626)
Patch8: %{name}-0.22.0-file-cache.patch
# https://github.com/OpenSC/OpenSC/pull/2656
Patch9: %{name}-0.23.0-pkcs11-tool-import.patch
# https://github.com/OpenSC/OpenSC/pull/2712
Patch10: %{name}-0.23.0-openssl-ctx.patch
# https://github.com/OpenSC/OpenSC/pull/2753
# https://github.com/OpenSC/OpenSC/commit/e8fba322a2f4d06ec5c74fe80f9e2b0e9fdefec6
# https://github.com/OpenSC/OpenSC/commit/891f10e49de1a5ee038b1cb2fb59dce40429e6c2
Patch11: %{name}-0.23.0-openpgp.patch
# https://github.com/OpenSC/OpenSC/commit/81944d1529202bd28359bede57c0a15deb65ba8a
Patch12: %{name}-0.23.0-cardos-pkcs15init.patch
Patch6: opensc-0.19.0-pinpad.patch
# https://github.com/OpenSC/OpenSC/pull/1772
Patch8: opensc-0.19.0-idprime.patch
# https://github.com/OpenSC/OpenSC/pull/1987
Patch9: opensc-0.20.0-cardos.patch
# https://github.com/OpenSC/OpenSC/pull/2129
Patch10: opensc-0.20.0-cac-pin-change.patch
# https://github.com/OpenSC/OpenSC/commit/6903aebf
Patch11: opensc-0.20.0-CVE-2020-26570.patch
# https://github.com/OpenSC/OpenSC/commit/ed55fcd2
Patch12: opensc-0.20.0-CVE-2020-26571.patch
# https://github.com/OpenSC/OpenSC/commit/9d294de9
Patch13: opensc-0.20.0-CVE-2020-26572.patch
# https://github.com/OpenSC/OpenSC/commit/8d4af9eb
Patch14: opensc-0.20.0-label-padding.patch
# https://github.com/OpenSC/OpenSC/commit/f1bcadfb
# https://github.com/OpenSC/OpenSC/pull/2166
Patch15: opensc-0.20.0-calloc0.patch
# https://github.com/OpenSC/OpenSC/pull/2148
# + configuration change by default
Patch16: opensc-0.20.0-file-cache.patch
# https://github.com/OpenSC/OpenSC/pull/1929
Patch17: opensc-0.20.0-idprime.patch
# https://github.com/OpenSC/OpenSC/pull/2787
Patch18: opensc-0.20.0-CVE-2023-2977.patch
# 31d8c2dfd14ed01b430def2f46cc718ef4b595fc
# 8f4a6c703b5ae7d4f44cf33c85330171afa917bf
# https://github.com/OpenSC/OpenSC/pull/1970 without the first and last commits
# https://github.com/OpenSC/OpenSC/pull/1923
# https://github.com/OpenSC/OpenSC/pull/2051
# https://github.com/OpenSC/OpenSC/pull/2077
# https://github.com/OpenSC/OpenSC/pull/2418
# https://github.com/OpenSC/OpenSC/pull/2600
# c2e00e9071952b30ed6d58d9b7670eb3d93ea6fb
# https://github.com/OpenSC/OpenSC/pull/2740
## OpenSC notify build issues
# 5e79a2a4abdd523cfff19824718bbb0d8ced7320
# 843779fe6e0f345f483f9ce9c9739913502391eb
# 7936bdef15c71139a6a6159cabaf9e6101565add
# 1202eceeefd5ffab45648d41ed0a3076cac10920
# 295f399304644e6b0acde267ac410d0aae4a1aee
# ca01aa7a8edc8280a5ceadebb472c2e3c198d8c2
Patch19: opensc-0.20.0-reader-removal.patch
# https://github.com/OpenSC/OpenSC/commit/bff98ff078a99e6864ba1a598fd7dc9af4a9476b
# https://github.com/OpenSC/OpenSC/commit/0875c69295ef28b45fb682b37cede58fc36b7a1a
Patch20: %{name}-0.23.0-cache-offsets.patch
# https://github.com/OpenSC/OpenSC/commit/868f76fb31255fd3fdacfc3e476452efeb61c3e7
# https://github.com/OpenSC/OpenSC/commit/80cc5d30635f0d2c92b5099c0f9dc680d0ffce2f
Patch21: %{name}-0.23.0-pin-bypass.patch
# https://github.com/OpenSC/OpenSC/commit/245efe608d083fd4e4ec96793fdefd218e26fde7
# https://github.com/OpenSC/OpenSC/commit/440ca666eff10cc7011901252d20f3fc4ea23651
# https://github.com/OpenSC/OpenSC/commit/41d61da8481582e12710b5858f8b635e0a71ab5e
# https://github.com/OpenSC/OpenSC/commit/88880db0307a07e33cf2e1592bb029e9c170dfea
# https://github.com/OpenSC/OpenSC/commit/638a5007a5d240d6fa901aa822cfeef94fe36e85
# https://github.com/OpenSC/OpenSC/commit/c449a181a6988cc1e8dc8764d23574e48cdc3fa6
# https://github.com/OpenSC/OpenSC/commit/5631e9843c832a99769def85b7b9b68b4e3e3959
# https://github.com/OpenSC/OpenSC/commit/e7f81d86dcdc751f4737f4b29a99bfc54d29c5c9
# https://github.com/OpenSC/OpenSC/commit/df5a176bfdf8c52ba89c7fef1f82f6f3b9312bc1
# https://github.com/OpenSC/OpenSC/commit/578aed8391ef117ca64a9e0cba8e5c264368a0ec
# https://github.com/OpenSC/OpenSC/commit/013a807492568bf9907cfb3df41f130ac83c7b9
# https://github.com/OpenSC/OpenSC/commit/fc2c20c3f895569eeb58328bb882aec07325d3b
# https://github.com/OpenSC/OpenSC/commit/3b9129bd3cfc6ac57d5554e015c3df85f5076dc
# https://github.com/OpenSC/OpenSC/commit/bda61d0d276dc98b9d1d1e6810bbd21d19e3859
# https://github.com/OpenSC/OpenSC/commit/a4921ab23fd0853f327517636c50de947548161
# https://github.com/OpenSC/OpenSC/commit/085994384a7171c5c68f6718d9db10ed77c5af1
# https://github.com/OpenSC/OpenSC/commit/0f0985f6343eeac4044661d56807ee9286db42c
Patch22: %{name}-0.23.0-pkcs15init.patch
# https://github.com/OpenSC/OpenSC/pull/2948
# https://github.com/OpenSC/OpenSC/pull/3016
Patch23: %{name}-0.23.0-constant-time-pkcs1.patch
BuildRequires: make
BuildRequires: pcsc-lite-devel
BuildRequires: readline-devel
BuildRequires: openssl-devel
BuildRequires: /usr/bin/xsltproc
BuildRequires: docbook-style-xsl
BuildRequires: autoconf automake libtool gcc
BuildRequires: desktop-file-utils
BuildRequires: bash-completion
BuildRequires: zlib-devel
# For tests
BuildRequires: libcmocka-devel
BuildRequires: vim-common
%if ! 0%{?rhel}
BuildRequires: softhsm
%endif
BuildRequires: openssl
Requires: pcsc-lite-libs%{?_isa}
Requires: pcsc-lite
Obsoletes: mozilla-opensc-signer < 0.12.0
Obsoletes: opensc-devel < 0.12.0
Obsoletes: coolkey <= 1.1.0-36
# The simclist is bundled in upstream
Provides: bundled(simclist) = 1.5
%description
OpenSC provides a set of libraries and utilities to work with smart cards. Its
@ -60,12 +109,23 @@ every software/card that does so, too.
%prep
%setup -q
%patch1 -p1 -b .pinpad
%patch8 -p1 -b .file-cache
%patch9 -p1 -b .pkcs11-tool-import
%patch10 -p1 -b .ossl3context
%patch11 -p1 -b .openpgp
%patch12 -p1 -b .cardos-pkcs15init
%patch6 -p1 -b .pinpad
%patch8 -p1 -b .idprime
%patch9 -p1 -b .cardos
%patch10 -p1 -b .cac-pin-change
%patch11 -p1 -b .CVE-2020-26570
%patch12 -p1 -b .CVE-2020-26571
%patch13 -p1 -b .CVE-2020-26572
%patch14 -p1 -b .padding
%patch15 -p1 -b .calloc0
%patch16 -p1 -b .file-cache
%patch17 -p1 -b .idprime
%patch18 -p1 -b .CVE-2023-2977
%patch19 -p1 -b .reader-removal
%patch20 -p1 -b .cache-offsets
%patch21 -p1 -b .pin-bypass
%patch22 -p1 -b .pkcs15init
%patch23 -p1 -b .constant-time-pkcs1.5
cp -p src/pkcs15init/README ./README.pkcs15init
cp -p src/scconf/README.scconf .
@ -75,30 +135,25 @@ sed -i -e 's|/usr/local/towitoko/lib/|/usr/lib/ctapi/|' etc/opensc.conf.example.
%build
autoreconf -fvi
%ifarch %{ix86}
%ifarch %{ix86} ppc s390
sed -i -e 's/opensc.conf/opensc-%{_arch}.conf/g' src/libopensc/Makefile.in
%endif
sed -i -e 's|"/lib /usr/lib\b|"/%{_lib} %{_libdir}|' configure # lib64 rpaths
%set_build_flags
CFLAGS="$CFLAGS -Wstrict-aliasing=2 -Wno-deprecated-declarations"
%configure --disable-static \
--disable-autostart-items \
--disable-notify \
--disable-assert \
--enable-pcsc \
--enable-cmocka \
--enable-sm
%make_build
--disable-tests \
--enable-sm \
--with-pcsc-provider=libpcsclite.so.1
make %{?_smp_mflags} V=1
%check
make check
%install
%make_install
make install DESTDIR=$RPM_BUILD_ROOT
install -Dpm 644 %{SOURCE1} $RPM_BUILD_ROOT%{_datadir}/p11-kit/modules/opensc.module
%ifarch %{ix86}
%ifarch %{ix86} ppc s390
# To avoid multilib issues, move these files on 32b intel architectures
rm -f $RPM_BUILD_ROOT%{_sysconfdir}/opensc.conf
install -Dpm 644 etc/opensc.conf $RPM_BUILD_ROOT%{_sysconfdir}/opensc-%{_arch}.conf
@ -120,29 +175,51 @@ rm -rf $RPM_BUILD_ROOT%{_datadir}/doc/opensc
# public headers and pkgconfig files.
# Remove the symlink as nothing is supposed to link against libopensc.
rm -f $RPM_BUILD_ROOT%{_libdir}/libopensc.so
# remove the .pc file so we do not confuse users #1673139
rm -f $RPM_BUILD_ROOT%{_libdir}/pkgconfig/*.pc
rm -f $RPM_BUILD_ROOT%{_libdir}/libsmm-local.so
%if 0%{?rhel} && 0%{?rhel} < 7
rm -rf %{buildroot}%{_datadir}/bash-completion/
%endif
# the npa-tool builds to nothing since we do not have OpenPACE library
rm -rf %{buildroot}%{_bindir}/npa-tool
rm -rf %{buildroot}%{_mandir}/man1/npa-tool.1*
# the pkcs11-register is not applicable to Fedora/RHEL where we use p11-kit
# We use p11-kit for pkcs11 modules registration
rm -rf %{buildroot}%{_bindir}/pkcs11-register
rm -rf %{buildroot}%{_mandir}/man1/pkcs11-register.1*
# It is even missing the manual page
#rm -rf %{buildroot}%{_mandir}/man1/pkcs11-register.1*
# Remove the notification files
rm %{buildroot}%{_datadir}/applications/org.opensc.notify.desktop
rm %{buildroot}%{_mandir}/man1/opensc-notify.1*
desktop-file-validate %{buildroot}/%{_datadir}/applications/org.opensc.notify.desktop
%post
/sbin/ldconfig
# Remove our PKCS#11 module from NSS DB, if there is NSS installed, because
# it is already loaded by p11-kit-proxy. Using both of them can cause
# race conditions and hard-to-debug problems
# TODO Remove with F30 or so
if [ -x /usr/bin/modutil ]; then
isThere=`modutil -rawlist -dbdir %{nssdb} | grep %{opensc_module} || echo NO`
if [ ! "$isThere" == "NO" ]; then
modutil -delete %{opensc_module} -dbdir %{nssdb} -force || :
fi
isThere=`modutil -rawlist -dbdir sql:%{nssdb} | grep %{opensc_module} || echo NO`
if [ ! "$isThere" == "NO" ]; then
modutil -delete %{opensc_module} -dbdir sql:%{nssdb} -force || :
fi
fi
%postun
/sbin/ldconfig
%files
%doc COPYING NEWS README*
%if ! 0%{?rhel} || 0%{?rhel} >= 7
%{_datadir}/bash-completion/*
%endif
%ifarch %{ix86}
%ifarch %{ix86} ppc s390
%{_mandir}/man5/opensc-%{_arch}.conf.5*
%else
%config(noreplace) %{_sysconfdir}/opensc.conf
@ -150,9 +227,6 @@ rm %{buildroot}%{_mandir}/man1/opensc-notify.1*
%endif
%config(noreplace) %{_sysconfdir}/opensc-%{_arch}.conf
# Co-owned with p11-kit so it is not hard dependency
%dir %{_datadir}/p11-kit
%dir %{_datadir}/p11-kit/modules
%{_datadir}/p11-kit/modules/opensc.module
%{_bindir}/cardos-tool
%{_bindir}/cryptoflex-tool
@ -164,6 +238,7 @@ rm %{buildroot}%{_mandir}/man1/opensc-notify.1*
%{_bindir}/opensc-explorer
%{_bindir}/opensc-tool
%{_bindir}/opensc-asn1
%{_bindir}/opensc-notify
%{_bindir}/piv-tool
%{_bindir}/pkcs11-tool
%{_bindir}/pkcs15-crypt
@ -173,11 +248,13 @@ rm %{buildroot}%{_mandir}/man1/opensc-notify.1*
%{_bindir}/dnie-tool
%{_bindir}/westcos-tool
%{_bindir}/egk-tool
%{_datadir}/applications/org.opensc.notify.desktop
%{_bindir}/goid-tool
%{_libdir}/lib*.so.*
%{_libdir}/opensc-pkcs11.so
%{_libdir}/pkcs11-spy.so
%{_libdir}/onepin-opensc-pkcs11.so
%{_libdir}/pkgconfig/*.pc
%%dir %{_libdir}/pkcs11
%{_libdir}/pkcs11/opensc-pkcs11.so
%{_libdir}/pkcs11/onepin-opensc-pkcs11.so
@ -187,13 +264,13 @@ rm %{buildroot}%{_mandir}/man1/opensc-notify.1*
%{_mandir}/man1/cryptoflex-tool.1*
%{_mandir}/man1/eidenv.1*
%{_mandir}/man1/gids-tool.1*
%{_mandir}/man1/goid-tool.1*
%{_mandir}/man1/iasecc-tool.1*
%{_mandir}/man1/netkey-tool.1*
%{_mandir}/man1/openpgp-tool.1*
%{_mandir}/man1/opensc-explorer.*
%{_mandir}/man1/opensc-tool.1*
%{_mandir}/man1/opensc-asn1.1*
%{_mandir}/man1/opensc-notify.1*
%{_mandir}/man1/piv-tool.1*
%{_mandir}/man1/pkcs11-tool.1*
%{_mandir}/man1/pkcs15-crypt.1*
@ -207,103 +284,62 @@ rm %{buildroot}%{_mandir}/man1/opensc-notify.1*
%changelog
* Thu May 25 2023 Jakub Jelen <jjelen@redhat.com> - 0.23.0-2
- Fix regression in handling OpenPGP cards
- Fix CVE-2023-2977: buffer overrun in pkcs15init for cardos
* Thu Feb 08 2024 Veronika Hanulikova <vhanulik@redhat.com> - 0.20.0-8
- Fix CVE-2023-5992: Side-channel leaks while stripping encryption PKCS#1.5 padding
* Wed Mar 08 2023 Jakub Jelen <jjelen@redhat.com> - 0.23.0-1
- Rebase to latest 0.23.0 release (#2100409)
- Use separate OpenSSL context to work better from inside of OpenSSL providers
* Thu Nov 30 2023 Jakub Jelen <jjelen@redhat.com> - 0.20.0-7
- Fix file caching with different offsets (RHEL-4077)
- Fix CVE-2023-40660: Potential PIN bypass
- Fix CVE-2023-40661: Dynamic analyzers reports in pkcs15init
- Fix CVE-2023-5992: Marvin: Side-channel leaks while stripping encryption PKCS#1.5 padding
* Fri Oct 08 2021 Jakub Jelen <jjelen@redhat.com> - 0.22.0-2
- Unbreak detection of unentrolled smart cards (#2007029)
- Enable file caching by default except for pkcs15-init (#2000626)
* Tue Jul 11 2023 Jakub Jelen <jjelen@redhat.com> - 0.20.0-6
- Fix introduced issues tagged by coverity (RHEL-765)
* Wed Aug 11 2021 Jakub Jelen <jjelen@redhat.com> - 0.22.0-1
- New upstream release (#1970534)
* Thu Jun 15 2023 Jakub Jelen <jjelen@redhat.com> - 0.20.0-5
- Avoid potential crash because of missing list terminator (#2196234)
- Fix CVE-2023-2977: potential buffer overrun in pkcs15 cardos_have_verifyrc_package (#2211093)
- Backport upstream changes regarding to reader removal (#2097048)
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 0.21.0-9
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688
* Fri Nov 20 2020 Jakub Jelen <jjelen@redhat.com> - 0.20.0-4
- Use file cache by default (#1892810)
- Avoid calloc with 0 argument (#1895401)
* Thu Jul 15 2021 Jakub Jelen <jjelen@redhat.com> - 0.21.0-8
- Fix issue with handling EC keys in OpenSSL 3.0 (#1953480)
* Tue Oct 20 2020 Jakub Jelen <jjelen@redhat.com> - 0.20.0-3
- Support PIN change for HID Alt tokens (#1830901)
- Fix CVE-2020-26570, CVE-2020-26571 and CVE-2020-26572
- Fix right padding of token labels of some cards (#1877973)
* Wed Jun 16 2021 Mohan Boddu <mboddu@redhat.com> - 0.21.0-7
- Rebuilt for RHEL 9 BETA for openssl 3.0
Related: rhbz#1971065
* Wed May 27 2020 Jakub Jelen <jjelen@redhat.com> - 0.20.0-2
- Unbreak different CardOS 5 configurations supporting raw RSA (#1830856)
* Mon May 24 2021 Jakub Jelen <jjelen@redhat.com> - 0.21.0-6
- Build against OpenSSL 3.0 (#1953480)
* Wed Apr 22 2020 Jakub Jelen <jjelen@redhat.com> - 0.20.0-1
- Rebase to current upstream release (#1810660)
* Fri Apr 16 2021 Mohan Boddu <mboddu@redhat.com> - 0.21.0-5
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
* Mon Nov 25 2019 Jakub Jelen <jjelen@redhat.com> - 0.19.0-7
- Unbreak RSA-PSS mechanisms in -6 release (#1775673)
* Thu Feb 25 2021 Jakub Jelen <jjelen@redhat.com> - 0.21.0-4
- Couple of more issues of strict aliasing (#1930652)
* Thu Nov 14 2019 Jakub Jelen <jjelen@redhat.com> - 0.19.0-6
- Add support for Gemalto IDPrime smart cards (#1657970)
- Fix 2k RSA key operations with Coolkey (#1766712)
* Tue Feb 23 2021 Jakub Jelen <jjelen@redhat.com> - 0.21.0-3
- Unbreak with gcc11 (#1930652)
* Thu Apr 18 2019 Jakub Jelen <jjelen@redhat.com> - 0.19.0-5
- Avoid multilib issues (#1693380)
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 0.21.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Tue Nov 24 2020 Jakub Jelen <jjelen@redhat.com> - 0.21.0-1
- New upstream release (#1884886)
* Fri Oct 30 2020 Jeff Law <law@redhat.com> - 0.20.0-9
- Fix potentially uninitialized array reference exposed by gcc-11
* Wed Aug 19 2020 Igor Raits <ignatenkobrain@fedoraproject.org> - 0.20.0-8
- Drop useless ldconfig scriptlets
* Tue Jul 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 0.20.0-7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Wed May 13 2020 Jakub Jelen <jjelen@redhat.com> - 0.20.0-6
- Unbreak CardOS 5.x support (#1830528)
* Mon Feb 10 2020 Jakub Jelen <jjelen@redhat.com> - 0.20.0-5
- Unbreak build on gcc10 with -fno-common (#1799836)
* Wed Jan 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 0.20.0-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Fri Jan 10 2020 Jakub Jelen <jjelen@redhat.com> - 0.20.0-3
- Drop the notification support for now
* Fri Jan 10 2020 Jakub Jelen <jjelen@redhat.com> - 0.20.0-2
- Cleanup spec file
- Split notify support to separate subpackage
* Thu Jan 02 2020 Jakub Jelen <jjelen@redhat.com> - 0.20.0-1
- New upstream release (#1749357)
- Fixes for various security issues identified by fuzzing (#1765223, #1765231, #1782520, #1782951, #1782956)
* Mon Sep 30 2019 Jakub Jelen <jjelen@redhat.com> - 0.19.0-8
- Correctly mention bundled simclist library
- Add missing zlib build requires (#1756326)
* Thu Jul 25 2019 Fedora Release Engineering <releng@fedoraproject.org> - 0.19.0-7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Wed Mar 27 2019 Jakub Jelen <jjelen@redhat.com> - 0.19.0-6
- Make OpenSC multilib again by moving the offending files on ix86 arch
- Do not ship packageconfig files to avoid inadvertent linking against pkcs11 modules (#1673139)
* Sun Feb 17 2019 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 0.19.0-5
- Rebuild for readline 8.0
* Fri Feb 01 2019 Fedora Release Engineering <releng@fedoraproject.org> - 0.19.0-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Wed Dec 12 2018 Jakub Jelen <jjelen@redhat.com> - 0.19.0-4
- Unbreak the Dual CAC cards in PIV driver (#1651748)
- Fix few more corner cases for handling different types of padding (#1595626)
- Unbreak signature verification in pkcs11-tool (#1651748)
* Wed Oct 31 2018 Jakub Jelen <jjelen@redhat.com> - 0.19.0-3
- Unbreak the RSA-PSS mechanisms
- Unbreak the signing using hashed mechanisms in CardOS and others
- Unbreak the RSA-PSS mechanisms (#1595626)
- Unbreak the signing using hashed mechanisms in CardOS and others (#1644338)
* Mon Oct 22 2018 Jakub Jelen <jjelen@redhat.com> - 0.19.0-2
- Fix verification after implementing RSA-PSS mechanisms
- Disable pinpad by default
- Avoid mismatching coolkey cards for muscle ones (#1588722)
- Implement legacy CAC1 driver (#1638052)
- Disable pinpad
- Fixup verification after RSA-PSS implementation
* Tue Sep 25 2018 Jakub Jelen <jjelen@redhat.com> - 0.19.0-1
- New upstream release fixing various CVE-2018-16418 - 16421, 16423 - 16427
@ -563,7 +599,7 @@ rm %{buildroot}%{_mandir}/man1/opensc-notify.1*
- Autorebuild for GCC 4.3
* Wed Dec 05 2007 Release Engineering <rel-eng at fedoraproject dot org> - 0.11.4-3
- Rebuild for deps
- Rebuild for deps
* Wed Dec 5 2007 Ville Skyttä <ville.skytta at iki.fi> - 0.11.4-2
- Rebuild.