import CS opensc-0.23.0-3.el9_3
This commit is contained in:
parent
7afc0ef384
commit
bc50fc13d0
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1 @@
|
||||
SOURCES/opensc-0.22.0.tar.gz
|
||||
SOURCES/opensc-0.23.0.tar.gz
|
||||
|
@ -1 +1 @@
|
||||
d920880c72462619e0a1a629e0a637155b75a352 SOURCES/opensc-0.22.0.tar.gz
|
||||
5a5367ef33efcc35ed420b191b4d1bc3aa34a538 SOURCES/opensc-0.23.0.tar.gz
|
||||
|
@ -3,7 +3,7 @@ diff -up opensc-0.19.0/etc/opensc.conf.pinpad opensc-0.19.0/etc/opensc.conf
|
||||
+++ opensc-0.19.0/etc/opensc.conf 2018-10-22 14:33:59.939410701 +0200
|
||||
@@ -4,4 +4,9 @@ app default {
|
||||
framework pkcs15 {
|
||||
# use_file_caching = true;
|
||||
# use_file_caching = public;
|
||||
}
|
||||
+ reader_driver pcsc {
|
||||
+ # The pinpad is disabled by default,
|
||||
|
@ -1,62 +0,0 @@
|
||||
From fe198e8b3837aa4c960e75d0e2a41020ad4dc9f9 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Jelen <jjelen@redhat.com>
|
||||
Date: Fri, 24 Sep 2021 13:33:26 +0200
|
||||
Subject: [PATCH 1/9] pkcs11: Unbreak detection of unenrolled cards
|
||||
|
||||
This was broken since 58b03b68, which tried to sanitize some states,
|
||||
but caused C_GetTokenInfo returning CKR_TOKEN_NOT_RECOGNIZED instead
|
||||
of empty token information.
|
||||
|
||||
Note, that this has effect only if the configuration options
|
||||
enable_default_driver and pkcs11_enable_InitToken are turned on.
|
||||
Otherwise it still returns CKR_TOKEN_NOT_RECOGNIZED.
|
||||
---
|
||||
src/pkcs11/framework-pkcs15.c | 17 +++++++++--------
|
||||
1 file changed, 9 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c
|
||||
index 74fe7b3c49..4205e41739 100644
|
||||
--- a/src/pkcs11/framework-pkcs15.c
|
||||
+++ b/src/pkcs11/framework-pkcs15.c
|
||||
@@ -544,9 +544,7 @@ CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
|
||||
{
|
||||
struct sc_pkcs11_slot *slot;
|
||||
struct pkcs15_fw_data *fw_data = NULL;
|
||||
- struct sc_pkcs15_card *p15card = NULL;
|
||||
struct sc_pkcs15_object *auth;
|
||||
- struct sc_pkcs15_auth_info *pin_info;
|
||||
CK_RV rv;
|
||||
|
||||
sc_log(context, "C_GetTokenInfo(%lx)", slotID);
|
||||
@@ -578,12 +576,6 @@ CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
|
||||
rv = sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_GetTokenInfo");
|
||||
goto out;
|
||||
}
|
||||
- p15card = fw_data->p15_card;
|
||||
- if (!p15card) {
|
||||
- rv = sc_to_cryptoki_error(SC_ERROR_INVALID_CARD, "C_GetTokenInfo");
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
/* User PIN flags are cleared before re-calculation */
|
||||
slot->token_info.flags &= ~(CKF_USER_PIN_COUNT_LOW|CKF_USER_PIN_FINAL_TRY|CKF_USER_PIN_LOCKED);
|
||||
auth = slot_data_auth(slot->fw_data);
|
||||
@@ -591,8 +583,17 @@ CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
|
||||
"C_GetTokenInfo() auth. object %p, token-info flags 0x%lX", auth,
|
||||
slot->token_info.flags);
|
||||
if (auth) {
|
||||
+ struct sc_pkcs15_card *p15card = NULL;
|
||||
+ struct sc_pkcs15_auth_info *pin_info = NULL;
|
||||
+
|
||||
pin_info = (struct sc_pkcs15_auth_info*) auth->data;
|
||||
|
||||
+ p15card = fw_data->p15_card;
|
||||
+ if (!p15card) {
|
||||
+ rv = sc_to_cryptoki_error(SC_ERROR_INVALID_CARD, "C_GetTokenInfo");
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
sc_pkcs15_get_pin_info(p15card, auth);
|
||||
|
||||
if (pin_info->tries_left >= 0) {
|
||||
|
@ -5,8 +5,8 @@ diff -up opensc-0.22.0/etc/opensc.conf.file-cache opensc-0.22.0/etc/opensc.conf
|
||||
# debug = 3;
|
||||
# debug_file = opensc-debug.txt;
|
||||
framework pkcs15 {
|
||||
- # use_file_caching = true;
|
||||
+ use_file_caching = true;
|
||||
- # use_file_caching = public;
|
||||
+ use_file_caching = public;
|
||||
}
|
||||
reader_driver pcsc {
|
||||
# The pinpad is disabled by default,
|
||||
@ -18,6 +18,6 @@ diff -up opensc-0.22.0/etc/opensc.conf.file-cache opensc-0.22.0/etc/opensc.conf
|
||||
+# brings more trouble than use so disable that:
|
||||
+app pkcs15-init {
|
||||
+ framework pkcs15 {
|
||||
+ use_file_caching = false;
|
||||
+ use_file_caching = no;
|
||||
+ }
|
||||
+}
|
||||
|
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;
|
||||
}
|
||||
|
||||
|
50
SOURCES/opensc-0.23.0-cardos-pkcs15init.patch
Normal file
50
SOURCES/opensc-0.23.0-cardos-pkcs15init.patch
Normal file
@ -0,0 +1,50 @@
|
||||
From 81944d1529202bd28359bede57c0a15deb65ba8a Mon Sep 17 00:00:00 2001
|
||||
From: fullwaywang <fullwaywang@tencent.com>
|
||||
Date: Mon, 29 May 2023 10:38:48 +0800
|
||||
Subject: [PATCH] pkcs15init: correct left length calculation to fix buffer
|
||||
overrun bug. Fixes #2785
|
||||
|
||||
---
|
||||
src/pkcs15init/pkcs15-cardos.c | 10 +++++-----
|
||||
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/src/pkcs15init/pkcs15-cardos.c b/src/pkcs15init/pkcs15-cardos.c
|
||||
index 9715cf390f..f41f73c349 100644
|
||||
--- a/src/pkcs15init/pkcs15-cardos.c
|
||||
+++ b/src/pkcs15init/pkcs15-cardos.c
|
||||
@@ -872,7 +872,7 @@ static int cardos_have_verifyrc_package(sc_card_t *card)
|
||||
sc_apdu_t apdu;
|
||||
u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
|
||||
int r;
|
||||
- const u8 *p = rbuf, *q;
|
||||
+ const u8 *p = rbuf, *q, *pp;
|
||||
size_t len, tlen = 0, ilen = 0;
|
||||
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0x01, 0x88);
|
||||
@@ -888,13 +888,13 @@ static int cardos_have_verifyrc_package(sc_card_t *card)
|
||||
return 0;
|
||||
|
||||
while (len != 0) {
|
||||
- p = sc_asn1_find_tag(card->ctx, p, len, 0xe1, &tlen);
|
||||
- if (p == NULL)
|
||||
+ pp = sc_asn1_find_tag(card->ctx, p, len, 0xe1, &tlen);
|
||||
+ if (pp == NULL)
|
||||
return 0;
|
||||
if (card->type == SC_CARD_TYPE_CARDOS_M4_3) {
|
||||
/* the verifyRC package on CardOS 4.3B use Manufacturer ID 0x01 */
|
||||
/* and Package Number 0x07 */
|
||||
- q = sc_asn1_find_tag(card->ctx, p, tlen, 0x01, &ilen);
|
||||
+ q = sc_asn1_find_tag(card->ctx, pp, tlen, 0x01, &ilen);
|
||||
if (q == NULL || ilen != 4)
|
||||
return 0;
|
||||
if (q[0] == 0x07)
|
||||
@@ -902,7 +902,7 @@ static int cardos_have_verifyrc_package(sc_card_t *card)
|
||||
} else if (card->type == SC_CARD_TYPE_CARDOS_M4_4) {
|
||||
/* the verifyRC package on CardOS 4.4 use Manufacturer ID 0x03 */
|
||||
/* and Package Number 0x02 */
|
||||
- q = sc_asn1_find_tag(card->ctx, p, tlen, 0x03, &ilen);
|
||||
+ q = sc_asn1_find_tag(card->ctx, pp, tlen, 0x03, &ilen);
|
||||
if (q == NULL || ilen != 4)
|
||||
return 0;
|
||||
if (q[0] == 0x02)
|
||||
|
475
SOURCES/opensc-0.23.0-constant-time-pkcs1.5.patch
Normal file
475
SOURCES/opensc-0.23.0-constant-time-pkcs1.5.patch
Normal file
@ -0,0 +1,475 @@
|
||||
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..f70251f5d6
|
||||
--- /dev/null
|
||||
+++ b/src/common/constant-time.h
|
||||
@@ -0,0 +1,108 @@
|
||||
+/* 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
|
||||
+# define constant_inline __inline__
|
||||
+# 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
|
||||
+
|
||||
+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);
|
||||
+}
|
||||
+
|
||||
+#endif /* CONSTANT_TIME_H */
|
||||
diff --git a/src/libopensc/internal.h b/src/libopensc/internal.h
|
||||
index 74014235ac..13eccfa1a4 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);
|
||||
#ifdef ENABLE_OPENSSL
|
||||
diff --git a/src/libopensc/padding.c b/src/libopensc/padding.c
|
||||
index 2837466992..ceb2a1e219 100644
|
||||
--- a/src/libopensc/padding.c
|
||||
+++ b/src/libopensc/padding.c
|
||||
@@ -33,9 +33,12 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "internal.h"
|
||||
+#include "common/constant-time.h"
|
||||
#include "pkcs11/pkcs11.h"
|
||||
/* TODO doxygen comments */
|
||||
|
||||
+#define SC_PKCS1_PADDING_MIN_SIZE 11
|
||||
+
|
||||
/*
|
||||
* Prefixes for pkcs-v1 signatures
|
||||
*/
|
||||
@@ -184,6 +187,84 @@ sc_pkcs1_strip_02_padding(sc_context_t *ctx, const u8 *data, size_t len, u8 *out
|
||||
LOG_FUNC_RETURN(ctx, len - n);
|
||||
}
|
||||
|
||||
+/* Original source: https://github.com/openssl/openssl/blob/9890cc42daff5e2d0cad01ac4bf78c391f599a6e/crypto/rsa/rsa_pk1.c#L171 */
|
||||
+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)
|
||||
+{
|
||||
+ unsigned int i = 0;
|
||||
+ u8 *msg = 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 || data_len <= 0 || data_len > n || n < SC_PKCS1_PADDING_MIN_SIZE)
|
||||
+ LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
|
||||
+
|
||||
+ msg = 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;
|
||||
+ }
|
||||
+
|
||||
+ // 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 there is a message after padding
|
||||
+ good &= constant_time_ge(mlen, 1);
|
||||
+ // 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]);
|
||||
+ }
|
||||
+
|
||||
+ free(msg);
|
||||
+ return constant_time_select(good, mlen, SC_ERROR_WRONG_PADDING);
|
||||
+}
|
||||
+
|
||||
#ifdef ENABLE_OPENSSL
|
||||
static int mgf1(u8 *mask, size_t len, u8 *seed, size_t seedLen, const EVP_MD *dgst)
|
||||
{
|
||||
diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c
|
||||
index 7c3a39432f..b5e492fe25 100644
|
||||
--- a/src/libopensc/pkcs15-sec.c
|
||||
+++ b/src/libopensc/pkcs15-sec.c
|
||||
@@ -308,9 +308,10 @@ int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card,
|
||||
|
||||
/* 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 = 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,7 @@ int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card,
|
||||
LOG_TEST_RET(ctx, r, "Invalid OAEP padding");
|
||||
}
|
||||
#endif
|
||||
- LOG_FUNC_RETURN(ctx, r);
|
||||
+ 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 809cd72d93..9c75759a08 100644
|
||||
--- a/src/pkcs11/framework-pkcs15.c
|
||||
+++ b/src/pkcs11/framework-pkcs15.c
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "libopensc/cardctl.h"
|
||||
#include "ui/notify.h"
|
||||
#include "common/compat_strnlen.h"
|
||||
+#include "common/constant-time.h"
|
||||
#ifdef ENABLE_OPENSSL
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/crypto.h>
|
||||
@@ -4603,15 +4604,51 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *session, void *obj,
|
||||
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)
|
||||
+ if (!((flags & SC_ALGORITHM_RSA_PAD_PKCS1) && constant_time_eq_s(rv, SC_ERROR_WRONG_PADDING)) &&
|
||||
+ 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);
|
||||
+ /* Handle buffer after PKCS#1 v1.5 depadding constant-time */
|
||||
+ if (flags & SC_ALGORITHM_RSA_PAD_PKCS1) {
|
||||
+ CK_ULONG mask, good, rv_pkcs11;
|
||||
+
|
||||
+ sc_log(context, "Decryption complete.");
|
||||
+ /* only padding error must be handled in constant-time way */
|
||||
+ if ((~constant_time_eq_s(rv, SC_ERROR_WRONG_PADDING) & constant_time_lt_s(sizeof(decrypted), rv)))
|
||||
+ return sc_to_cryptoki_error(rv, "C_Decrypt");
|
||||
+
|
||||
+ /* check rv for error */
|
||||
+ good = ~constant_time_eq_s(rv, SC_ERROR_WRONG_PADDING);
|
||||
+ rv_pkcs11 = constant_time_select_s(good, CKR_OK, SC_ERROR_WRONG_PADDING);
|
||||
+ if (pData == NULL_PTR) {
|
||||
+ /* set length only if rv good */
|
||||
+ *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 accordingly */
|
||||
+ 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, 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);
|
||||
+ return rv_pkcs11;
|
||||
+ }
|
||||
+
|
||||
+ sc_log(context, "Decryption complete. Result %d.", rv);
|
||||
if (rv < 0)
|
||||
return sc_to_cryptoki_error(rv, "C_Decrypt");
|
||||
|
||||
@@ -4622,7 +4659,6 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *session, void *obj,
|
||||
if (buff_too_small)
|
||||
return CKR_BUFFER_TOO_SMALL;
|
||||
memcpy(pData, decrypted, *pulDataLen);
|
||||
-
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c
|
||||
index 03495265a4..95d80249bb 100644
|
||||
--- a/src/pkcs11/mechanism.c
|
||||
+++ b/src/pkcs11/mechanism.c
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "sc-pkcs11.h"
|
||||
+#include "common/constant-time.h"
|
||||
|
||||
/* Also used for verification data */
|
||||
struct hash_signature_info {
|
||||
@@ -1093,7 +1094,8 @@ sc_pkcs11_decr(struct sc_pkcs11_session *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 */
|
||||
+ if (!constant_time_eq_s(rv, CKR_BUFFER_TOO_SMALL) && pData != NULL)
|
||||
session_stop_operation(session, SC_PKCS11_OPERATION_DECRYPT);
|
||||
|
||||
return rv;
|
||||
@@ -1536,6 +1538,13 @@ sc_pkcs11_decrypt(sc_pkcs11_operation_t *operation,
|
||||
if (pulDataLen)
|
||||
*pulDataLen = ulDataLen;
|
||||
|
||||
+ /* No need for DecryptFinalize */
|
||||
+ if (((CK_MECHANISM_PTR) &operation->mechanism)->mechanism == CKM_RSA_PKCS) {
|
||||
+ if (pulDataLen)
|
||||
+ *pulDataLen = ulDataLen;
|
||||
+ return rv;
|
||||
+ }
|
||||
+
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
|
||||
diff --git a/src/pkcs11/misc.c b/src/pkcs11/misc.c
|
||||
index 5ca1176b1d..2893b2bf3e 100644
|
||||
--- a/src/pkcs11/misc.c
|
||||
+++ b/src/pkcs11/misc.c
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "sc-pkcs11.h"
|
||||
+#include "common/constant-time.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);
|
||||
}
|
||||
diff --git a/src/pkcs11/pkcs11-object.c b/src/pkcs11/pkcs11-object.c
|
||||
index f04c0b4c56..93cc319c24 100644
|
||||
--- a/src/pkcs11/pkcs11-object.c
|
||||
+++ b/src/pkcs11/pkcs11-object.c
|
||||
@@ -1034,7 +1034,7 @@ C_Decrypt(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
rv = reset_login_state(session->slot, rv);
|
||||
}
|
||||
|
||||
- SC_LOG_RV("C_Decrypt() = %s", rv);
|
||||
+ SC_LOG("C_Decrypt()");
|
||||
sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h
|
||||
index 66dfcdde67..7239b4c5b8 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/libopensc/padding.c b/src/libopensc/padding.c
|
||||
index ceb2a1e21..c2cc58d47 100644
|
||||
--- a/src/libopensc/padding.c
|
||||
+++ b/src/libopensc/padding.c
|
||||
@@ -192,7 +192,7 @@ 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)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
- u8 *msg = NULL;
|
||||
+ 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);
|
||||
@@ -200,7 +200,7 @@ sc_pkcs1_strip_02_padding_constant_time(sc_context_t *ctx, unsigned int n, const
|
||||
if (data == NULL || data_len <= 0 || data_len > n || n < SC_PKCS1_PADDING_MIN_SIZE)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
|
||||
|
||||
- msg = calloc(n, sizeof(u8));
|
||||
+ msg = msg_orig = calloc(n, sizeof(u8));
|
||||
if (msg == NULL)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
|
||||
|
||||
@@ -261,7 +261,7 @@ sc_pkcs1_strip_02_padding_constant_time(sc_context_t *ctx, unsigned int n, const
|
||||
out[i] = constant_time_select_8(mask, msg[msg_index], out[i]);
|
||||
}
|
||||
|
||||
- free(msg);
|
||||
+ free(msg_orig);
|
||||
return constant_time_select(good, mlen, SC_ERROR_WRONG_PADDING);
|
||||
}
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
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
|
||||
|
225
SOURCES/opensc-0.23.0-openpgp.patch
Normal file
225
SOURCES/opensc-0.23.0-openpgp.patch
Normal file
@ -0,0 +1,225 @@
|
||||
From 3b580b6fff9ac463ecc6e996cfaf573f62749368 Mon Sep 17 00:00:00 2001
|
||||
From: Frank Morgner <frankmorgner@gmail.com>
|
||||
Date: Fri, 14 Apr 2023 12:02:54 +0200
|
||||
Subject: [PATCH 1/2] openpgp: identify OpenPGP compliance with bcd_version
|
||||
rather than card type
|
||||
|
||||
---
|
||||
src/libopensc/card-openpgp.c | 22 +++++++++++++---------
|
||||
1 file changed, 13 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c
|
||||
index fad32f0ce7..2ea5dc9d36 100644
|
||||
--- a/src/libopensc/card-openpgp.c
|
||||
+++ b/src/libopensc/card-openpgp.c
|
||||
@@ -1780,13 +1780,18 @@ pgp_get_pubkey_pem(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len)
|
||||
* p1: number of an instance (DO 7F21: 0x00 for AUT, 0x01 for DEC and 0x02 for SIG)
|
||||
*/
|
||||
static int
|
||||
-pgp_select_data(sc_card_t *card, u8 p1){
|
||||
+pgp_select_data(sc_card_t *card, u8 p1)
|
||||
+{
|
||||
sc_apdu_t apdu;
|
||||
u8 apdu_data[6];
|
||||
int r;
|
||||
+ struct pgp_priv_data *priv = DRVDATA(card);
|
||||
|
||||
LOG_FUNC_CALLED(card->ctx);
|
||||
|
||||
+ if (priv->bcd_version < OPENPGP_CARD_3_0)
|
||||
+ LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
|
||||
+
|
||||
sc_log(card->ctx, "select data with: %u", p1);
|
||||
|
||||
// create apdu data (taken from spec: SELECT DATA 7.2.5.)
|
||||
@@ -2179,8 +2184,7 @@ pgp_set_security_env(sc_card_t *card,
|
||||
/* The SC_SEC_ENV_ALG_PRESENT is set always so let it pass for GNUK */
|
||||
if ((env->flags & SC_SEC_ENV_ALG_PRESENT)
|
||||
&& (env->algorithm != SC_ALGORITHM_RSA)
|
||||
- && (priv->bcd_version < OPENPGP_CARD_3_0)
|
||||
- && (card->type != SC_CARD_TYPE_OPENPGP_GNUK))
|
||||
+ && (priv->bcd_version < OPENPGP_CARD_3_0))
|
||||
LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS,
|
||||
"only RSA algorithm supported");
|
||||
|
||||
@@ -2944,13 +2948,13 @@ pgp_update_card_algorithms(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *ke
|
||||
{
|
||||
sc_algorithm_info_t *algo;
|
||||
u8 id = key_info->key_id;
|
||||
+ struct pgp_priv_data *priv = DRVDATA(card);
|
||||
|
||||
LOG_FUNC_CALLED(card->ctx);
|
||||
|
||||
/* protect incompatible cards against non-RSA */
|
||||
if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA
|
||||
- && card->type < SC_CARD_TYPE_OPENPGP_V3
|
||||
- && card->type != SC_CARD_TYPE_OPENPGP_GNUK)
|
||||
+ && priv->bcd_version < OPENPGP_CARD_3_0)
|
||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
|
||||
|
||||
if (id > card->algorithm_count) {
|
||||
@@ -2992,13 +2996,13 @@ pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info)
|
||||
size_t apdu_le;
|
||||
size_t resplen = 0;
|
||||
int r = SC_SUCCESS;
|
||||
+ struct pgp_priv_data *priv = DRVDATA(card);
|
||||
|
||||
LOG_FUNC_CALLED(card->ctx);
|
||||
|
||||
/* protect incompatible cards against non-RSA */
|
||||
if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA
|
||||
- && card->type < SC_CARD_TYPE_OPENPGP_V3
|
||||
- && card->type != SC_CARD_TYPE_OPENPGP_GNUK)
|
||||
+ && priv->bcd_version < OPENPGP_CARD_3_0)
|
||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
|
||||
if (key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA
|
||||
&& card->type != SC_CARD_TYPE_OPENPGP_GNUK)
|
||||
@@ -3358,13 +3362,13 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info)
|
||||
u8 *data = NULL;
|
||||
size_t len = 0;
|
||||
int r;
|
||||
+ struct pgp_priv_data *priv = DRVDATA(card);
|
||||
|
||||
LOG_FUNC_CALLED(card->ctx);
|
||||
|
||||
/* protect incompatible cards against non-RSA */
|
||||
if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA
|
||||
- && card->type < SC_CARD_TYPE_OPENPGP_V3
|
||||
- && card->type != SC_CARD_TYPE_OPENPGP_GNUK)
|
||||
+ && priv->bcd_version < OPENPGP_CARD_3_0)
|
||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
|
||||
|
||||
/* Validate */
|
||||
|
||||
From 9eccc1494d8303ffe42beb772732df218875e3ac Mon Sep 17 00:00:00 2001
|
||||
From: Frank Morgner <frankmorgner@gmail.com>
|
||||
Date: Fri, 14 Apr 2023 12:09:55 +0200
|
||||
Subject: [PATCH 2/2] openpgp: ignore errors on SELECT DATA for OpenPGP 2 and
|
||||
below
|
||||
|
||||
fixes https://github.com/OpenSC/OpenSC/issues/2752
|
||||
---
|
||||
src/libopensc/pkcs15-openpgp.c | 11 +++--------
|
||||
1 file changed, 3 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/src/libopensc/pkcs15-openpgp.c b/src/libopensc/pkcs15-openpgp.c
|
||||
index e2f3442238..9d3fd746a0 100644
|
||||
--- a/src/libopensc/pkcs15-openpgp.c
|
||||
+++ b/src/libopensc/pkcs15-openpgp.c
|
||||
@@ -556,14 +556,9 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card)
|
||||
memset(&cert_info, 0, sizeof(cert_info));
|
||||
memset(&cert_obj, 0, sizeof(cert_obj));
|
||||
|
||||
- /* only try to SELECT DATA for OpenPGP >= v3 */
|
||||
- if (card->type >= SC_CARD_TYPE_OPENPGP_V3) {
|
||||
- r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_SELECT_DATA, &i);
|
||||
- if (r < 0) {
|
||||
- free(buffer);
|
||||
- LOG_TEST_RET(card->ctx, r, "Failed OpenPGP - select data");
|
||||
- }
|
||||
- }
|
||||
+ /* try to SELECT DATA. Will only work for OpenPGP >= v3, errors are non-critical */
|
||||
+ sc_card_ctl(card, SC_CARDCTL_OPENPGP_SELECT_DATA, &i);
|
||||
+
|
||||
sc_format_path(certs[i].path, &cert_info.path);
|
||||
|
||||
/* Certificate ID. We use the same ID as the authentication key */
|
||||
|
||||
commit e8fba322a2f4d06ec5c74fe80f9e2b0e9fdefec6
|
||||
Author: Jakub Jelen <jjelen@redhat.com>
|
||||
Date: Fri May 19 16:49:00 2023 +0200
|
||||
|
||||
openpgp: Fix fingerprint calculation
|
||||
|
||||
fixes https://github.com/OpenSC/OpenSC/issues/2775
|
||||
|
||||
diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c
|
||||
index cc454cef..496e38e6 100644
|
||||
--- a/src/libopensc/card-openpgp.c
|
||||
+++ b/src/libopensc/card-openpgp.c
|
||||
@@ -2697,15 +2697,23 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime,
|
||||
|
||||
/* RSA */
|
||||
if (key_info->algorithm == SC_OPENPGP_KEYALGO_RSA) {
|
||||
+ unsigned short bytes_length = 0;
|
||||
+
|
||||
*p = 1; /* Algorithm ID, RSA */
|
||||
p += 1;
|
||||
+
|
||||
+ /* Modulus */
|
||||
+ bytes_length = BYTES4BITS(key_info->u.rsa.modulus_len);
|
||||
ushort2bebytes(p, (unsigned short)key_info->u.rsa.modulus_len);
|
||||
p += 2;
|
||||
- memcpy(p, key_info->u.rsa.modulus, (BYTES4BITS(key_info->u.rsa.modulus_len)));
|
||||
- p += (key_info->u.rsa.modulus_len >> 3);
|
||||
- ushort2bebytes(++p, (unsigned short)key_info->u.rsa.exponent_len);
|
||||
+ memcpy(p, key_info->u.rsa.modulus, bytes_length);
|
||||
+ p += bytes_length;
|
||||
+
|
||||
+ /* Exponent */
|
||||
+ bytes_length = BYTES4BITS(key_info->u.rsa.exponent_len);
|
||||
+ ushort2bebytes(p, (unsigned short)key_info->u.rsa.exponent_len);
|
||||
p += 2;
|
||||
- memcpy(p, key_info->u.rsa.exponent, (BYTES4BITS(key_info->u.rsa.exponent_len)));
|
||||
+ memcpy(p, key_info->u.rsa.exponent, bytes_length);
|
||||
}
|
||||
/* ECC */
|
||||
else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH
|
||||
|
||||
commit 891f10e49de1a5ee038b1cb2fb59dce40429e6c2
|
||||
Author: Jakub Jelen <jjelen@redhat.com>
|
||||
Date: Fri May 19 17:53:35 2023 +0200
|
||||
|
||||
openpgp: Fix modulus length calculation in pkc15init layer
|
||||
|
||||
diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h
|
||||
index 5a0a19c5..ba685a30 100644
|
||||
--- a/src/libopensc/pkcs15.h
|
||||
+++ b/src/libopensc/pkcs15.h
|
||||
@@ -373,7 +373,7 @@ struct sc_pkcs15_prkey_info {
|
||||
unsigned int usage, access_flags;
|
||||
int native, key_reference;
|
||||
/* convert to union if other types are supported */
|
||||
- size_t modulus_length; /* RSA */
|
||||
+ size_t modulus_length; /* RSA, in bits */
|
||||
size_t field_length; /* EC in bits */
|
||||
|
||||
unsigned int algo_refs[SC_MAX_SUPPORTED_ALGORITHMS];
|
||||
diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c
|
||||
index c75bcbda..3e060be5 100644
|
||||
--- a/src/pkcs15init/pkcs15-openpgp.c
|
||||
+++ b/src/pkcs15init/pkcs15-openpgp.c
|
||||
@@ -235,7 +235,7 @@ static int openpgp_generate_key_rsa(sc_card_t *card, sc_pkcs15_object_t *obj,
|
||||
|
||||
/* Prepare buffer */
|
||||
key_info.u.rsa.modulus_len = required->modulus_length;
|
||||
- key_info.u.rsa.modulus = calloc(required->modulus_length >> 3, 1);
|
||||
+ key_info.u.rsa.modulus = calloc(BYTES4BITS(required->modulus_length), 1);
|
||||
if (key_info.u.rsa.modulus == NULL)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_ENOUGH_MEMORY);
|
||||
|
||||
@@ -252,18 +252,18 @@ static int openpgp_generate_key_rsa(sc_card_t *card, sc_pkcs15_object_t *obj,
|
||||
|
||||
pubkey->algorithm = SC_ALGORITHM_RSA;
|
||||
sc_log(ctx, "Set output modulus info");
|
||||
- pubkey->u.rsa.modulus.len = key_info.u.rsa.modulus_len;
|
||||
- pubkey->u.rsa.modulus.data = calloc(key_info.u.rsa.modulus_len, 1);
|
||||
+ pubkey->u.rsa.modulus.len = BYTES4BITS(key_info.u.rsa.modulus_len);
|
||||
+ pubkey->u.rsa.modulus.data = calloc(pubkey->u.rsa.modulus.len, 1);
|
||||
if (pubkey->u.rsa.modulus.data == NULL)
|
||||
goto err;
|
||||
- memcpy(pubkey->u.rsa.modulus.data, key_info.u.rsa.modulus, key_info.u.rsa.modulus_len);
|
||||
+ memcpy(pubkey->u.rsa.modulus.data, key_info.u.rsa.modulus, BYTES4BITS(key_info.u.rsa.modulus_len));
|
||||
|
||||
sc_log(ctx, "Set output exponent info");
|
||||
- pubkey->u.rsa.exponent.len = key_info.u.rsa.exponent_len;
|
||||
- pubkey->u.rsa.exponent.data = calloc(BYTES4BITS(key_info.u.rsa.exponent_len), 1);
|
||||
+ pubkey->u.rsa.exponent.len = BYTES4BITS(key_info.u.rsa.exponent_len);
|
||||
+ pubkey->u.rsa.exponent.data = calloc(pubkey->u.rsa.exponent.len, 1);
|
||||
if (pubkey->u.rsa.exponent.data == NULL)
|
||||
goto err;
|
||||
- memcpy(pubkey->u.rsa.exponent.data, key_info.u.rsa.exponent, BYTES4BITS(key_info.u.rsa.exponent_len));
|
||||
+ memcpy(pubkey->u.rsa.exponent.data, key_info.u.rsa.exponent, pubkey->u.rsa.exponent.len);
|
||||
|
||||
err:
|
||||
free(key_info.u.rsa.modulus);
|
3047
SOURCES/opensc-0.23.0-openssl-ctx.patch
Normal file
3047
SOURCES/opensc-0.23.0-openssl-ctx.patch
Normal file
File diff suppressed because it is too large
Load Diff
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
|
||||
|
212
SOURCES/opensc-0.23.0-pkcs11-tool-import.patch
Normal file
212
SOURCES/opensc-0.23.0-pkcs11-tool-import.patch
Normal file
@ -0,0 +1,212 @@
|
||||
From 99f7b82f187ca3512ceae6270c391243d018fdac Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Jelen <jjelen@redhat.com>
|
||||
Date: Thu, 1 Dec 2022 20:08:53 +0100
|
||||
Subject: [PATCH 1/4] pkcs11-tool: Fix private key import
|
||||
|
||||
---
|
||||
src/tools/pkcs11-tool.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c
|
||||
index aae205fe2c..cfee8526d5 100644
|
||||
--- a/src/tools/pkcs11-tool.c
|
||||
+++ b/src/tools/pkcs11-tool.c
|
||||
@@ -3669,13 +3669,13 @@ parse_rsa_pkey(EVP_PKEY *pkey, int private, struct rsakey_info *rsa)
|
||||
RSA_get0_factors(r, &r_p, &r_q);
|
||||
RSA_get0_crt_params(r, &r_dmp1, &r_dmq1, &r_iqmp);
|
||||
#else
|
||||
- if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR1, &r_d) != 1 ||
|
||||
+ if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_D, &r_d) != 1 ||
|
||||
EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR1, &r_p) != 1 ||
|
||||
EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR2, &r_q) != 1 ||
|
||||
EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT1, &r_dmp1) != 1 ||
|
||||
EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT2, &r_dmq1) != 1 ||
|
||||
- EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT3, &r_iqmp) != 1) {
|
||||
util_fatal("OpenSSL error during RSA private key parsing");
|
||||
+ EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_COEFFICIENT1, &r_iqmp) != 1) {
|
||||
}
|
||||
#endif
|
||||
RSA_GET_BN(rsa, private_exponent, r_d);
|
||||
|
||||
From 4a6e1d1dcd18757502027b1c5d2fb2cbaca28407 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Jelen <jjelen@redhat.com>
|
||||
Date: Thu, 1 Dec 2022 20:11:41 +0100
|
||||
Subject: [PATCH 2/4] pkcs11-tool: Log more information on OpenSSL errors
|
||||
|
||||
---
|
||||
src/tools/pkcs11-tool.c | 15 ++++++---------
|
||||
1 file changed, 6 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c
|
||||
index cfee8526d5..f2e6b1dd91 100644
|
||||
--- a/src/tools/pkcs11-tool.c
|
||||
+++ b/src/tools/pkcs11-tool.c
|
||||
@@ -3641,10 +3641,8 @@ parse_rsa_pkey(EVP_PKEY *pkey, int private, struct rsakey_info *rsa)
|
||||
const BIGNUM *r_dmp1, *r_dmq1, *r_iqmp;
|
||||
r = EVP_PKEY_get1_RSA(pkey);
|
||||
if (!r) {
|
||||
- if (private)
|
||||
- util_fatal("OpenSSL error during RSA private key parsing");
|
||||
- else
|
||||
- util_fatal("OpenSSL error during RSA public key parsing");
|
||||
+ util_fatal("OpenSSL error during RSA %s key parsing: %s", private ? "private" : "public",
|
||||
+ ERR_error_string(ERR_peek_last_error(), NULL));
|
||||
}
|
||||
|
||||
RSA_get0_key(r, &r_n, &r_e, NULL);
|
||||
@@ -3654,10 +3652,8 @@ parse_rsa_pkey(EVP_PKEY *pkey, int private, struct rsakey_info *rsa)
|
||||
BIGNUM *r_dmp1 = NULL, *r_dmq1 = NULL, *r_iqmp = NULL;
|
||||
if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_N, &r_n) != 1 ||
|
||||
EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_E, &r_e) != 1) {
|
||||
- if (private)
|
||||
- util_fatal("OpenSSL error during RSA private key parsing");
|
||||
- else
|
||||
- util_fatal("OpenSSL error during RSA public key parsing");
|
||||
+ util_fatal("OpenSSL error during RSA %s key parsing: %s", private ? "private" : "public",
|
||||
+ ERR_error_string(ERR_peek_last_error(), NULL));
|
||||
}
|
||||
#endif
|
||||
RSA_GET_BN(rsa, modulus, r_n);
|
||||
@@ -3674,8 +3670,9 @@ parse_rsa_pkey(EVP_PKEY *pkey, int private, struct rsakey_info *rsa)
|
||||
EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR2, &r_q) != 1 ||
|
||||
EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT1, &r_dmp1) != 1 ||
|
||||
EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT2, &r_dmq1) != 1 ||
|
||||
- util_fatal("OpenSSL error during RSA private key parsing");
|
||||
EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_COEFFICIENT1, &r_iqmp) != 1) {
|
||||
+ util_fatal("OpenSSL error during RSA private key parsing: %s",
|
||||
+ ERR_error_string(ERR_peek_last_error(), NULL));
|
||||
}
|
||||
#endif
|
||||
RSA_GET_BN(rsa, private_exponent, r_d);
|
||||
|
||||
From 267da3e81f1fc23a9ccce1462ab5deb1a4d4aec5 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Jelen <jjelen@redhat.com>
|
||||
Date: Thu, 1 Dec 2022 20:38:31 +0100
|
||||
Subject: [PATCH 3/4] Reproducer for broken pkcs11-tool key import
|
||||
|
||||
---
|
||||
tests/Makefile.am | 10 ++++---
|
||||
tests/test-pkcs11-tool-import.sh | 48 ++++++++++++++++++++++++++++++++
|
||||
2 files changed, 54 insertions(+), 4 deletions(-)
|
||||
create mode 100755 tests/test-pkcs11-tool-import.sh
|
||||
|
||||
diff --git a/tests/Makefile.am b/tests/Makefile.am
|
||||
index d378e2ee00..9d8a24c321 100644
|
||||
--- a/tests/Makefile.am
|
||||
+++ b/tests/Makefile.am
|
||||
@@ -14,8 +14,9 @@ dist_noinst_SCRIPTS = common.sh \
|
||||
test-pkcs11-tool-test-threads.sh \
|
||||
test-pkcs11-tool-sign-verify.sh \
|
||||
test-pkcs11-tool-allowed-mechanisms.sh \
|
||||
- test-pkcs11-tool-sym-crypt-test.sh\
|
||||
- test-pkcs11-tool-unwrap-wrap-test.sh
|
||||
+ test-pkcs11-tool-sym-crypt-test.sh \
|
||||
+ test-pkcs11-tool-unwrap-wrap-test.sh \
|
||||
+ test-pkcs11-tool-import.sh
|
||||
|
||||
.NOTPARALLEL:
|
||||
TESTS = \
|
||||
@@ -25,8 +26,9 @@ TESTS = \
|
||||
test-pkcs11-tool-test.sh \
|
||||
test-pkcs11-tool-test-threads.sh \
|
||||
test-pkcs11-tool-allowed-mechanisms.sh \
|
||||
- test-pkcs11-tool-sym-crypt-test.sh\
|
||||
- test-pkcs11-tool-unwrap-wrap-test.sh
|
||||
+ test-pkcs11-tool-sym-crypt-test.sh \
|
||||
+ test-pkcs11-tool-unwrap-wrap-test.sh \
|
||||
+ test-pkcs11-tool-import.sh
|
||||
XFAIL_TESTS = \
|
||||
test-pkcs11-tool-test-threads.sh \
|
||||
test-pkcs11-tool-test.sh
|
||||
diff --git a/tests/test-pkcs11-tool-import.sh b/tests/test-pkcs11-tool-import.sh
|
||||
new file mode 100755
|
||||
index 0000000000..76ff8e51be
|
||||
--- /dev/null
|
||||
+++ b/tests/test-pkcs11-tool-import.sh
|
||||
@@ -0,0 +1,48 @@
|
||||
+#!/bin/bash
|
||||
+SOURCE_PATH=${SOURCE_PATH:-..}
|
||||
+
|
||||
+source $SOURCE_PATH/tests/common.sh
|
||||
+
|
||||
+echo "======================================================="
|
||||
+echo "Setup SoftHSM"
|
||||
+echo "======================================================="
|
||||
+if [[ ! -f $P11LIB ]]; then
|
||||
+ echo "WARNING: The SoftHSM is not installed. Can not run this test"
|
||||
+ exit 77;
|
||||
+fi
|
||||
+card_setup
|
||||
+
|
||||
+ID="0100"
|
||||
+OPTS=""
|
||||
+for KEYTYPE in "RSA" "EC"; do
|
||||
+ echo "======================================================="
|
||||
+ echo "Generate and import $KEYTYPE keys"
|
||||
+ echo "======================================================="
|
||||
+ if [ "$KEYTYPE" == "RSA" ]; then
|
||||
+ ID="0100"
|
||||
+ elif [ "$KEYTYPE" == "EC" ]; then
|
||||
+ ID="0200"
|
||||
+ OPTS="-pkeyopt ec_paramgen_curve:P-521"
|
||||
+ fi
|
||||
+ openssl genpkey -out "${KEYTYPE}_private.der" -outform DER -algorithm $KEYTYPE $OPTS
|
||||
+ assert $? "Failed to generate private $KEYTYPE key"
|
||||
+ $PKCS11_TOOL --write-object "${KEYTYPE}_private.der" --id "$ID" --type privkey \
|
||||
+ --label "$KEYTYPE" -p "$PIN" --module "$P11LIB"
|
||||
+ assert $? "Failed to write private $KEYTYPE key"
|
||||
+
|
||||
+ openssl pkey -in "${KEYTYPE}_private.der" -out "${KEYTYPE}_public.der" -pubout -inform DER -outform DER
|
||||
+ assert $? "Failed to convert private $KEYTYPE key to public"
|
||||
+ $PKCS11_TOOL --write-object "${KEYTYPE}_public.der" --id "$ID" --type pubkey --label "$KEYTYPE" \
|
||||
+ -p $PIN --module $P11LIB
|
||||
+ assert $? "Failed to write public $KEYTYPE key"
|
||||
+ # certificate import already tested in all other tests
|
||||
+
|
||||
+ rm "${KEYTYPE}_private.der" "${KEYTYPE}_public.der"
|
||||
+done
|
||||
+
|
||||
+echo "======================================================="
|
||||
+echo "Cleanup"
|
||||
+echo "======================================================="
|
||||
+card_cleanup
|
||||
+
|
||||
+exit $ERRORS
|
||||
|
||||
From 63a7bceeca43ece1eee201ef7a974b20b294ba4e Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Jelen <jakuje@gmail.com>
|
||||
Date: Fri, 2 Dec 2022 18:07:43 +0100
|
||||
Subject: [PATCH 4/4] Simplify the new test
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Co-authored-by: Veronika Hanulíková <61348757+xhanulik@users.noreply.github.com>
|
||||
---
|
||||
tests/test-pkcs11-tool-import.sh | 8 +++-----
|
||||
1 file changed, 3 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/tests/test-pkcs11-tool-import.sh b/tests/test-pkcs11-tool-import.sh
|
||||
index 76ff8e51be..c90b3b4926 100755
|
||||
--- a/tests/test-pkcs11-tool-import.sh
|
||||
+++ b/tests/test-pkcs11-tool-import.sh
|
||||
@@ -12,15 +12,13 @@ if [[ ! -f $P11LIB ]]; then
|
||||
fi
|
||||
card_setup
|
||||
|
||||
-ID="0100"
|
||||
-OPTS=""
|
||||
for KEYTYPE in "RSA" "EC"; do
|
||||
echo "======================================================="
|
||||
echo "Generate and import $KEYTYPE keys"
|
||||
echo "======================================================="
|
||||
- if [ "$KEYTYPE" == "RSA" ]; then
|
||||
- ID="0100"
|
||||
- elif [ "$KEYTYPE" == "EC" ]; then
|
||||
+ ID="0100"
|
||||
+ OPTS=""
|
||||
+ if [ "$KEYTYPE" == "EC" ]; then
|
||||
ID="0200"
|
||||
OPTS="-pkeyopt ec_paramgen_curve:P-521"
|
||||
fi
|
||||
|
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
@ -1,33 +0,0 @@
|
||||
commit 6bc05d7037041e543d627248ca9df90723426ce1
|
||||
Author: Jakub Jelen <jjelen@redhat.com>
|
||||
Date: Tue Aug 10 16:30:40 2021 +0200
|
||||
|
||||
p11test: Fix invalid format string on 32b architectures
|
||||
|
||||
diff --git a/src/tests/p11test/p11test.c b/src/tests/p11test/p11test.c
|
||||
index dbac167d..49de6a93 100644
|
||||
--- a/src/tests/p11test/p11test.c
|
||||
+++ b/src/tests/p11test/p11test.c
|
||||
@@ -139,7 +139,7 @@ int main(int argc, char** argv) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
- debug_print("Card info:\n\tPIN %s\n\tPIN LENGTH %lu\n\t",
|
||||
+ debug_print("Card info:\n\tPIN %s\n\tPIN LENGTH %zu\n\t",
|
||||
token.pin, token.pin_length);
|
||||
|
||||
return cmocka_run_group_tests(readonly_tests_without_initialization,
|
||||
diff --git a/src/tests/p11test/p11test_case_pss_oaep.c b/src/tests/p11test/p11test_case_pss_oaep.c
|
||||
index 1d876a5b..5a6ae9d0 100644
|
||||
--- a/src/tests/p11test/p11test_case_pss_oaep.c
|
||||
+++ b/src/tests/p11test/p11test_case_pss_oaep.c
|
||||
@@ -402,7 +402,7 @@ int oaep_encrypt_decrypt_test(test_cert_t *o, token_info_t *info, test_mech_t *m
|
||||
if (message_length < 0) {
|
||||
mech->usage_flags &= ~CKF_DECRYPT;
|
||||
debug_print(" [SKIP %s ] Too small modulus (%ld bits)"
|
||||
- " or too large hash %s (%lu B) for OAEP", o->id_str,
|
||||
+ " or too large hash %s (%zu B) for OAEP", o->id_str,
|
||||
o->bits, get_mechanism_name(mech->hash),
|
||||
get_hash_length(mech->hash));
|
||||
return 0;
|
||||
|
@ -1,16 +0,0 @@
|
||||
diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c
|
||||
index d251495c..e48f3189 100644
|
||||
--- a/src/tools/opensc-explorer.c
|
||||
+++ b/src/tools/opensc-explorer.c
|
||||
@@ -2030,9 +2030,9 @@ static int do_put_data(int argc, char **argv)
|
||||
static int do_apdu(int argc, char **argv)
|
||||
{
|
||||
sc_apdu_t apdu;
|
||||
- u8 buf[SC_MAX_EXT_APDU_BUFFER_SIZE];
|
||||
+ u8 buf[SC_MAX_EXT_APDU_BUFFER_SIZE] = {0};
|
||||
u8 rbuf[SC_MAX_EXT_APDU_BUFFER_SIZE];
|
||||
- size_t len, i;
|
||||
+ size_t len = 0, i;
|
||||
int r;
|
||||
|
||||
if (argc < 1)
|
@ -2,8 +2,8 @@
|
||||
%define nssdb %{_sysconfdir}/pki/nssdb
|
||||
|
||||
Name: opensc
|
||||
Version: 0.22.0
|
||||
Release: 2%{?dist}
|
||||
Version: 0.23.0
|
||||
Release: 3%{?dist}
|
||||
Summary: Smart card library and applications
|
||||
|
||||
License: LGPLv2+
|
||||
@ -11,16 +11,52 @@ URL: https://github.com/OpenSC/OpenSC/wiki
|
||||
Source0: https://github.com/OpenSC/OpenSC/releases/download/%{version}/%{name}-%{version}.tar.gz
|
||||
Source1: opensc.module
|
||||
Patch1: opensc-0.19.0-pinpad.patch
|
||||
# https://github.com/OpenSC/OpenSC/pull/2241/
|
||||
Patch5: %{name}-gcc11.patch
|
||||
# https://github.com/OpenSC/OpenSC/pull/2343
|
||||
Patch7: %{name}-32b-arch.patch
|
||||
# File caching by default (#2000626)
|
||||
Patch8: %{name}-%{version}-file-cache.patch
|
||||
# https://github.com/OpenSC/OpenSC/pull/2414 (#2007029)
|
||||
Patch9: %{name}-%{version}-detect-empty.patch
|
||||
Patch8: %{name}-0.22.0-file-cache.patch
|
||||
# https://github.com/OpenSC/OpenSC/pull/2656
|
||||
Patch9: %{name}-0.23.0-pkcs11-tool-import.patch
|
||||
# https://github.com/OpenSC/OpenSC/pull/2712
|
||||
Patch10: %{name}-0.23.0-openssl-ctx.patch
|
||||
# https://github.com/OpenSC/OpenSC/pull/2753
|
||||
# https://github.com/OpenSC/OpenSC/commit/e8fba322a2f4d06ec5c74fe80f9e2b0e9fdefec6
|
||||
# https://github.com/OpenSC/OpenSC/commit/891f10e49de1a5ee038b1cb2fb59dce40429e6c2
|
||||
Patch11: %{name}-0.23.0-openpgp.patch
|
||||
# https://github.com/OpenSC/OpenSC/commit/81944d1529202bd28359bede57c0a15deb65ba8a
|
||||
Patch12: %{name}-0.23.0-cardos-pkcs15init.patch
|
||||
# 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
|
||||
Patch17: %{name}-0.23.0-constant-time-pkcs1.5.patch
|
||||
|
||||
BuildRequires: make
|
||||
BuildRequires: make
|
||||
BuildRequires: pcsc-lite-devel
|
||||
BuildRequires: readline-devel
|
||||
BuildRequires: openssl-devel
|
||||
@ -31,6 +67,7 @@ BuildRequires: bash-completion
|
||||
BuildRequires: zlib-devel
|
||||
# For tests
|
||||
BuildRequires: libcmocka-devel
|
||||
BuildRequires: vim-common
|
||||
%if ! 0%{?rhel}
|
||||
BuildRequires: softhsm
|
||||
%endif
|
||||
@ -56,10 +93,16 @@ every software/card that does so, too.
|
||||
%prep
|
||||
%setup -q
|
||||
%patch1 -p1 -b .pinpad
|
||||
%patch5 -p1 -b .gcc11
|
||||
%patch7 -p1 -b .32b
|
||||
%patch8 -p1 -b .file-cache
|
||||
%patch9 -p1 -b .detect-empty
|
||||
%patch9 -p1 -b .pkcs11-tool-import
|
||||
%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
|
||||
|
||||
cp -p src/pkcs15init/README ./README.pkcs15init
|
||||
cp -p src/scconf/README.scconf .
|
||||
@ -75,21 +118,19 @@ sed -i -e 's/opensc.conf/opensc-%{_arch}.conf/g' src/libopensc/Makefile.in
|
||||
sed -i -e 's|"/lib /usr/lib\b|"/%{_lib} %{_libdir}|' configure # lib64 rpaths
|
||||
%set_build_flags
|
||||
CFLAGS="$CFLAGS -Wstrict-aliasing=2 -Wno-deprecated-declarations"
|
||||
%configure --disable-static \
|
||||
%configure --disable-static \
|
||||
--disable-autostart-items \
|
||||
--disable-notify \
|
||||
--disable-assert \
|
||||
--enable-pcsc \
|
||||
--enable-cmocka \
|
||||
--enable-sm \
|
||||
--with-pcsc-provider=libpcsclite.so.1
|
||||
--enable-sm
|
||||
%make_build
|
||||
|
||||
|
||||
%check
|
||||
make check
|
||||
|
||||
|
||||
%install
|
||||
%make_install
|
||||
install -Dpm 644 %{SOURCE1} $RPM_BUILD_ROOT%{_datadir}/p11-kit/modules/opensc.module
|
||||
@ -119,9 +160,6 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/libopensc.so
|
||||
# remove the .pc file so we do not confuse users #1673139
|
||||
rm -f $RPM_BUILD_ROOT%{_libdir}/pkgconfig/*.pc
|
||||
rm -f $RPM_BUILD_ROOT%{_libdir}/libsmm-local.so
|
||||
%if 0%{?rhel} && 0%{?rhel} < 7
|
||||
rm -rf %{buildroot}%{_datadir}/bash-completion/
|
||||
%endif
|
||||
|
||||
# the npa-tool builds to nothing since we do not have OpenPACE library
|
||||
rm -rf %{buildroot}%{_bindir}/npa-tool
|
||||
@ -132,7 +170,6 @@ rm -rf %{buildroot}%{_bindir}/pkcs11-register
|
||||
rm -rf %{buildroot}%{_mandir}/man1/pkcs11-register.1*
|
||||
|
||||
# Remove the notification files
|
||||
rm %{buildroot}%{_bindir}/opensc-notify
|
||||
rm %{buildroot}%{_datadir}/applications/org.opensc.notify.desktop
|
||||
rm %{buildroot}%{_mandir}/man1/opensc-notify.1*
|
||||
|
||||
@ -140,9 +177,7 @@ rm %{buildroot}%{_mandir}/man1/opensc-notify.1*
|
||||
%files
|
||||
%doc COPYING NEWS README*
|
||||
|
||||
%if ! 0%{?rhel} || 0%{?rhel} >= 7
|
||||
%{_datadir}/bash-completion/*
|
||||
%endif
|
||||
|
||||
%ifarch %{ix86}
|
||||
%{_mandir}/man5/opensc-%{_arch}.conf.5*
|
||||
@ -209,6 +244,21 @@ rm %{buildroot}%{_mandir}/man1/opensc-notify.1*
|
||||
|
||||
|
||||
%changelog
|
||||
* 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
|
||||
|
||||
* Wed Mar 08 2023 Jakub Jelen <jjelen@redhat.com> - 0.23.0-1
|
||||
- Rebase to latest 0.23.0 release (#2100409)
|
||||
- Use separate OpenSSL context to work better from inside of OpenSSL providers
|
||||
|
||||
* Fri Oct 08 2021 Jakub Jelen <jjelen@redhat.com> - 0.22.0-2
|
||||
- Unbreak detection of unentrolled smart cards (#2007029)
|
||||
- Enable file caching by default except for pkcs15-init (#2000626)
|
||||
|
Loading…
Reference in New Issue
Block a user