import CS opensc-0.23.0-5.el9
This commit is contained in:
parent
873535e9e3
commit
76917519d5
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;
|
||||
}
|
||||
|
||||
|
824
SOURCES/opensc-0.23.0-constant-time-pkcs1.5.patch
Normal file
824
SOURCES/opensc-0.23.0-constant-time-pkcs1.5.patch
Normal file
@ -0,0 +1,824 @@
|
||||
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
|
||||
index 5153428dce..9ecbffe8fd 100644
|
||||
--- a/src/common/Makefile.am
|
||||
+++ b/src/common/Makefile.am
|
||||
@@ -8,7 +8,8 @@ dist_noinst_DATA = \
|
||||
LICENSE.compat_getopt compat_getopt.txt \
|
||||
compat_getopt_main.c \
|
||||
README.compat_strlcpy compat_strlcpy.3
|
||||
-noinst_HEADERS = compat_strlcat.h compat_strlcpy.h compat_strnlen.h compat_getpass.h compat_getopt.h simclist.h libpkcs11.h libscdl.h
|
||||
+noinst_HEADERS = compat_strlcat.h compat_strlcpy.h compat_strnlen.h compat_getpass.h \
|
||||
+ compat_getopt.h simclist.h libpkcs11.h libscdl.h constant-time.h
|
||||
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/src
|
||||
|
||||
@@ -43,7 +44,8 @@ TIDY_FILES = \
|
||||
compat_report_rangecheckfailure.c \
|
||||
compat___iob_func.c \
|
||||
simclist.c simclist.h \
|
||||
- libpkcs11.c libscdl.c
|
||||
+ libpkcs11.c libscdl.c \
|
||||
+ constant-time.h
|
||||
|
||||
check-local:
|
||||
if [ -x "$(CLANGTIDY)" ]; then clang-tidy -config='' --checks='$(TIDY_CHECKS)' -header-filter=.* $(addprefix $(srcdir)/,$(TIDY_FILES)) -- $(TIDY_FLAGS); fi
|
||||
diff --git a/src/common/constant-time.h b/src/common/constant-time.h
|
||||
new file mode 100644
|
||||
index 0000000000..40c3e500c2
|
||||
--- /dev/null
|
||||
+++ b/src/common/constant-time.h
|
||||
@@ -0,0 +1,134 @@
|
||||
+/* Original source: https://github.com/openssl/openssl/blob/9890cc42daff5e2d0cad01ac4bf78c391f599a6e/include/internal/constant_time.h */
|
||||
+
|
||||
+#ifndef CONSTANT_TIME_H
|
||||
+#define CONSTANT_TIME_H
|
||||
+
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+#if !defined(inline)
|
||||
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
||||
+#define constant_inline inline
|
||||
+#elif defined(__GNUC__) && __GNUC__ >= 2
|
||||
+#elif defined(__GNUC__) && __GNUC__ >= 2
|
||||
+#elif defined(_MSC_VER)
|
||||
+#define constant_inline __inline
|
||||
+#else
|
||||
+#define constant_inline
|
||||
+#endif
|
||||
+#else /* use what caller wants as inline may be from config.h */
|
||||
+#define constant_inline inline /* inline */
|
||||
+#endif
|
||||
+
|
||||
+/*-
|
||||
+ * The boolean methods return a bitmask of all ones (0xff...f) for true
|
||||
+ * and 0 for false. For example,
|
||||
+ * if (a < b) {
|
||||
+ * c = a;
|
||||
+ * } else {
|
||||
+ * c = b;
|
||||
+ * }
|
||||
+ * can be written as
|
||||
+ * unsigned int lt = constant_time_lt(a, b);
|
||||
+ * c = constant_time_select(lt, a, b);
|
||||
+ */
|
||||
+
|
||||
+static constant_inline unsigned int
|
||||
+value_barrier(unsigned int a)
|
||||
+{
|
||||
+ volatile unsigned int r = a;
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
+static constant_inline size_t
|
||||
+value_barrier_s(size_t a)
|
||||
+{
|
||||
+ volatile size_t r = a;
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
+/* MSB */
|
||||
+static constant_inline size_t
|
||||
+constant_time_msb_s(size_t a)
|
||||
+{
|
||||
+ return 0 - (a >> (sizeof(a) * 8 - 1));
|
||||
+}
|
||||
+
|
||||
+static constant_inline unsigned int
|
||||
+constant_time_msb(unsigned int a)
|
||||
+{
|
||||
+ return 0 - (a >> (sizeof(a) * 8 - 1));
|
||||
+}
|
||||
+
|
||||
+/* Select */
|
||||
+static constant_inline unsigned int
|
||||
+constant_time_select(unsigned int mask, unsigned int a, unsigned int b)
|
||||
+{
|
||||
+ return (value_barrier(mask) & a) | (value_barrier(~mask) & b);
|
||||
+}
|
||||
+
|
||||
+static constant_inline unsigned char
|
||||
+constant_time_select_8(unsigned char mask, unsigned char a, unsigned char b)
|
||||
+{
|
||||
+ return (unsigned char)constant_time_select(mask, a, b);
|
||||
+}
|
||||
+
|
||||
+static constant_inline size_t
|
||||
+constant_time_select_s(size_t mask, size_t a, size_t b)
|
||||
+{
|
||||
+ return (value_barrier_s(mask) & a) | (value_barrier_s(~mask) & b);
|
||||
+}
|
||||
+
|
||||
+/* Zero */
|
||||
+static constant_inline unsigned int
|
||||
+constant_time_is_zero(unsigned int a)
|
||||
+{
|
||||
+ return constant_time_msb(~a & (a - 1));
|
||||
+}
|
||||
+
|
||||
+static constant_inline size_t
|
||||
+constant_time_is_zero_s(size_t a)
|
||||
+{
|
||||
+ return constant_time_msb_s(~a & (a - 1));
|
||||
+}
|
||||
+
|
||||
+/* Comparison*/
|
||||
+static constant_inline size_t
|
||||
+constant_time_lt_s(size_t a, size_t b)
|
||||
+{
|
||||
+ return constant_time_msb_s(a ^ ((a ^ b) | ((a - b) ^ b)));
|
||||
+}
|
||||
+
|
||||
+static constant_inline unsigned int
|
||||
+constant_time_lt(unsigned int a, unsigned int b)
|
||||
+{
|
||||
+ return constant_time_msb(a ^ ((a ^ b) | ((a - b) ^ b)));
|
||||
+}
|
||||
+
|
||||
+static constant_inline unsigned int
|
||||
+constant_time_ge(unsigned int a, unsigned int b)
|
||||
+{
|
||||
+ return ~constant_time_lt(a, b);
|
||||
+}
|
||||
+
|
||||
+/* Equality*/
|
||||
+
|
||||
+static constant_inline unsigned int
|
||||
+constant_time_eq(unsigned int a, unsigned int b)
|
||||
+{
|
||||
+ return constant_time_is_zero(a ^ b);
|
||||
+}
|
||||
+
|
||||
+static constant_inline size_t
|
||||
+constant_time_eq_s(size_t a, size_t b)
|
||||
+{
|
||||
+ return constant_time_is_zero_s(a ^ b);
|
||||
+}
|
||||
+
|
||||
+static constant_inline unsigned int
|
||||
+constant_time_eq_i(int a, int b)
|
||||
+{
|
||||
+ return constant_time_eq((unsigned int)a, (unsigned int)b);
|
||||
+}
|
||||
+
|
||||
+#endif /* CONSTANT_TIME_H */
|
||||
diff --git a/src/libopensc/internal.h b/src/libopensc/internal.h
|
||||
index 7531260c14..2a98f0e966 100644
|
||||
--- a/src/libopensc/internal.h
|
||||
+++ b/src/libopensc/internal.h
|
||||
@@ -175,8 +175,8 @@ int _sc_card_add_xeddsa_alg(struct sc_card *card, size_t key_length,
|
||||
|
||||
int sc_pkcs1_strip_01_padding(struct sc_context *ctx, const u8 *in_dat, size_t in_len,
|
||||
u8 *out_dat, size_t *out_len);
|
||||
-int sc_pkcs1_strip_02_padding(struct sc_context *ctx, const u8 *data, size_t len,
|
||||
- u8 *out_dat, size_t *out_len);
|
||||
+int sc_pkcs1_strip_02_padding_constant_time(sc_context_t *ctx, unsigned int n, const u8 *data,
|
||||
+ unsigned int data_len, u8 *out, unsigned int *out_len);
|
||||
int sc_pkcs1_strip_digest_info_prefix(unsigned int *algorithm,
|
||||
const u8 *in_dat, size_t in_len, u8 *out_dat, size_t *out_len);
|
||||
#ifdef ENABLE_OPENSSL
|
||||
diff --git a/src/libopensc/padding.c b/src/libopensc/padding.c
|
||||
index ca47733a4e..ddb3061134 100644
|
||||
--- a/src/libopensc/padding.c
|
||||
+++ b/src/libopensc/padding.c
|
||||
@@ -32,10 +32,13 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
+#include "common/constant-time.h"
|
||||
#include "internal.h"
|
||||
#include "pkcs11/pkcs11.h"
|
||||
/* TODO doxygen comments */
|
||||
|
||||
+#define SC_PKCS1_PADDING_MIN_SIZE 11
|
||||
+
|
||||
/*
|
||||
* Prefixes for pkcs-v1 signatures
|
||||
*/
|
||||
@@ -144,44 +147,82 @@ sc_pkcs1_strip_01_padding(struct sc_cont
|
||||
}
|
||||
|
||||
|
||||
-/* remove pkcs1 BT02 padding (adding BT02 padding is currently not
|
||||
- * needed/implemented) */
|
||||
+/* Remove pkcs1 BT02 padding (adding BT02 padding is currently not
|
||||
+ * needed/implemented) in constant-time.
|
||||
+ * Original source: https://github.com/openssl/openssl/blob/9890cc42daff5e2d0cad01ac4bf78c391f599a6e/crypto/rsa/rsa_pk1.c#L171 */
|
||||
int
|
||||
-sc_pkcs1_strip_02_padding(sc_context_t *ctx, const u8 *data, size_t len, u8 *out, size_t *out_len)
|
||||
+sc_pkcs1_strip_02_padding_constant_time(sc_context_t *ctx, unsigned int n, const u8 *data, unsigned int data_len, u8 *out, unsigned int *out_len)
|
||||
{
|
||||
- unsigned int n = 0;
|
||||
-
|
||||
+ unsigned int i = 0;
|
||||
+ u8 *msg, *msg_orig = NULL;
|
||||
+ unsigned int good, found_zero_byte, mask;
|
||||
+ unsigned int zero_index = 0, msg_index, mlen = -1, len = 0;
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
- if (data == NULL || len < 3)
|
||||
+
|
||||
+ if (data == NULL || data_len <= 0 || data_len > n || n < SC_PKCS1_PADDING_MIN_SIZE)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
|
||||
|
||||
- /* skip leading zero byte */
|
||||
- if (*data == 0) {
|
||||
- data++;
|
||||
- len--;
|
||||
+ msg = msg_orig = calloc(n, sizeof(u8));
|
||||
+ if (msg == NULL)
|
||||
+ LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
|
||||
+
|
||||
+ /*
|
||||
+ * We can not check length of input data straight away and still we need to read
|
||||
+ * from input even when the input is not as long as needed to keep the time constant.
|
||||
+ * If data has wrong size, it is padded by zeroes from left and the following checks
|
||||
+ * do not pass.
|
||||
+ */
|
||||
+ len = data_len;
|
||||
+ for (data += len, msg += n, i = 0; i < n; i++) {
|
||||
+ mask = ~constant_time_is_zero(len);
|
||||
+ len -= 1 & mask;
|
||||
+ data -= 1 & mask;
|
||||
+ *--msg = *data & mask;
|
||||
+ }
|
||||
+ // check first byte to be 0x00
|
||||
+ good = constant_time_is_zero(msg[0]);
|
||||
+ // check second byte to be 0x02
|
||||
+ good &= constant_time_eq(msg[1], 2);
|
||||
+
|
||||
+ // find zero byte after random data in padding
|
||||
+ found_zero_byte = 0;
|
||||
+ for (i = 2; i < n; i++) {
|
||||
+ unsigned int equals0 = constant_time_is_zero(msg[i]);
|
||||
+ zero_index = constant_time_select(~found_zero_byte & equals0, i, zero_index);
|
||||
+ found_zero_byte |= equals0;
|
||||
}
|
||||
- if (data[0] != 0x02)
|
||||
- LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_PADDING);
|
||||
- /* skip over padding bytes */
|
||||
- for (n = 1; n < len && data[n]; n++)
|
||||
- ;
|
||||
- /* Must be at least 8 pad bytes */
|
||||
- if (n >= len || n < 9)
|
||||
- LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_PADDING);
|
||||
- n++;
|
||||
- if (out == NULL)
|
||||
- /* just check the padding */
|
||||
- LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
|
||||
- /* Now move decrypted contents to head of buffer */
|
||||
- if (*out_len < len - n)
|
||||
- LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
|
||||
- *out_len = len - n;
|
||||
- memmove(out, data + n, *out_len);
|
||||
+ // zero_index stands for index of last found zero
|
||||
+ good &= constant_time_ge(zero_index, 2 + 8);
|
||||
+
|
||||
+ // start of the actual message in data
|
||||
+ msg_index = zero_index + 1;
|
||||
+
|
||||
+ // length of message
|
||||
+ mlen = data_len - msg_index;
|
||||
+
|
||||
+ // check that message fits into out buffer
|
||||
+ good &= constant_time_ge(*out_len, mlen);
|
||||
+
|
||||
+ // move the result in-place by |num|-SC_PKCS1_PADDING_MIN_SIZE-|mlen| bytes to the left.
|
||||
+ *out_len = constant_time_select(constant_time_lt(n - SC_PKCS1_PADDING_MIN_SIZE, *out_len),
|
||||
+ n - SC_PKCS1_PADDING_MIN_SIZE, *out_len);
|
||||
+ for (msg_index = 1; msg_index < n - SC_PKCS1_PADDING_MIN_SIZE; msg_index <<= 1) {
|
||||
+ mask = ~constant_time_eq(msg_index & (n - SC_PKCS1_PADDING_MIN_SIZE - mlen), 0);
|
||||
+ for (i = SC_PKCS1_PADDING_MIN_SIZE; i < n - msg_index; i++)
|
||||
+ msg[i] = constant_time_select_8(mask, msg[i + msg_index], msg[i]);
|
||||
+ }
|
||||
+ // move message into out buffer, if good
|
||||
+ for (i = 0; i < *out_len; i++) {
|
||||
+ unsigned int msg_index;
|
||||
+ // when out is longer than message in data, use some bogus index in msg
|
||||
+ mask = good & constant_time_lt(i, mlen);
|
||||
+ msg_index = constant_time_select(mask, i + SC_PKCS1_PADDING_MIN_SIZE, 0); // to now overflow msg buffer
|
||||
+ out[i] = constant_time_select_8(mask, msg[msg_index], out[i]);
|
||||
+ }
|
||||
|
||||
- sc_log(ctx, "stripped output(%"SC_FORMAT_LEN_SIZE_T"u): %s", len - n,
|
||||
- sc_dump_hex(out, len - n));
|
||||
- LOG_FUNC_RETURN(ctx, len - n);
|
||||
+ free(msg_orig);
|
||||
+ return constant_time_select(good, mlen, SC_ERROR_WRONG_PADDING);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_OPENSSL
|
||||
diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c
|
||||
index 3391994abe..5248d9758a 100644
|
||||
--- a/src/minidriver/minidriver.c
|
||||
+++ b/src/minidriver/minidriver.c
|
||||
@@ -4653,9 +4653,9 @@ DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData,
|
||||
"sc_pkcs15_decipher: DECRYPT-INFO dwVersion=%lu\n",
|
||||
(unsigned long)pInfo->dwVersion);
|
||||
if (pInfo->dwPaddingType == CARD_PADDING_PKCS1) {
|
||||
- size_t temp = pInfo->cbData;
|
||||
+ unsigned int temp = pInfo->cbData;
|
||||
logprintf(pCardData, 2, "sc_pkcs15_decipher: stripping PKCS1 padding\n");
|
||||
- r = sc_pkcs1_strip_02_padding(vs->ctx, pbuf2, pInfo->cbData, pbuf2, &temp);
|
||||
+ r = sc_pkcs1_strip_02_padding_constant_time(vs->ctx, prkey_info->modulus_length / 8, pbuf2, pInfo->cbData, pbuf2, &temp);
|
||||
pInfo->cbData = (DWORD) temp;
|
||||
if (r < 0) {
|
||||
logprintf(pCardData, 2, "Cannot strip PKCS1 padding: %i\n", r);
|
||||
|
||||
diff --git a/src/tests/unittests/Makefile.am b/src/tests/unittests/Makefile.am
|
||||
index 7019ca7ba8..4c73911e48 100644
|
||||
--- a/src/tests/unittests/Makefile.am
|
||||
+++ b/src/tests/unittests/Makefile.am
|
||||
@@ -6,8 +6,10 @@ include $(top_srcdir)/aminclude_static.a
|
||||
clean-local: code-coverage-clean
|
||||
distclean-local: code-coverage-dist-clean
|
||||
|
||||
-noinst_PROGRAMS = asn1 simpletlv cachedir pkcs15filter openpgp-tool hextobin decode_ecdsa_signature
|
||||
-TESTS = asn1 simpletlv cachedir pkcs15filter openpgp-tool hextobin decode_ecdsa_signature
|
||||
+noinst_PROGRAMS = asn1 simpletlv cachedir pkcs15filter openpgp-tool hextobin \
|
||||
+ decode_ecdsa_signature strip_pkcs1_2_padding
|
||||
+TESTS = asn1 simpletlv cachedir pkcs15filter openpgp-tool hextobin \
|
||||
+ decode_ecdsa_signature strip_pkcs1_2_padding
|
||||
|
||||
noinst_HEADERS = torture.h
|
||||
|
||||
@@ -28,6 +30,7 @@ pkcs15filter_SOURCES = pkcs15-emulator-f
|
||||
openpgp_tool_SOURCES = openpgp-tool.c $(top_builddir)/src/tools/openpgp-tool-helpers.c
|
||||
hextobin_SOURCES = hextobin.c
|
||||
decode_ecdsa_signature_SOURCES = decode_ecdsa_signature.c
|
||||
+strip_pkcs1_2_paddingSOURCES = strip_pkcs1_2_padding.c
|
||||
|
||||
if ENABLE_ZLIB
|
||||
noinst_PROGRAMS += compression
|
||||
diff --git a/src/tests/unittests/Makefile.mak b/src/tests/unittests/Makefile.mak
|
||||
index 2607546f57..6284b51af9 100644
|
||||
--- a/src/tests/unittests/Makefile.mak
|
||||
+++ b/src/tests/unittests/Makefile.mak
|
||||
@@ -1,10 +1,11 @@
|
||||
TOPDIR = ..\..\..
|
||||
|
||||
-TARGETS = asn1 compression pkcs15filter
|
||||
+TARGETS = asn1 compression pkcs15filter strip_pkcs1_2_padding
|
||||
|
||||
OBJECTS = asn1.obj \
|
||||
compression.obj \
|
||||
- pkcs15-emulator-filter.obj
|
||||
+ pkcs15-emulator-filter.obj \
|
||||
+ strip_pkcs1_2_padding.obj \
|
||||
$(TOPDIR)\win32\versioninfo.res
|
||||
|
||||
all: $(TARGETS)
|
||||
diff --git a/src/tests/unittests/strip_pkcs1_2_padding.c b/src/tests/unittests/strip_pkcs1_2_padding.c
|
||||
new file mode 100644
|
||||
index 0000000000..f9561b936d
|
||||
--- /dev/null
|
||||
+++ b/src/tests/unittests/strip_pkcs1_2_padding.c
|
||||
@@ -0,0 +1,204 @@
|
||||
+#include "common/compat_strlcpy.c"
|
||||
+#include "libopensc/log.c"
|
||||
+#include "libopensc/padding.c"
|
||||
+#include "torture.h"
|
||||
+#include <cmocka.h>
|
||||
+
|
||||
+static void
|
||||
+torture_long_output_buffer(void **state)
|
||||
+{
|
||||
+ unsigned int n = 14;
|
||||
+ unsigned int in_len = 14;
|
||||
+ unsigned char in[] = {0x00, 0x02,
|
||||
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
||||
+ 0x00,
|
||||
+ 'm', 's', 'g'};
|
||||
+ unsigned int out_len = 3;
|
||||
+ unsigned char *out = calloc(out_len, sizeof(unsigned char));
|
||||
+ unsigned char result_msg[] = {'m', 's', 'g'};
|
||||
+ int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
|
||||
+ assert_int_equal(r, 3);
|
||||
+ assert_memory_equal(out, result_msg, r);
|
||||
+ free(out);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+torture_short_output_buffer(void **state)
|
||||
+{
|
||||
+ unsigned int n = 14;
|
||||
+ unsigned int in_len = 14;
|
||||
+ unsigned char in[] = {0x00, 0x02,
|
||||
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
||||
+ 0x00,
|
||||
+ 'm', 's', 'g'};
|
||||
+ unsigned int out_len = 1;
|
||||
+ unsigned char *out = calloc(out_len, sizeof(unsigned char));
|
||||
+ int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
|
||||
+ assert_int_equal(r, SC_ERROR_WRONG_PADDING);
|
||||
+ free(out);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+torture_short_message_correct_padding(void **state)
|
||||
+{
|
||||
+ unsigned int n = 14;
|
||||
+ unsigned int in_len = 14;
|
||||
+ unsigned char in[] = {0x00, 0x02,
|
||||
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
||||
+ 0x00,
|
||||
+ 'm', 's', 'g'};
|
||||
+ unsigned int out_len = 3;
|
||||
+ unsigned char *out = calloc(out_len, sizeof(unsigned char));
|
||||
+ unsigned char result_msg[] = {'m', 's', 'g'};
|
||||
+ int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
|
||||
+ assert_int_equal(r, 3);
|
||||
+ assert_memory_equal(out, result_msg, r);
|
||||
+ free(out);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+torture_missing_first_zero(void **state)
|
||||
+{
|
||||
+ unsigned int n = 13;
|
||||
+ unsigned int in_len = 13;
|
||||
+ unsigned char in[] = {0x02,
|
||||
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
||||
+ 0x00,
|
||||
+ 'm', 's', 'g'};
|
||||
+ unsigned int out_len = 10;
|
||||
+ unsigned char *out = calloc(out_len, sizeof(unsigned char));
|
||||
+ int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
|
||||
+ assert_int_equal(r, SC_ERROR_WRONG_PADDING);
|
||||
+ free(out);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+torture_missing_two(void **state)
|
||||
+{
|
||||
+ unsigned int n = 13;
|
||||
+ unsigned int in_len = 13;
|
||||
+ unsigned char in[] = {0x00,
|
||||
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
||||
+ 0x00,
|
||||
+ 'm', 's', 'g'};
|
||||
+ unsigned int out_len = 10;
|
||||
+ unsigned char *out = calloc(out_len, sizeof(unsigned char));
|
||||
+ int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
|
||||
+ assert_int_equal(r, SC_ERROR_WRONG_PADDING);
|
||||
+ free(out);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+torture_short_padding(void **state)
|
||||
+{
|
||||
+ unsigned int n = 13;
|
||||
+ unsigned int in_len = 13;
|
||||
+ unsigned char in[] = {0x00, 0x02,
|
||||
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
+ 0x00,
|
||||
+ 'm', 's', 'g'};
|
||||
+ unsigned int out_len = 10;
|
||||
+ unsigned char *out = calloc(out_len, sizeof(unsigned char));
|
||||
+ int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
|
||||
+ assert_int_equal(r, SC_ERROR_WRONG_PADDING);
|
||||
+ free(out);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+torture_missing_second_zero(void **state)
|
||||
+{
|
||||
+ unsigned int n = 13;
|
||||
+ unsigned int in_len = 13;
|
||||
+ unsigned char in[] = {0x00, 0x02,
|
||||
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
||||
+ 'm', 's', 'g'};
|
||||
+ unsigned int out_len = 10;
|
||||
+ unsigned char *out = calloc(out_len, sizeof(unsigned char));
|
||||
+ int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
|
||||
+ assert_int_equal(r, SC_ERROR_WRONG_PADDING);
|
||||
+ free(out);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+torture_missing_message(void **state)
|
||||
+{
|
||||
+ unsigned int n = 20;
|
||||
+ unsigned int in_len = 11;
|
||||
+ unsigned char in[] = {0x00, 0x02,
|
||||
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
||||
+ 0x00};
|
||||
+ unsigned int out_len = 11;
|
||||
+ unsigned char *out = calloc(out_len, sizeof(unsigned char));
|
||||
+ int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
|
||||
+ assert_int_equal(r, SC_ERROR_WRONG_PADDING);
|
||||
+ free(out);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+torture_one_byte_message(void **state)
|
||||
+{
|
||||
+ unsigned int n = 12;
|
||||
+ unsigned int in_len = 12;
|
||||
+ unsigned char in[] = {0x00, 0x02,
|
||||
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
||||
+ 0x00,
|
||||
+ 'm'};
|
||||
+ unsigned int out_len = 1;
|
||||
+ unsigned char *out = calloc(out_len, sizeof(unsigned char));
|
||||
+ unsigned char result_msg[] = {'m'};
|
||||
+ int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
|
||||
+ assert_int_equal(r, 1);
|
||||
+ assert_memory_equal(out, result_msg, r);
|
||||
+ free(out);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+torture_longer_padding(void **state)
|
||||
+{
|
||||
+ unsigned int n = 26;
|
||||
+ unsigned int in_len = 26;
|
||||
+ unsigned char in[] = {0x00, 0x02,
|
||||
+ 0x0e, 0x38, 0x97, 0x18, 0x16, 0x57, 0x9e, 0x30, 0xb6, 0xa5, 0x78, 0x13, 0x20, 0xca, 0x11,
|
||||
+ 0x00,
|
||||
+ 0x9d, 0x98, 0x3d, 0xca, 0xa9, 0xa7, 0x11, 0x0a};
|
||||
+ unsigned int out_len = 8;
|
||||
+ unsigned char *out = calloc(out_len, sizeof(unsigned char));
|
||||
+ unsigned char result_msg[] = {0x9d, 0x98, 0x3d, 0xca, 0xa9, 0xa7, 0x11, 0x0a};
|
||||
+ int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
|
||||
+ assert_int_equal(r, 8);
|
||||
+ assert_memory_equal(out, result_msg, r);
|
||||
+ free(out);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+torture_empty_message(void **state)
|
||||
+{
|
||||
+ unsigned int n = 18;
|
||||
+ unsigned int in_len = 18;
|
||||
+ unsigned char in[] = {0x00, 0x02,
|
||||
+ 0x0e, 0x38, 0x97, 0x18, 0x16, 0x57, 0x9e, 0x30, 0xb6, 0xa5, 0x78, 0x13, 0x20, 0xca, 0x11,
|
||||
+ 0x00};
|
||||
+ unsigned int out_len = 8;
|
||||
+ unsigned char *out = calloc(out_len, sizeof(unsigned char));
|
||||
+ int r = sc_pkcs1_strip_02_padding_constant_time(NULL, n, in, in_len, out, &out_len);
|
||||
+ assert_int_equal(r, 0);
|
||||
+ free(out);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+main(void)
|
||||
+{
|
||||
+ const struct CMUnitTest tests[] = {
|
||||
+ cmocka_unit_test(torture_long_output_buffer),
|
||||
+ cmocka_unit_test(torture_short_output_buffer),
|
||||
+ cmocka_unit_test(torture_short_message_correct_padding),
|
||||
+ cmocka_unit_test(torture_missing_first_zero),
|
||||
+ cmocka_unit_test(torture_missing_two),
|
||||
+ cmocka_unit_test(torture_short_padding),
|
||||
+ cmocka_unit_test(torture_missing_second_zero),
|
||||
+ cmocka_unit_test(torture_missing_message),
|
||||
+ cmocka_unit_test(torture_one_byte_message),
|
||||
+ cmocka_unit_test(torture_longer_padding),
|
||||
+ cmocka_unit_test(torture_empty_message)};
|
||||
+ return cmocka_run_group_tests(tests, NULL, NULL);
|
||||
+}
|
||||
|
||||
diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c
|
||||
index a019af460f..f7ee819d65 100644
|
||||
--- a/src/libopensc/pkcs15-sec.c
|
||||
+++ b/src/libopensc/pkcs15-sec.c
|
||||
@@ -308,9 +308,10 @@ int sc_pkcs15_decipher(struct sc_pkcs15_
|
||||
|
||||
/* Strip any padding */
|
||||
if (pad_flags & SC_ALGORITHM_RSA_PAD_PKCS1) {
|
||||
- size_t s = r;
|
||||
- r = sc_pkcs1_strip_02_padding(ctx, out, s, out, &s);
|
||||
- LOG_TEST_RET(ctx, r, "Invalid PKCS#1 padding");
|
||||
+ unsigned int s = r;
|
||||
+ unsigned int key_size = (unsigned int)alg_info->key_length;
|
||||
+ r = sc_pkcs1_strip_02_padding_constant_time(ctx, key_size / 8, out, s, out, &s);
|
||||
+ /* for keeping PKCS#1 v1.5 depadding constant-time, do not log error here */
|
||||
}
|
||||
#ifdef ENABLE_OPENSSL
|
||||
if (pad_flags & SC_ALGORITHM_RSA_PAD_OAEP)
|
||||
@@ -332,7 +333,8 @@ int sc_pkcs15_decipher(struct sc_pkcs15_
|
||||
LOG_TEST_RET(ctx, r, "Invalid OAEP padding");
|
||||
}
|
||||
#endif
|
||||
- LOG_FUNC_RETURN(ctx, r);
|
||||
+ /* do not log error code to prevent side channel attack */
|
||||
+ return r;
|
||||
}
|
||||
|
||||
/* derive one key from another. RSA can use decipher, so this is for only ECDH
|
||||
|
||||
diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c
|
||||
index f75a3dbaec..632681df63 100644
|
||||
--- a/src/pkcs11/framework-pkcs15.c
|
||||
+++ b/src/pkcs11/framework-pkcs15.c
|
||||
@@ -18,6 +18,7 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
+#include "common/constant-time.h"
|
||||
#include "config.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -4395,7 +4396,8 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_se
|
||||
struct pkcs15_fw_data *fw_data = NULL;
|
||||
struct pkcs15_prkey_object *prkey;
|
||||
unsigned char decrypted[512]; /* FIXME: Will not work for keys above 4096 bits */
|
||||
- int buff_too_small, rv, flags = 0, prkey_has_path = 0;
|
||||
+ int rv, flags = 0, prkey_has_path = 0;
|
||||
+ CK_ULONG mask, good, rv_pkcs11;
|
||||
|
||||
if (pulDataLen == NULL) {
|
||||
/* This is call from the C_DecyptInit function */
|
||||
@@ -4484,27 +4486,53 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_se
|
||||
rv = sc_pkcs15_decipher(fw_data->p15_card, prkey->prv_p15obj, flags,
|
||||
pEncryptedData, ulEncryptedDataLen, decrypted, sizeof(decrypted), pMechanism);
|
||||
|
||||
- if (rv < 0 && !sc_pkcs11_conf.lock_login && !prkey_has_path)
|
||||
+ /* skip for PKCS#1 v1.5 padding prevent side channel attack */
|
||||
+ if (!(flags & SC_ALGORITHM_RSA_PAD_PKCS1) &&
|
||||
+ rv < 0 && !sc_pkcs11_conf.lock_login && !prkey_has_path)
|
||||
if (reselect_app_df(fw_data->p15_card) == SC_SUCCESS)
|
||||
rv = sc_pkcs15_decipher(fw_data->p15_card, prkey->prv_p15obj, flags,
|
||||
pEncryptedData, ulEncryptedDataLen, decrypted, sizeof(decrypted), pMechanism);
|
||||
|
||||
sc_unlock(p11card->card);
|
||||
|
||||
- sc_log(context, "Decryption complete. Result %d.", rv);
|
||||
+ sc_log(context, "Decryption complete.");
|
||||
|
||||
- if (rv < 0)
|
||||
- return sc_to_cryptoki_error(rv, "C_Decrypt");
|
||||
+ /* Handle following code in constant-time
|
||||
+ * to prevent Marvin attack for PKCS#1 v1.5 padding. */
|
||||
|
||||
- buff_too_small = (*pulDataLen < (CK_ULONG)rv);
|
||||
- *pulDataLen = rv;
|
||||
- if (pData == NULL_PTR)
|
||||
- return CKR_OK;
|
||||
- if (buff_too_small)
|
||||
- return CKR_BUFFER_TOO_SMALL;
|
||||
- memcpy(pData, decrypted, *pulDataLen);
|
||||
+ /* only padding error must be handled in constant-time way,
|
||||
+ * other error can be returned straight away */
|
||||
+ if ((~constant_time_eq_i(rv, SC_ERROR_WRONG_PADDING) & constant_time_lt_s(sizeof(decrypted), (size_t)rv)))
|
||||
+ return sc_to_cryptoki_error(rv, "C_Decrypt");
|
||||
|
||||
- return CKR_OK;
|
||||
+ /* check rv for padding error */
|
||||
+ good = ~constant_time_eq_i(rv, SC_ERROR_WRONG_PADDING);
|
||||
+ rv_pkcs11 = sc_to_cryptoki_error(SC_ERROR_WRONG_PADDING, "C_Decrypt");
|
||||
+ rv_pkcs11 = constant_time_select_s(good, CKR_OK, rv_pkcs11);
|
||||
+
|
||||
+ if (pData == NULL_PTR) {
|
||||
+ /* set length only if no error */
|
||||
+ *pulDataLen = constant_time_select_s(good, rv, *pulDataLen);
|
||||
+ /* return error only if original rv < 0 */
|
||||
+ return rv_pkcs11;
|
||||
+ }
|
||||
+
|
||||
+ /* check whether *pulDataLen < rv and set return value for small output buffer */
|
||||
+ mask = good & constant_time_lt_s(*pulDataLen, rv);
|
||||
+ rv_pkcs11 = constant_time_select_s(mask, CKR_BUFFER_TOO_SMALL, rv_pkcs11);
|
||||
+ good &= ~mask;
|
||||
+
|
||||
+ /* move everything from decrypted into out buffer constant-time, if rv is ok */
|
||||
+ for (CK_ULONG i = 0; i < *pulDataLen; i++) { /* iterate over whole pData to not disclose real depadded length */
|
||||
+ CK_ULONG msg_index;
|
||||
+ mask = good & constant_time_lt_s(i, sizeof(decrypted)); /* i should be in the bounds of decrypted */
|
||||
+ mask &= constant_time_lt_s(i, constant_time_select_s(good, rv, 0)); /* check that is in bounds of depadded message */
|
||||
+ msg_index = constant_time_select_s(mask, i, 0);
|
||||
+ pData[i] = constant_time_select_8(mask, decrypted[msg_index], pData[i]);
|
||||
+ }
|
||||
+ *pulDataLen = constant_time_select_s(good, rv, *pulDataLen);
|
||||
+ /* do not log error code to prevent side channel attack */
|
||||
+ return rv_pkcs11;
|
||||
}
|
||||
|
||||
|
||||
|
||||
diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c
|
||||
index 03495265a4..d3f0434231 100644
|
||||
--- a/src/pkcs11/mechanism.c
|
||||
+++ b/src/pkcs11/mechanism.c
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
+#include "common/constant-time.h"
|
||||
#include "sc-pkcs11.h"
|
||||
|
||||
/* Also used for verification data */
|
||||
@@ -1089,7 +1090,9 @@ sc_pkcs11_decr(struct sc_pkcs11_session
|
||||
rv = op->type->decrypt(op, pEncryptedData, ulEncryptedDataLen,
|
||||
pData, pulDataLen);
|
||||
|
||||
- if (rv != CKR_BUFFER_TOO_SMALL && pData != NULL)
|
||||
+ /* terminate session for any return value except CKR_BUFFER_TOO_SMALL,
|
||||
+ * perform check in time side-channel free way to prevent Marvin attack */
|
||||
+ if (!constant_time_eq_s(rv, CKR_BUFFER_TOO_SMALL) && pData != NULL)
|
||||
session_stop_operation(session, SC_PKCS11_OPERATION_DECRYPT);
|
||||
|
||||
return rv;
|
||||
@@ -1110,10 +1113,12 @@ sc_pkcs11_decr_update(struct sc_pkcs11_s
|
||||
rv = op->type->decrypt_update(op, pEncryptedData, ulEncryptedDataLen,
|
||||
pData, pulDataLen);
|
||||
|
||||
- /* terminate session for any error except CKR_BUFFER_TOO_SMALL */
|
||||
- if (rv != CKR_OK && rv != CKR_BUFFER_TOO_SMALL)
|
||||
+ /* terminate session for any return value except CKR_BUFFER_TOO_SMALL,
|
||||
+ * perform check in time side-channel free way to prevent Marvin attack */
|
||||
+ if (~constant_time_eq_s(rv, CKR_OK) & ~constant_time_eq_s(rv, CKR_BUFFER_TOO_SMALL))
|
||||
session_stop_operation(session, SC_PKCS11_OPERATION_DECRYPT);
|
||||
- LOG_FUNC_RETURN(context, (int)rv);
|
||||
+ /* do not log error code to prevent side channel attack */
|
||||
+ return rv;
|
||||
}
|
||||
|
||||
CK_RV
|
||||
@@ -1530,6 +1535,10 @@ sc_pkcs11_decrypt(sc_pkcs11_operation_t
|
||||
if (pulDataLen)
|
||||
*pulDataLen = ulDataLen;
|
||||
|
||||
+ /* Skip DecryptFinalize for PKCS#1 v1.5 padding to prevent time side-channel leakage */
|
||||
+ if (((CK_MECHANISM_PTR)&operation->mechanism)->mechanism == CKM_RSA_PKCS)
|
||||
+ return rv;
|
||||
+
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
|
||||
|
||||
|
||||
diff --git a/src/pkcs11/pkcs11-object.c b/src/pkcs11/pkcs11-object.c
|
||||
index f04c0b4c56..b023911213 100644
|
||||
--- a/src/pkcs11/pkcs11-object.c
|
||||
+++ b/src/pkcs11/pkcs11-object.c
|
||||
@@ -1034,7 +1034,8 @@ C_Decrypt(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
rv = reset_login_state(session->slot, rv);
|
||||
}
|
||||
|
||||
- SC_LOG_RV("C_Decrypt() = %s", rv);
|
||||
+ /* do not log error code to prevent side channel attack */
|
||||
+ SC_LOG("C_Decrypt()");
|
||||
sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
@@ -1058,7 +1059,8 @@ C_DecryptUpdate(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
rv = sc_pkcs11_decr_update(session, pEncryptedPart, ulEncryptedPartLen,
|
||||
pPart, pulPartLen);
|
||||
|
||||
- SC_LOG_RV("C_DecryptUpdate() = %s", rv);
|
||||
+ /* do not log error code to prevent side channel attack */
|
||||
+ SC_LOG("C_DecryptUpdate()");
|
||||
sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
@@ -1086,7 +1088,8 @@ C_DecryptFinal(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
rv = reset_login_state(session->slot, rv);
|
||||
}
|
||||
|
||||
- SC_LOG_RV("C_DecryptFinal() = %s", rv);
|
||||
+ /* do not log error code to prevent side channel attack */
|
||||
+ SC_LOG("C_DecryptFinal()");
|
||||
sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h
|
||||
index 66dfcdde67..510017ed2a 100644
|
||||
--- a/src/pkcs11/sc-pkcs11.h
|
||||
+++ b/src/pkcs11/sc-pkcs11.h
|
||||
@@ -246,6 +246,11 @@ do {\
|
||||
}\
|
||||
} while(0)
|
||||
|
||||
+#define SC_LOG(fmt) \
|
||||
+ do { \
|
||||
+ sc_log(context, (fmt)); \
|
||||
+ } while (0)
|
||||
+
|
||||
/* Debug virtual slots. S is slot to be highlighted or NULL
|
||||
* C is a comment format string and args It will be preceded by "VSS " */
|
||||
#define DEBUG_VSS(S, ...) do { sc_log(context,"VSS " __VA_ARGS__); _debug_virtual_slots(S); } while (0)
|
||||
|
||||
|
||||
diff --git a/src/pkcs11/misc.c b/src/pkcs11/misc.c
|
||||
index 5ca1176b1d..1d893d6181 100644
|
||||
--- a/src/pkcs11/misc.c
|
||||
+++ b/src/pkcs11/misc.c
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
+#include "common/constant-time.h"
|
||||
#include "sc-pkcs11.h"
|
||||
|
||||
#define DUMP_TEMPLATE_MAX 32
|
||||
@@ -174,7 +175,7 @@ CK_RV reset_login_state(struct sc_pkcs11_slot *slot, CK_RV rv)
|
||||
slot->p11card->framework->logout(slot);
|
||||
}
|
||||
|
||||
- if (rv == CKR_USER_NOT_LOGGED_IN) {
|
||||
+ if (constant_time_eq_s(rv, CKR_USER_NOT_LOGGED_IN)) {
|
||||
slot->login_user = -1;
|
||||
pop_all_login_states(slot);
|
||||
}
|
99
SOURCES/opensc-0.23.0-myeid-sym.patch
Normal file
99
SOURCES/opensc-0.23.0-myeid-sym.patch
Normal file
@ -0,0 +1,99 @@
|
||||
From cde2e050ec4f2f1b7db38429aa4e9c0f4656308c Mon Sep 17 00:00:00 2001
|
||||
From: Peter Popovec <popovec.peter@gmail.com>
|
||||
Date: Wed, 26 Apr 2023 13:22:09 +0200
|
||||
Subject: [PATCH] NULL pointer fix
|
||||
|
||||
Thanks to the clang analyzer:
|
||||
Null pointer passed to 2nd parameter expecting 'nonnull'
|
||||
[clang-analyzer-core.NonNullParamChecker]
|
||||
|
||||
modified: src/libopensc/card-myeid.c
|
||||
---
|
||||
src/libopensc/card-myeid.c | 15 ++++++++++-----
|
||||
1 file changed, 10 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c
|
||||
index 31dd209f3..951c179f1 100644
|
||||
--- a/src/libopensc/card-myeid.c
|
||||
+++ b/src/libopensc/card-myeid.c
|
||||
@@ -1973,6 +1973,9 @@ myeid_enc_dec_sym(struct sc_card *card, const u8 *data, size_t datalen,
|
||||
return_len = block_size - pad_byte;
|
||||
}
|
||||
*outlen = return_len;
|
||||
+ /* application can request buffer size or actual buffer size is too small */
|
||||
+ if (out == NULL)
|
||||
+ LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
if (return_len > *outlen)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_BUFFER_TOO_SMALL);
|
||||
memcpy(out, priv->sym_plain_buffer, return_len);
|
||||
@@ -2042,10 +2045,11 @@ myeid_enc_dec_sym(struct sc_card *card, const u8 *data, size_t datalen,
|
||||
priv->sym_crypt_buffer_len = 0;
|
||||
rest_len = 0;
|
||||
}
|
||||
- memcpy(sdata, data, apdu_datalen);
|
||||
- data += apdu_datalen;
|
||||
- datalen -= apdu_datalen;
|
||||
-
|
||||
+ if (data) {
|
||||
+ memcpy(sdata, data, apdu_datalen);
|
||||
+ data += apdu_datalen;
|
||||
+ datalen -= apdu_datalen;
|
||||
+ }
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
LOG_TEST_RET(ctx, r, "APDU transmit failed");
|
||||
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
@@ -2084,7 +2088,8 @@ myeid_enc_dec_sym(struct sc_card *card, const u8 *data, size_t datalen,
|
||||
/* save rest of data for next run */
|
||||
priv->sym_crypt_buffer_len = datalen;
|
||||
sc_log(ctx, "rest data len = %zu", datalen);
|
||||
- memcpy(priv->sym_crypt_buffer, data, datalen);
|
||||
+ if (data)
|
||||
+ memcpy(priv->sym_crypt_buffer, data, datalen);
|
||||
sc_log(ctx, "return data len = %zu", return_len);
|
||||
*outlen = return_len;
|
||||
return SC_SUCCESS;
|
||||
--
|
||||
2.41.0
|
||||
|
||||
From f1993dc4e0b33050b8f72a3558ee88b24c4063b2 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Popovec <popovec.peter@gmail.com>
|
||||
Date: Tue, 27 Jun 2023 09:50:42 +0200
|
||||
Subject: [PATCH] myeid: fixed CID 380538 Out-of-bounds read (OVERRUN)
|
||||
|
||||
also fixes output buffer size checking
|
||||
---
|
||||
src/libopensc/card-myeid.c | 10 ++++++----
|
||||
1 file changed, 6 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c
|
||||
index 4ee424684..50e78ff1d 100644
|
||||
--- a/src/libopensc/card-myeid.c
|
||||
+++ b/src/libopensc/card-myeid.c
|
||||
@@ -1986,18 +1986,20 @@ myeid_enc_dec_sym(struct sc_card *card, const u8 *data, size_t datalen,
|
||||
sc_log(ctx, "Found padding byte %02x", pad_byte);
|
||||
if (pad_byte == 0 || pad_byte > block_size)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_PADDING);
|
||||
- sdata = priv->sym_plain_buffer + block_size - pad_byte;
|
||||
+ sdata = priv->sym_plain_buffer + block_size;
|
||||
for (i = 0; i < pad_byte; i++)
|
||||
- if (sdata[i] != pad_byte)
|
||||
+ if (*(--sdata) != pad_byte)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_PADDING);
|
||||
return_len = block_size - pad_byte;
|
||||
}
|
||||
- *outlen = return_len;
|
||||
/* application can request buffer size or actual buffer size is too small */
|
||||
- if (out == NULL)
|
||||
+ if (out == NULL) {
|
||||
+ *outlen = return_len;
|
||||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
+ }
|
||||
if (return_len > *outlen)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_BUFFER_TOO_SMALL);
|
||||
+ *outlen = return_len;
|
||||
memcpy(out, priv->sym_plain_buffer, return_len);
|
||||
sc_log(ctx, "C_DecryptFinal %zu bytes", *outlen);
|
||||
return SC_SUCCESS;
|
||||
--
|
||||
2.41.0
|
||||
|
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
|
||||
|
446
SOURCES/opensc-0.23.0-pkcs11-uri.patch
Normal file
446
SOURCES/opensc-0.23.0-pkcs11-uri.patch
Normal file
@ -0,0 +1,446 @@
|
||||
From 700b6e767391fdec3e9ed3865780f6bf7828ac85 Mon Sep 17 00:00:00 2001
|
||||
From: Sergio Arroutbi <sarroutb@redhat.com>
|
||||
Date: Fri, 19 Apr 2024 16:02:13 +0200
|
||||
Subject: [PATCH 1/2] Include uri in pkcs11-tool -L option
|
||||
|
||||
Fixes: #3123
|
||||
|
||||
Signed-off-by: Sergio Arroutbi <sarroutb@redhat.com>
|
||||
---
|
||||
src/tools/pkcs11-tool.c | 66 +++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 66 insertions(+)
|
||||
|
||||
diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c
|
||||
index 5b2abf590c..c165945872 100644
|
||||
--- a/src/tools/pkcs11-tool.c
|
||||
+++ b/src/tools/pkcs11-tool.c
|
||||
@@ -621,6 +621,7 @@ static void generate_random(CK_SESSION_HANDLE session);
|
||||
static CK_RV find_object_with_attributes(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *out,
|
||||
CK_ATTRIBUTE *attrs, CK_ULONG attrsLen, CK_ULONG obj_index);
|
||||
static CK_ULONG get_private_key_length(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE prkey);
|
||||
+static const char *percent_encode(CK_UTF8CHAR *, size_t);
|
||||
|
||||
/* win32 needs this in open(2) */
|
||||
#ifndef O_BINARY
|
||||
@@ -1681,6 +1682,15 @@ static void show_token(CK_SLOT_ID slot)
|
||||
printf(" serial num : %s\n", p11_utf8_to_local(info.serialNumber,
|
||||
sizeof(info.serialNumber)));
|
||||
printf(" pin min/max : %lu/%lu\n", info.ulMinPinLen, info.ulMaxPinLen);
|
||||
+ printf(" uri : pkcs11:model=");
|
||||
+ printf("%s", percent_encode(info.model, sizeof(info.model)));
|
||||
+ printf(";manufacturer=");
|
||||
+ printf("%s", percent_encode(info.manufacturerID, sizeof(info.manufacturerID)));
|
||||
+ printf(";serial=");
|
||||
+ printf("%s", percent_encode(info.serialNumber, sizeof(info.serialNumber)));
|
||||
+ printf(";token=");
|
||||
+ printf("%s", percent_encode(info.label, sizeof(info.label)));
|
||||
+ printf("\n");
|
||||
}
|
||||
|
||||
static void list_mechs(CK_SLOT_ID slot)
|
||||
@@ -8293,6 +8303,62 @@ static const char *p11_utf8_to_local(CK_UTF8CHAR *string, size_t len)
|
||||
return buffer;
|
||||
}
|
||||
|
||||
+static CK_BBOOL
|
||||
+p11_is_percent_format_reserved_char(CK_UTF8CHAR c)
|
||||
+{
|
||||
+ switch (c) {
|
||||
+ case ' ':
|
||||
+ case '!':
|
||||
+ case '"':
|
||||
+ case '#':
|
||||
+ case '$':
|
||||
+ case '%':
|
||||
+ case '&':
|
||||
+ case '\'':
|
||||
+ case '(':
|
||||
+ case ')':
|
||||
+ case '*':
|
||||
+ case '+':
|
||||
+ case ',':
|
||||
+ case '/':
|
||||
+ case ':':
|
||||
+ case ';':
|
||||
+ case '=':
|
||||
+ case '?':
|
||||
+ case '@':
|
||||
+ case '[':
|
||||
+ case ']':
|
||||
+ return CK_TRUE;
|
||||
+ }
|
||||
+ return CK_FALSE;
|
||||
+}
|
||||
+
|
||||
+static const char *
|
||||
+percent_encode(CK_UTF8CHAR *string, size_t len)
|
||||
+{
|
||||
+ static char buffer[1024];
|
||||
+ size_t output_index, input_index;
|
||||
+
|
||||
+ while (len && string[len - 1] == ' ')
|
||||
+ len--;
|
||||
+
|
||||
+ for (output_index = input_index = 0; output_index < sizeof(buffer) - 3;
|
||||
+ output_index++) {
|
||||
+ if (input_index >= len) {
|
||||
+ break;
|
||||
+ }
|
||||
+ if (p11_is_percent_format_reserved_char(string[input_index])) {
|
||||
+ snprintf(&buffer[output_index], 4, "%%%x", string[input_index]);
|
||||
+ output_index += 2;
|
||||
+ } else {
|
||||
+ buffer[output_index] = string[input_index];
|
||||
+ }
|
||||
+ input_index++;
|
||||
+ }
|
||||
+ buffer[output_index] = '\0';
|
||||
+ return buffer;
|
||||
+}
|
||||
+
|
||||
static void p11_fatal(const char *func, CK_RV rv)
|
||||
{
|
||||
if (p11)
|
||||
|
||||
From d9119d0695ea207dca50d651f78ec5fd0a9023ba Mon Sep 17 00:00:00 2001
|
||||
From: Sergio Arroutbi <sarroutb@redhat.com>
|
||||
Date: Thu, 25 Apr 2024 13:42:14 +0200
|
||||
Subject: [PATCH 2/2] Update src/tools/pkcs11-tool.c
|
||||
|
||||
Co-authored-by: Jakub Jelen <jakuje@gmail.com>
|
||||
---
|
||||
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 c165945872..46f8b735e5 100644
|
||||
--- a/src/tools/pkcs11-tool.c
|
||||
+++ b/src/tools/pkcs11-tool.c
|
||||
@@ -1682,8 +1682,8 @@ static void show_token(CK_SLOT_ID slot)
|
||||
printf(" serial num : %s\n", p11_utf8_to_local(info.serialNumber,
|
||||
sizeof(info.serialNumber)));
|
||||
printf(" pin min/max : %lu/%lu\n", info.ulMinPinLen, info.ulMaxPinLen);
|
||||
- printf(" uri : pkcs11:model=");
|
||||
- printf("%s", percent_encode(info.model, sizeof(info.model)));
|
||||
+ printf(" uri : pkcs11:");
|
||||
+ printf("model=%s", percent_encode(info.model, sizeof(info.model)));
|
||||
printf(";manufacturer=");
|
||||
printf("%s", percent_encode(info.manufacturerID, sizeof(info.manufacturerID)));
|
||||
printf(";serial=");
|
||||
|
||||
From 5289269d4a57563bdcd604ec091e6eda0f0547fd Mon Sep 17 00:00:00 2001
|
||||
From: Sergio Arroutbi <sarroutb@redhat.com>
|
||||
Date: Tue, 30 Apr 2024 18:30:16 +0200
|
||||
Subject: [PATCH] Include URIs for PKCS#11 objects
|
||||
|
||||
Fixes: #3129
|
||||
|
||||
Signed-off-by: Sergio Arroutbi <sarroutb@redhat.com>
|
||||
---
|
||||
src/tests/fuzzing/fuzz_pkcs15init.c | 7 +-
|
||||
src/tools/pkcs11-tool.c | 119 ++++++++++++++++++++++------
|
||||
tests/test-pkcs11-tool-test.sh | 20 ++++-
|
||||
3 files changed, 116 insertions(+), 30 deletions(-)
|
||||
|
||||
diff --git a/src/tests/fuzzing/fuzz_pkcs15init.c b/src/tests/fuzzing/fuzz_pkcs15init.c
|
||||
index e44e3aae35..85810ded77 100644
|
||||
--- a/src/tests/fuzzing/fuzz_pkcs15init.c
|
||||
+++ b/src/tests/fuzzing/fuzz_pkcs15init.c
|
||||
@@ -109,7 +109,7 @@ int fuzz_get_reader_data(const uint8_t *from, size_t from_size, const uint8_t **
|
||||
size_t i = 0;
|
||||
while(i < from_size - 1 && from[i] != '\0')
|
||||
i++;
|
||||
-
|
||||
+
|
||||
if (from[i] != '\0')
|
||||
return 0;
|
||||
|
||||
@@ -126,6 +126,7 @@ void do_init_app(struct sc_profile *profile, struct sc_pkcs15_card *p15card, sc_
|
||||
int so_puk_disabled = 0;
|
||||
|
||||
memset(&init_args, 0, sizeof(init_args));
|
||||
+ memset(&info, 0, sizeof(info));
|
||||
sc_pkcs15init_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &info);
|
||||
if ((info.attrs.pin.flags & SC_PKCS15_PIN_FLAG_UNBLOCK_DISABLED) &&
|
||||
(info.attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN))
|
||||
@@ -150,7 +151,7 @@ void do_store_pin(struct sc_profile *profile, struct sc_pkcs15_card *p15card, sc
|
||||
struct sc_pkcs15init_pinargs pin_args;
|
||||
char pin_id[SC_PKCS15_MAX_ID_SIZE] = "1\0";
|
||||
sc_pkcs15init_set_p15card(profile, p15card);
|
||||
-
|
||||
+
|
||||
memcpy(pin, "1234555678\0", 11); /* Set new pin */
|
||||
memset(&pin_args, 0, sizeof(pin_args));
|
||||
|
||||
@@ -363,6 +364,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
if (card)
|
||||
sc_disconnect_card(card);
|
||||
sc_release_context(ctx);
|
||||
-
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c
|
||||
index 46f8b735e5..4e1668290f 100644
|
||||
--- a/src/tools/pkcs11-tool.c
|
||||
+++ b/src/tools/pkcs11-tool.c
|
||||
@@ -1648,6 +1648,43 @@ static void list_slots(int tokens, int refresh, int print)
|
||||
}
|
||||
}
|
||||
|
||||
+static const char *
|
||||
+copy_key_value_to_uri(const char *key, const char *value, CK_BBOOL last)
|
||||
+{
|
||||
+ static char URI[1024];
|
||||
+ static size_t shift = 0;
|
||||
+ if (key && (shift + strlen(key) < sizeof(URI))) {
|
||||
+ strcpy(&URI[shift], key);
|
||||
+ shift += strlen(key);
|
||||
+ }
|
||||
+ if (value && (shift + strlen(value) < sizeof(URI))) {
|
||||
+ strcpy(&URI[shift], value);
|
||||
+ shift += strlen(value);
|
||||
+ }
|
||||
+ if (key && value && !last && shift < sizeof(URI)) {
|
||||
+ URI[shift++] = ';';
|
||||
+ }
|
||||
+ if (last && shift < sizeof(URI)) {
|
||||
+ URI[shift] = '\0';
|
||||
+ shift = 0;
|
||||
+ }
|
||||
+ return URI;
|
||||
+}
|
||||
+
|
||||
+static const char *
|
||||
+get_uri(CK_TOKEN_INFO_PTR info)
|
||||
+{
|
||||
+ copy_key_value_to_uri("pkcs11:", NULL, CK_FALSE);
|
||||
+ const char *model = percent_encode(info->model, sizeof(info->model));
|
||||
+ copy_key_value_to_uri("model=", model, CK_FALSE);
|
||||
+ const char *manufacturer = percent_encode(info->manufacturerID, sizeof(info->manufacturerID));
|
||||
+ copy_key_value_to_uri("manufacturer=", manufacturer, CK_FALSE);
|
||||
+ const char *serial = percent_encode(info->serialNumber, sizeof(info->serialNumber));
|
||||
+ copy_key_value_to_uri("serial=", serial, CK_FALSE);
|
||||
+ const char *token = percent_encode(info->label, sizeof(info->label));
|
||||
+ return copy_key_value_to_uri("token=", token, CK_TRUE);
|
||||
+}
|
||||
+
|
||||
static void show_token(CK_SLOT_ID slot)
|
||||
{
|
||||
CK_TOKEN_INFO info;
|
||||
@@ -1682,14 +1719,7 @@ static void show_token(CK_SLOT_ID slot)
|
||||
printf(" serial num : %s\n", p11_utf8_to_local(info.serialNumber,
|
||||
sizeof(info.serialNumber)));
|
||||
printf(" pin min/max : %lu/%lu\n", info.ulMinPinLen, info.ulMaxPinLen);
|
||||
- printf(" uri : pkcs11:");
|
||||
- printf("model=%s", percent_encode(info.model, sizeof(info.model)));
|
||||
- printf(";manufacturer=");
|
||||
- printf("%s", percent_encode(info.manufacturerID, sizeof(info.manufacturerID)));
|
||||
- printf(";serial=");
|
||||
- printf("%s", percent_encode(info.serialNumber, sizeof(info.serialNumber)));
|
||||
- printf(";token=");
|
||||
- printf("%s", percent_encode(info.label, sizeof(info.label)));
|
||||
+ printf(" uri : %s", get_uri(&info));
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
@@ -5045,13 +5075,14 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj)
|
||||
{
|
||||
CK_MECHANISM_TYPE_PTR mechs = NULL;
|
||||
CK_KEY_TYPE key_type = getKEY_TYPE(sess, obj);
|
||||
- CK_ULONG size = 0;
|
||||
+ CK_ULONG size, idsize = 0;
|
||||
unsigned char *id, *oid, *value;
|
||||
const char *sepa;
|
||||
char *label;
|
||||
char *unique_id;
|
||||
int pub = 1;
|
||||
int sec = 0;
|
||||
+ CK_TOKEN_INFO info;
|
||||
|
||||
switch(getCLASS(sess, obj)) {
|
||||
case CKO_PRIVATE_KEY:
|
||||
@@ -5243,17 +5274,15 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj)
|
||||
|
||||
if ((label = getLABEL(sess, obj, NULL)) != NULL) {
|
||||
printf(" label: %s\n", label);
|
||||
- free(label);
|
||||
}
|
||||
|
||||
- if ((id = getID(sess, obj, &size)) != NULL && size) {
|
||||
+ if ((id = getID(sess, obj, &idsize)) != NULL && idsize) {
|
||||
unsigned int n;
|
||||
|
||||
printf(" ID: ");
|
||||
- for (n = 0; n < size; n++)
|
||||
+ for (n = 0; n < idsize; n++)
|
||||
printf("%02x", id[n]);
|
||||
printf("\n");
|
||||
- free(id);
|
||||
}
|
||||
|
||||
printf(" Usage: ");
|
||||
@@ -5355,7 +5384,26 @@ show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj)
|
||||
printf(" Unique ID: %s\n", unique_id);
|
||||
free(unique_id);
|
||||
}
|
||||
-
|
||||
+ get_token_info(opt_slot, &info);
|
||||
+ printf(" uri: %s", get_uri(&info));
|
||||
+ if (id != NULL && idsize) {
|
||||
+ printf(";id=%%");
|
||||
+ for (unsigned int n = 0; n < idsize; n++)
|
||||
+ printf("%02x", id[n]);
|
||||
+ free(id);
|
||||
+ }
|
||||
+ if (label != NULL) {
|
||||
+ const char *pelabel = percent_encode((unsigned char *)label, strlen(label));
|
||||
+ printf(";object=%s", pelabel);
|
||||
+ free(label);
|
||||
+ }
|
||||
+ if (sec) {
|
||||
+ printf(";type=secret-key\n");
|
||||
+ } else if (pub) {
|
||||
+ printf(";type=public\n");
|
||||
+ } else {
|
||||
+ printf(";type=private\n");
|
||||
+ }
|
||||
suppress_warn = 0;
|
||||
}
|
||||
|
||||
@@ -5363,6 +5411,7 @@ static void show_cert(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj)
|
||||
{
|
||||
CK_CERTIFICATE_TYPE cert_type = getCERTIFICATE_TYPE(sess, obj);
|
||||
CK_ULONG size;
|
||||
+ CK_TOKEN_INFO info;
|
||||
unsigned char *id;
|
||||
char *label;
|
||||
char *unique_id;
|
||||
@@ -5389,7 +5438,6 @@ static void show_cert(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj)
|
||||
|
||||
if ((label = getLABEL(sess, obj, NULL)) != NULL) {
|
||||
printf(" label: %s\n", label);
|
||||
- free(label);
|
||||
}
|
||||
|
||||
#if defined(ENABLE_OPENSSL)
|
||||
@@ -5433,37 +5481,49 @@ static void show_cert(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj)
|
||||
for (n = 0; n < size; n++)
|
||||
printf("%02x", id[n]);
|
||||
printf("\n");
|
||||
- free(id);
|
||||
}
|
||||
if ((unique_id = getUNIQUE_ID(sess, obj, NULL)) != NULL) {
|
||||
printf(" Unique ID: %s\n", unique_id);
|
||||
free(unique_id);
|
||||
}
|
||||
+ get_token_info(opt_slot, &info);
|
||||
+ printf(" uri: %s", get_uri(&info));
|
||||
+ if (id != NULL && size) {
|
||||
+ printf(";id=%%");
|
||||
+ for (unsigned int n = 0; n < size; n++)
|
||||
+ printf("%02x", id[n]);
|
||||
+ free(id);
|
||||
+ }
|
||||
+ if (label != NULL) {
|
||||
+ const char *pelabel = percent_encode((unsigned char *)label, strlen(label));
|
||||
+ printf(";object=%s", pelabel);
|
||||
+ free(label);
|
||||
+ }
|
||||
+ printf(";type=cert\n");
|
||||
}
|
||||
|
||||
static void show_dobj(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj)
|
||||
{
|
||||
unsigned char *oid_buf;
|
||||
char *label;
|
||||
+ char *application;
|
||||
CK_ULONG size = 0;
|
||||
+ CK_TOKEN_INFO info;
|
||||
|
||||
suppress_warn = 1;
|
||||
printf("Data object %u\n", (unsigned int) obj);
|
||||
printf(" label: ");
|
||||
if ((label = getLABEL(sess, obj, NULL)) != NULL) {
|
||||
printf("'%s'\n", label);
|
||||
- free(label);
|
||||
- }
|
||||
- else {
|
||||
+ } else {
|
||||
printf("<empty>\n");
|
||||
}
|
||||
|
||||
printf(" application: ");
|
||||
- if ((label = getAPPLICATION(sess, obj, NULL)) != NULL) {
|
||||
- printf("'%s'\n", label);
|
||||
- free(label);
|
||||
- }
|
||||
- else {
|
||||
+ if ((application = getAPPLICATION(sess, obj, NULL)) != NULL) {
|
||||
+ printf("'%s'\n", application);
|
||||
+ free(application);
|
||||
+ } else {
|
||||
printf("<empty>\n");
|
||||
}
|
||||
|
||||
@@ -5494,8 +5554,16 @@ static void show_dobj(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj)
|
||||
printf(" private");
|
||||
if (!getMODIFIABLE(sess, obj) && !getPRIVATE(sess, obj))
|
||||
printf("<empty>");
|
||||
+ printf("\n");
|
||||
|
||||
- printf ("\n");
|
||||
+ get_token_info(opt_slot, &info);
|
||||
+ printf(" uri: %s", get_uri(&info));
|
||||
+ if (label != NULL) {
|
||||
+ const char *pelabel = percent_encode((unsigned char *)label, strlen(label));
|
||||
+ printf(";object=%s", pelabel);
|
||||
+ free(label);
|
||||
+ }
|
||||
+ printf(";type=data\n");
|
||||
suppress_warn = 0;
|
||||
}
|
||||
|
||||
@@ -8337,6 +8405,7 @@ static const char *
|
||||
percent_encode(CK_UTF8CHAR *string, size_t len)
|
||||
{
|
||||
static char buffer[1024];
|
||||
+ memset(buffer, 0, 1024);
|
||||
size_t output_index, input_index;
|
||||
|
||||
while (len && string[len - 1] == ' ')
|
||||
diff --git a/tests/test-pkcs11-tool-test.sh b/tests/test-pkcs11-tool-test.sh
|
||||
index 2a1f43b8bc..1a96cbd754 100755
|
||||
--- a/tests/test-pkcs11-tool-test.sh
|
||||
+++ b/tests/test-pkcs11-tool-test.sh
|
||||
@@ -20,12 +20,28 @@ assert $? "Failed to set up card"
|
||||
echo "======================================================="
|
||||
echo "Test"
|
||||
echo "======================================================="
|
||||
-$PKCS11_TOOL --test -p $PIN --module $P11LIB
|
||||
+$PKCS11_TOOL --test -p "${PIN}" --module "${P11LIB}"
|
||||
assert $? "Failed running tests"
|
||||
|
||||
+echo "======================================================="
|
||||
+echo "Test objects URI"
|
||||
+echo "======================================================="
|
||||
+$PKCS11_TOOL -O 2>/dev/null | grep 'uri:' 2>/dev/null >/dev/null
|
||||
+assert $? "Failed running objects URI tests"
|
||||
+$PKCS11_TOOL -O 2>/dev/null | grep 'uri:' | awk -F 'uri:' '{print $2}' | tr -d ' ' | grep ^"pkcs11:" 2>/dev/null >/dev/null
|
||||
+assert $? "Failed running objects URI tests"
|
||||
+
|
||||
+echo "======================================================="
|
||||
+echo "Test slots URI"
|
||||
+echo "======================================================="
|
||||
+$PKCS11_TOOL -L 2>/dev/null | grep 'uri' 2>/dev/null >/dev/null
|
||||
+assert $? "Failed running slots URI tests"
|
||||
+$PKCS11_TOOL -O 2>/dev/null | grep 'uri' | awk -F 'uri*:' '{print $2}' | tr -d ' ' | grep ^"pkcs11:" 2>/dev/null >/dev/null
|
||||
+assert $? "Failed running slots URI tests"
|
||||
+
|
||||
echo "======================================================="
|
||||
echo "Cleanup"
|
||||
echo "======================================================="
|
||||
card_cleanup
|
||||
|
||||
-exit $ERRORS
|
||||
+exit "${ERRORS}"
|
1016
SOURCES/opensc-0.23.0-pkcs15init.patch
Normal file
1016
SOURCES/opensc-0.23.0-pkcs15init.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -3,7 +3,7 @@
|
||||
|
||||
Name: opensc
|
||||
Version: 0.23.0
|
||||
Release: 2%{?dist}
|
||||
Release: 5%{?dist}
|
||||
Summary: Smart card library and applications
|
||||
|
||||
License: LGPLv2+
|
||||
@ -23,6 +23,42 @@ Patch10: %{name}-0.23.0-openssl-ctx.patch
|
||||
Patch11: %{name}-0.23.0-openpgp.patch
|
||||
# https://github.com/OpenSC/OpenSC/commit/81944d1529202bd28359bede57c0a15deb65ba8a
|
||||
Patch12: %{name}-0.23.0-cardos-pkcs15init.patch
|
||||
# https://github.com/OpenSC/OpenSC/commit/bff98ff078a99e6864ba1a598fd7dc9af4a9476b
|
||||
# https://github.com/OpenSC/OpenSC/commit/0875c69295ef28b45fb682b37cede58fc36b7a1a
|
||||
Patch13: %{name}-0.23.0-cache-offsets.patch
|
||||
# https://github.com/OpenSC/OpenSC/commit/868f76fb31255fd3fdacfc3e476452efeb61c3e7
|
||||
# https://github.com/OpenSC/OpenSC/commit/80cc5d30635f0d2c92b5099c0f9dc680d0ffce2f
|
||||
Patch14: %{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/4013a807492568bf9907cfb3df41f130ac83c7b9
|
||||
# https://github.com/OpenSC/OpenSC/commit/09164045facaeae193feb48d9c2fc5cc4321e8a
|
||||
# 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
|
||||
# https://github.com/OpenSC/OpenSC/commit/5f6370a35f151497838628f78111087eb8e7ff1
|
||||
# https://github.com/OpenSC/OpenSC/commit/fbff25ec6c6d0ad3f8df76f57210698f7947fc3
|
||||
Patch15: %{name}-0.23.0-pkcs15init.patch
|
||||
# https://github.com/OpenSC/OpenSC/commit/cde2e050ec4f2f1b7db38429aa4e9c0f4656308c
|
||||
# https://github.com/OpenSC/OpenSC/commit/f1993dc4e0b33050b8f72a3558ee88b24c4063b2
|
||||
Patch16: %{name}-0.23.0-myeid-sym.patch
|
||||
# https://github.com/OpenSC/OpenSC/pull/2948
|
||||
# https://github.com/OpenSC/OpenSC/pull/3016
|
||||
Patch17: %{name}-0.23.0-constant-time-pkcs1.5.patch
|
||||
# https://github.com/OpenSC/OpenSC/pull/3125
|
||||
# https://github.com/OpenSC/OpenSC/pull/3130
|
||||
Patch18: %{name}-0.23.0-pkcs11-uri.patch
|
||||
|
||||
BuildRequires: make
|
||||
BuildRequires: pcsc-lite-devel
|
||||
@ -66,6 +102,12 @@ every software/card that does so, too.
|
||||
%patch10 -p1 -b .ossl3context
|
||||
%patch11 -p1 -b .openpgp
|
||||
%patch12 -p1 -b .cardos-pkcs15init
|
||||
%patch13 -p1 -b .cache-offsets
|
||||
%patch14 -p1 -b .pin-bypass
|
||||
%patch15 -p1 -b .pkcs15init
|
||||
%patch16 -p1 -b .myeid-sym
|
||||
%patch17 -p1 -b .constant-time-pkcs1
|
||||
%patch18 -p1 -b .pkcs11-uri
|
||||
|
||||
cp -p src/pkcs15init/README ./README.pkcs15init
|
||||
cp -p src/scconf/README.scconf .
|
||||
@ -207,6 +249,19 @@ rm %{buildroot}%{_mandir}/man1/opensc-notify.1*
|
||||
|
||||
|
||||
%changelog
|
||||
* Thu Oct 24 2024 Veronika Hanulikova <vhanulik@redhat.com> - 0.23.0-5
|
||||
- Add URI in PKCS#11 objects and pkcs11-tool (RHEL-53115)
|
||||
|
||||
* Thu Feb 08 2024 Veronika Hanulikova <vhanulik@redhat.com> - 0.23.0-4
|
||||
- Fix CVE-2023-5992: Side-channel leaks while stripping encryption PKCS#1.5 padding
|
||||
|
||||
* Thu Nov 30 2023 Jakub Jelen <jjelen@redhat.com> - 0.23.0-3
|
||||
- Fix file caching with different offsets (RHEL-4079)
|
||||
- Fix CVE-2023-40660: Potential PIN bypass
|
||||
- Fix CVE-2023-40661: Dynamic analyzers reports in pkcs15init
|
||||
- Fix CVE-2023-4535: Out-of-bounds read in MyEID driver handling encryption using symmetric keys
|
||||
- Fix CVE-2023-5992: Side-channel leaks while stripping encryption PKCS#1.5 padding
|
||||
|
||||
* 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
|
||||
|
Loading…
Reference in New Issue
Block a user