!43 openEuler-22.03-LTS-Next: fix CVE-2021-42782

From: @hugel 
Reviewed-by: @overweight 
Signed-off-by: @overweight
This commit is contained in:
openeuler-ci-bot 2022-05-10 01:19:45 +00:00 committed by Gitee
commit 23184c3b37
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
6 changed files with 314 additions and 7 deletions

View File

@ -0,0 +1,25 @@
From 78cdab949f098ad7e593d853229fccf57d749d0c Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Mon, 30 Nov 2020 17:43:03 +0100
Subject: [PATCH] tcos: prevent out of bounds read
Thanks oss-fuzz
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=27719
---
src/libopensc/pkcs15-tcos.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/libopensc/pkcs15-tcos.c b/src/libopensc/pkcs15-tcos.c
index 60de1470eb..1134ac11ba 100644
--- a/src/libopensc/pkcs15-tcos.c
+++ b/src/libopensc/pkcs15-tcos.c
@@ -152,7 +152,7 @@ static int insert_key(
sc_log(ctx, "No EF_KEYD-Record found\n");
return 1;
}
- for (i = 0; i < r; i += 2 + buf[i + 1]) {
+ for (i = 0; i + 1 < r; i += 2 + buf[i + 1]) {
if (buf[i] == 0xB6)
can_sign++;
if (buf[i] == 0xB8)

View File

@ -0,0 +1,26 @@
From 7114fb71b54ddfe06ce5dfdab013f4c38f129d14 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Wed, 24 Mar 2021 10:57:27 +0100
Subject: [PATCH] coolkey: Initialize potentially uninitialized memory
Thanks oss-fuzz
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28855
---
src/libopensc/pkcs15-coolkey.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/libopensc/pkcs15-coolkey.c b/src/libopensc/pkcs15-coolkey.c
index 373ec7a5a9..586475ddee 100644
--- a/src/libopensc/pkcs15-coolkey.c
+++ b/src/libopensc/pkcs15-coolkey.c
@@ -425,7 +425,8 @@ coolkey_get_public_key_from_certificate(sc_pkcs15_card_t *p15card, sc_cardctl_co
sc_pkcs15_pubkey_t *key = NULL;
int r;
- cert_info.value.value = NULL;
+ memset(&cert_info, 0, sizeof(cert_info));
+
r = coolkey_get_certificate(p15card->card, obj, &cert_info.value);
if (r < 0) {
goto fail;

View File

@ -0,0 +1,26 @@
From ae1cf0be90396fb6c0be95829bf0d3eecbd2fd1c Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Thu, 11 Feb 2021 11:22:54 +0100
Subject: [PATCH] iasecc: Prevent stack buffer overflow when empty ACL is
returned
Thanks oss-fuzz
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=30800
---
src/libopensc/card-iasecc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c
index 166bc307bc..0eec63363a 100644
--- a/src/libopensc/card-iasecc.c
+++ b/src/libopensc/card-iasecc.c
@@ -1171,7 +1171,7 @@ iasecc_process_fci(struct sc_card *card, struct sc_file *file,
else
acls = sc_asn1_find_tag(ctx, buf, buflen, IASECC_DOCP_TAG_ACLS_CONTACT, &taglen);
- if (!acls) {
+ if (!acls || taglen < 7) {
sc_log(ctx,
"ACLs not found in data(%"SC_FORMAT_LEN_SIZE_T"u) %s",
buflen, sc_dump_hex(buf, buflen));

View File

@ -0,0 +1,223 @@
From 456ac566938a1da774db06126a2fa6c0cba514b3 Mon Sep 17 00:00:00 2001
From: Doug Engert <deengert@gmail.com>
Date: Wed, 14 Jul 2021 11:15:10 -0500
Subject: [PATCH] PIV Improved parsing of data from the card
Based on Fuzz testing, many of the calls to sc_asn1_find_tag were replaced
with sc_asn1_read_tag. The input is also tested that the
expected tag is the first byte. Additional tests are also add.
sc_asn1_find_tag will skip 0X00 or 0Xff if found. NIST sp800-73-x specs
do not allow these extra bytes.
On branch PIV-improved-parsing
Changes to be committed:
modified: card-piv.c
---
src/libopensc/card-piv.c | 112 +++++++++++++++++++++------------------
1 file changed, 60 insertions(+), 52 deletions(-)
diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c
index f144b2ccef..77e4864f66 100644
--- a/src/libopensc/card-piv.c
+++ b/src/libopensc/card-piv.c
@@ -608,14 +608,12 @@ static int piv_generate_key(sc_card_t *card,
const u8 *cp;
keydata->exponent = 0;
- /* expected tag is 7f49. */
- /* we will whatever tag is present */
-
cp = rbuf;
in_len = r;
+ /* expected tag is 0x7f49,returned as cla_out == 0x60 and tag_out = 0x1F49 */
r = sc_asn1_read_tag(&cp, in_len, &cla_out, &tag_out, &in_len);
- if (cp == NULL) {
+ if (cp == NULL || in_len == 0 || cla_out != 0x60 || tag_out != 0x1f49) {
r = SC_ERROR_ASN1_OBJECT_NOT_FOUND;
}
if (r != SC_SUCCESS) {
@@ -1032,7 +1030,7 @@ piv_cache_internal_data(sc_card_t *card, int enumtag)
priv->obj_cache[enumtag].obj_len,
0x53, &bodylen);
- if (body == NULL)
+ if (body == NULL || priv->obj_cache[enumtag].obj_data[0] != 0x53)
LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_VALID);
/* get the certificate out */
@@ -1611,7 +1609,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card,
/* Remove the encompassing outer TLV of 0x7C and get the data */
body = sc_asn1_find_tag(card->ctx, rbuf,
r, 0x7C, &body_len);
- if (!body) {
+ if (!body || rbuf[0] != 0x7C) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid Witness Data response of NULL\n");
r = SC_ERROR_INVALID_DATA;
goto err;
@@ -1753,7 +1751,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card,
/* Remove the encompassing outer TLV of 0x7C and get the data */
body = sc_asn1_find_tag(card->ctx, rbuf,
r, 0x7C, &body_len);
- if(!body) {
+ if(!body || rbuf[0] != 0x7C) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not find outer tag 0x7C in response");
r = SC_ERROR_INVALID_DATA;
goto err;
@@ -1914,7 +1912,7 @@ static int piv_general_external_authenticate(sc_card_t *card,
/* Remove the encompassing outer TLV of 0x7C and get the data */
body = sc_asn1_find_tag(card->ctx, rbuf,
r, 0x7C, &body_len);
- if (!body) {
+ if (!body || rbuf[0] != 0x7C) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid Challenge Data response of NULL\n");
r = SC_ERROR_INVALID_DATA;
goto err;
@@ -2079,7 +2077,7 @@ piv_get_serial_nr_from_CHUI(sc_card_t* card, sc_serial_number_t* serial)
r = SC_ERROR_INTERNAL;
if (rbuflen != 0) {
body = sc_asn1_find_tag(card->ctx, rbuf, rbuflen, 0x53, &bodylen); /* Pass the outer wrapper asn1 */
- if (body != NULL && bodylen != 0) {
+ if (body != NULL && bodylen != 0 && rbuf[0] == 0x53) {
fascn = sc_asn1_find_tag(card->ctx, body, bodylen, 0x30, &fascnlen); /* Find the FASC-N data */
guid = sc_asn1_find_tag(card->ctx, body, bodylen, 0x34, &guidlen);
@@ -2311,10 +2309,10 @@ static int piv_validate_general_authentication(sc_card_t *card,
piv_private_data_t * priv = PIV_DATA(card);
int r, tmplen, tmplen2;
u8 *p;
- const u8 *tag;
+ const unsigned char *p2;
size_t taglen;
- const u8 *body;
size_t bodylen;
+ unsigned int cla, tag;
unsigned int real_alg_id, op_tag;
u8 sbuf[4096]; /* needs work. for 3072 keys, needs 384+10 or so */
@@ -2367,20 +2365,28 @@ static int piv_validate_general_authentication(sc_card_t *card,
r = piv_general_io(card, 0x87, real_alg_id, priv->key_ref,
sbuf, p - sbuf, rbuf, sizeof rbuf);
+ if (r < 0)
+ goto err;
- if (r >= 0) {
- body = sc_asn1_find_tag(card->ctx, rbuf, r, 0x7c, &bodylen);
- if (body) {
- tag = sc_asn1_find_tag(card->ctx, body, bodylen, 0x82, &taglen);
- if (tag) {
- memcpy(out, tag, taglen);
- r = taglen;
- } else
- r = SC_ERROR_INVALID_DATA;
- } else
- r = SC_ERROR_INVALID_DATA;
+ p2 = rbuf;
+ r = sc_asn1_read_tag(&p2, r, &cla, &tag, &bodylen);
+ if (p2 == NULL || r < 0 || bodylen == 0 || (cla|tag) != 0x7C) {
+ LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find 0x7C");
+ }
+
+ r = sc_asn1_read_tag(&p2, bodylen, &cla, &tag, &taglen);
+ if (p2 == NULL || r < 0 || taglen == 0 || (cla|tag) != 0x82) {
+ LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find 0x82");
}
+ if (taglen > outlen) {
+ LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "data read longer then buffer");
+ }
+
+ memcpy(out, p2, taglen);
+ r = taglen;
+
+err:
LOG_FUNC_RETURN(card->ctx, r);
}
@@ -2394,19 +2400,19 @@ piv_compute_signature(sc_card_t *card, const u8 * data, size_t datalen,
int i;
size_t nLen;
u8 rbuf[128]; /* For EC conversions 384 will fit */
- const u8 * body;
- size_t bodylen;
- const u8 * tag;
- size_t taglen;
+ const unsigned char *pseq, *pint, *ptemp, *pend;
+ unsigned int cla, tag;
+ size_t seqlen;
+ size_t intlen;
+ size_t templen;
SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
/* The PIV returns a DER SEQUENCE{INTEGER, INTEGER}
- * Which may have leading 00 to force positive
- * TODO: -DEE should check if PKCS15 want the same
- * But PKCS11 just wants 2* filed_length in bytes
+ * Which may have leading 00 to force a positive integer
+ * But PKCS11 just wants 2* field_length in bytes
* So we have to strip out the integers
- * if present and pad on left if too short.
+ * and pad on left if too short.
*/
if (priv->alg_id == 0x11 || priv->alg_id == 0x14 ) {
@@ -2424,32 +2430,34 @@ piv_compute_signature(sc_card_t *card, const u8 * data, size_t datalen,
if (r < 0)
goto err;
- body = sc_asn1_find_tag(card->ctx, rbuf, r, 0x30, &bodylen);
-
- for (i = 0; i<2; i++) {
- if (body) {
- tag = sc_asn1_find_tag(card->ctx, body, bodylen, 0x02, &taglen);
- if (tag) {
- bodylen -= taglen - (tag - body);
- body = tag + taglen;
-
- if (taglen > nLen) { /* drop leading 00 if present */
- if (*tag != 0x00) {
- r = SC_ERROR_INVALID_DATA;
- goto err;
- }
- tag++;
- taglen--;
- }
- memcpy(out + nLen*i + nLen - taglen , tag, taglen);
- } else {
+ pseq = rbuf;
+ r = sc_asn1_read_tag(&pseq, r, &cla, &tag, &seqlen);
+ if (pseq == NULL || r < 0 || seqlen == 0 || (cla|tag) != 0x30)
+ LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find 0x30");
+
+ pint = pseq;
+ pend = pseq + seqlen;
+ for (i = 0; i < 2; i++) {
+ r = sc_asn1_read_tag(&pint, (pend - pint), &cla, &tag, &intlen);
+ if (pint == NULL || r < 0 || intlen == 0 || (cla|tag) != 0x02)
+ LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find 0x02");
+ if (intlen > nLen + 1)
+ LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA,"Signature too long");
+
+ ptemp = pint;
+ templen = intlen;
+ if (intlen > nLen) { /* drop leading 00 if present */
+ if (*ptemp != 0x00) {
+ LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA,"Signature too long");
r = SC_ERROR_INVALID_DATA;
goto err;
}
- } else {
- r = SC_ERROR_INVALID_DATA;
- goto err;
+ ptemp++;
+ templen--;
}
+ memcpy(out + nLen*i + nLen - templen , ptemp, templen);
+ pint += intlen; /* next integer */
+
}
r = 2 * nLen;
} else { /* RSA is all set */

View File

@ -3,7 +3,7 @@
Name: opensc
Version: 0.21.0
Release: 5
Release: 6
License: LGPLv2.1+
Summary: Smart card library and applications
URL: https://github.com/OpenSC/OpenSC/wiki
@ -27,12 +27,16 @@ Patch6: oberthur-Correctly-check-for-return-values.patch
Patch7: oberthur-Avoid-memory-leaks.patch
Patch8: oberthur-fixed-Heap-buffer-overflow.patch
Patch9: oberthur-One-more-overlooked-buffer-overflow.patch
Patch10: cardos-Correctly-calculate-the-left-bytes-to-avoid-b.patch
Patch11: oberthur-Handle-1B-OIDs.patch
Patch12: Fix-ACLs-support.patch
Patch13: backport-CVE-2021-42778-idprime-Use-temporary.patch
Patch14: backport-tcos-Reformat-insert_pin-for-readability.patch
Patch15: backport-CVE-2021-42780-tcos-Check-bounds-in-insert_pin.patch
Patch10: oberthur-Handle-1B-OIDs.patch
Patch11: Fix-ACLs-support.patch
Patch12: backport-CVE-2021-42778-idprime-Use-temporary.patch
Patch13: backport-tcos-Reformat-insert_pin-for-readability.patch
Patch14: backport-CVE-2021-42780-tcos-Check-bounds-in-insert_pin.patch
Patch15: backport-0001-CVE-2021-42782-tcos-prevent-out-of-bounds-read.patch
Patch16: backport-0002-CVE-2021-42782-coolkey-Initialize-potentially.patch
Patch17: backport-0003-CVE-2021-42782-cardos-Correctly-calculate-the-left.patch
Patch18: backport-0004-CVE-2021-42782-iasecc-Prevent-stack-buffer.patch
Patch19: backport-0005-CVE-2021-42782-PIV-Improved-parsing.patch
%description
OpenSC provides a set of libraries and utilities to work with smart cards.
@ -151,6 +155,9 @@ make check
%{_datadir}/opensc/
%changelog
* Mon May 9 2022 Hugel <gengqihu1@h-partners.com> - 0.21.0-6
- fix CVE-2021-42782
* Mon May 9 2022 Hugel <gengqihu1@h-partners.com> - 0.21.0-5
- fix CVE-2021-42778 CVE-2021-42780