Compare commits
No commits in common. "c8-beta" and "c8" have entirely different histories.
96
SOURCES/opensc-0.23.0-cache-offsets.patch
Normal file
96
SOURCES/opensc-0.23.0-cache-offsets.patch
Normal 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;
|
||||
}
|
||||
|
||||
|
485
SOURCES/opensc-0.23.0-constant-time-pkcs1.patch
Normal file
485
SOURCES/opensc-0.23.0-constant-time-pkcs1.patch
Normal 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);
|
||||
}
|
||||
|
107
SOURCES/opensc-0.23.0-pin-bypass.patch
Normal file
107
SOURCES/opensc-0.23.0-pin-bypass.patch
Normal 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
|
||||
|
855
SOURCES/opensc-0.23.0-pkcs15init.patch
Normal file
855
SOURCES/opensc-0.23.0-pkcs15init.patch
Normal 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
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
Name: opensc
|
||||
Version: 0.20.0
|
||||
Release: 6%{?dist}
|
||||
Release: 8%{?dist}
|
||||
Summary: Smart card library and applications
|
||||
|
||||
Group: System Environment/Libraries
|
||||
@ -54,7 +54,33 @@ Patch18: opensc-0.20.0-CVE-2023-2977.patch
|
||||
# 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: pcsc-lite-devel
|
||||
BuildRequires: readline-devel
|
||||
@ -96,6 +122,10 @@ every software/card that does so, too.
|
||||
%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 .
|
||||
@ -254,6 +284,15 @@ fi
|
||||
|
||||
|
||||
%changelog
|
||||
* 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
|
||||
|
||||
* 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
|
||||
|
||||
* Tue Jul 11 2023 Jakub Jelen <jjelen@redhat.com> - 0.20.0-6
|
||||
- Fix introduced issues tagged by coverity (RHEL-765)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user