fix CVE-2021-42782
This commit is contained in:
parent
4c0e7903e4
commit
a863078a17
@ -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)
|
||||
@ -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;
|
||||
@ -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));
|
||||
223
backport-0005-CVE-2021-42782-PIV-Improved-parsing.patch
Normal file
223
backport-0005-CVE-2021-42782-PIV-Improved-parsing.patch
Normal 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;
|
||||
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;
|
||||
|
||||
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 */
|
||||
378
backport-simplify-PIV-IO.patch
Normal file
378
backport-simplify-PIV-IO.patch
Normal file
@ -0,0 +1,378 @@
|
||||
From cfd5519b981c1aeb8f150a13b0f116fb281c8782 Mon Sep 17 00:00:00 2001
|
||||
From: Frank Morgner <frankmorgner@gmail.com>
|
||||
Date: Tue, 17 Sep 2019 15:15:30 +0200
|
||||
Subject: [PATCH] simplify PIV I/O
|
||||
|
||||
---
|
||||
src/libopensc/card-piv.c | 126 +++++++++++----------------------------
|
||||
1 file changed, 34 insertions(+), 92 deletions(-)
|
||||
|
||||
diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c
|
||||
index 7098e64ecf..6e5e116699 100644
|
||||
--- a/src/libopensc/card-piv.c
|
||||
+++ b/src/libopensc/card-piv.c
|
||||
@@ -513,34 +513,17 @@ put_tag_and_len(unsigned int tag, size_t len, u8 **ptr)
|
||||
* Used by GET DATA, PUT DATA, GENERAL AUTHENTICATE
|
||||
* and GENERATE ASYMMETRIC KEY PAIR.
|
||||
* GET DATA may call to get the first 128 bytes to get the length from the tag.
|
||||
- *
|
||||
- * A caller may provide a buffer, and length to read. If not provided,
|
||||
- * an internal 4096 byte buffer is used, and a copy is returned to the
|
||||
- * caller. that need to be freed by the caller.
|
||||
*/
|
||||
|
||||
static int piv_general_io(sc_card_t *card, int ins, int p1, int p2,
|
||||
- const u8 * sendbuf, size_t sendbuflen, u8 ** recvbuf,
|
||||
- size_t * recvbuflen)
|
||||
+ const u8 * sendbuf, size_t sendbuflen, u8 *recvbuf,
|
||||
+ size_t recvbuflen)
|
||||
{
|
||||
int r;
|
||||
sc_apdu_t apdu;
|
||||
- u8 rbufinitbuf[4096];
|
||||
- u8 *rbuf;
|
||||
- size_t rbuflen;
|
||||
-
|
||||
|
||||
SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
|
||||
|
||||
- rbuf = rbufinitbuf;
|
||||
- rbuflen = sizeof(rbufinitbuf);
|
||||
-
|
||||
- /* if caller provided a buffer and length */
|
||||
- if (recvbuf && *recvbuf && recvbuflen && *recvbuflen) {
|
||||
- rbuf = *recvbuf;
|
||||
- rbuflen = *recvbuflen;
|
||||
- }
|
||||
-
|
||||
r = sc_lock(card);
|
||||
if (r != SC_SUCCESS)
|
||||
LOG_FUNC_RETURN(card->ctx, r);
|
||||
@@ -553,15 +536,14 @@ static int piv_general_io(sc_card_t *card, int ins, int p1, int p2,
|
||||
apdu.datalen = sendbuflen;
|
||||
apdu.data = sendbuf;
|
||||
|
||||
- if (recvbuf) {
|
||||
- apdu.resp = rbuf;
|
||||
- apdu.le = (rbuflen > 256) ? 256 : rbuflen;
|
||||
- apdu.resplen = rbuflen;
|
||||
+ if (recvbuf && recvbuflen) {
|
||||
+ apdu.le = (recvbuflen > 256) ? 256 : recvbuflen;
|
||||
+ apdu.resplen = recvbuflen;
|
||||
} else {
|
||||
- apdu.resp = rbuf;
|
||||
apdu.le = 0;
|
||||
apdu.resplen = 0;
|
||||
}
|
||||
+ apdu.resp = recvbuf;
|
||||
|
||||
/* with new adpu.c and chaining, this actually reads the whole object */
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
@@ -578,18 +560,7 @@ static int piv_general_io(sc_card_t *card, int ins, int p1, int p2,
|
||||
goto err;
|
||||
}
|
||||
|
||||
- if (recvbuflen) {
|
||||
- if (recvbuf && *recvbuf == NULL) {
|
||||
- *recvbuf = malloc(apdu.resplen);
|
||||
- if (*recvbuf == NULL) {
|
||||
- r = SC_ERROR_OUT_OF_MEMORY;
|
||||
- goto err;
|
||||
- }
|
||||
- memcpy(*recvbuf, rbuf, apdu.resplen); /* copy tag too */
|
||||
- }
|
||||
- *recvbuflen = apdu.resplen;
|
||||
- r = *recvbuflen;
|
||||
- }
|
||||
+ r = apdu.resplen;
|
||||
|
||||
err:
|
||||
sc_unlock(card);
|
||||
@@ -604,8 +575,7 @@ static int piv_generate_key(sc_card_t *card,
|
||||
sc_cardctl_piv_genkey_info_t *keydata)
|
||||
{
|
||||
int r;
|
||||
- u8 *rbuf = NULL;
|
||||
- size_t rbuflen = 0;
|
||||
+ u8 rbuf[4096];
|
||||
u8 *p;
|
||||
const u8 *tag;
|
||||
u8 tagbuf[16];
|
||||
@@ -654,7 +624,7 @@ static int piv_generate_key(sc_card_t *card,
|
||||
p+=out_len;
|
||||
|
||||
r = piv_general_io(card, 0x47, 0x00, keydata->key_num,
|
||||
- tagbuf, p - tagbuf, &rbuf, &rbuflen);
|
||||
+ tagbuf, p - tagbuf, rbuf, sizeof rbuf);
|
||||
|
||||
if (r >= 0) {
|
||||
const u8 *cp;
|
||||
@@ -664,9 +634,9 @@ static int piv_generate_key(sc_card_t *card,
|
||||
/* we will whatever tag is present */
|
||||
|
||||
cp = rbuf;
|
||||
- in_len = rbuflen;
|
||||
+ in_len = r;
|
||||
|
||||
- r = sc_asn1_read_tag(&cp, rbuflen, &cla_out, &tag_out, &in_len);
|
||||
+ r = sc_asn1_read_tag(&cp, in_len, &cla_out, &tag_out, &in_len);
|
||||
if (cp == NULL) {
|
||||
r = SC_ERROR_ASN1_OBJECT_NOT_FOUND;
|
||||
}
|
||||
@@ -710,8 +680,6 @@ static int piv_generate_key(sc_card_t *card,
|
||||
}
|
||||
|
||||
err:
|
||||
- if (rbuf)
|
||||
- free(rbuf);
|
||||
LOG_FUNC_RETURN(card->ctx, r);
|
||||
}
|
||||
|
||||
@@ -927,27 +895,23 @@ piv_get_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len)
|
||||
|
||||
if (*buf_len == 1 && *buf == NULL) { /* we need to get the length */
|
||||
u8 rbufinitbuf[8]; /* tag of 53 with 82 xx xx will fit in 4 */
|
||||
- u8 *rbuf;
|
||||
- size_t rbuflen;
|
||||
size_t bodylen;
|
||||
unsigned int cla_out, tag_out;
|
||||
const u8 *body;
|
||||
|
||||
sc_log(card->ctx, "get len of #%d", enumtag);
|
||||
- rbuf = rbufinitbuf;
|
||||
- rbuflen = sizeof(rbufinitbuf);
|
||||
- r = piv_general_io(card, 0xCB, 0x3F, 0xFF, tagbuf, p - tagbuf, &rbuf, &rbuflen);
|
||||
+ r = piv_general_io(card, 0xCB, 0x3F, 0xFF, tagbuf, p - tagbuf, rbufinitbuf, sizeof rbufinitbuf);
|
||||
if (r > 0) {
|
||||
int r_tag;
|
||||
- body = rbuf;
|
||||
- r_tag = sc_asn1_read_tag(&body, rbuflen, &cla_out, &tag_out, &bodylen);
|
||||
+ body = rbufinitbuf;
|
||||
+ r_tag = sc_asn1_read_tag(&body, r, &cla_out, &tag_out, &bodylen);
|
||||
if ((r_tag != SC_SUCCESS && r_tag != SC_ERROR_ASN1_END_OF_CONTENTS)
|
||||
|| body == NULL) {
|
||||
sc_log(card->ctx, "r_tag:%d body:%p", r_tag, body);
|
||||
r = SC_ERROR_FILE_NOT_FOUND;
|
||||
goto err;
|
||||
}
|
||||
- *buf_len = (body - rbuf) + bodylen;
|
||||
+ *buf_len = (body - rbufinitbuf) + bodylen;
|
||||
} else if ( r == 0 ) {
|
||||
r = SC_ERROR_FILE_NOT_FOUND;
|
||||
goto err;
|
||||
@@ -970,7 +934,7 @@ piv_get_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len)
|
||||
}
|
||||
}
|
||||
|
||||
- r = piv_general_io(card, 0xCB, 0x3F, 0xFF, tagbuf, p - tagbuf, buf, buf_len);
|
||||
+ r = piv_general_io(card, 0xCB, 0x3F, 0xFF, tagbuf, p - tagbuf, *buf, *buf_len);
|
||||
|
||||
err:
|
||||
sc_unlock(card);
|
||||
@@ -1270,7 +1234,7 @@ piv_put_data(sc_card_t *card, int tag, const u8 *buf, size_t buf_len)
|
||||
memcpy(p, buf, buf_len);
|
||||
p += buf_len;
|
||||
|
||||
- r = piv_general_io(card, 0xDB, 0x3F, 0xFF, sbuf, p - sbuf, NULL, NULL);
|
||||
+ r = piv_general_io(card, 0xDB, 0x3F, 0xFF, sbuf, p - sbuf, NULL, 0);
|
||||
|
||||
if (sbuf)
|
||||
free(sbuf);
|
||||
@@ -1584,8 +1548,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card,
|
||||
#ifdef ENABLE_OPENSSL
|
||||
int N;
|
||||
int locked = 0;
|
||||
- u8 *rbuf = NULL;
|
||||
- size_t rbuflen;
|
||||
+ u8 rbuf[4096];
|
||||
u8 *nonce = NULL;
|
||||
size_t nonce_len;
|
||||
u8 *p;
|
||||
@@ -1645,7 +1608,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card,
|
||||
*p++ = 0x00;
|
||||
|
||||
/* get the encrypted nonce */
|
||||
- r = piv_general_io(card, 0x87, alg_id, key_ref, sbuf, p - sbuf, &rbuf, &rbuflen);
|
||||
+ r = piv_general_io(card, 0x87, alg_id, key_ref, sbuf, p - sbuf, rbuf, sizeof rbuf);
|
||||
|
||||
if (r < 0) goto err;
|
||||
|
||||
@@ -1765,12 +1728,8 @@ static int piv_general_mutual_authenticate(sc_card_t *card,
|
||||
put_tag_and_len(0x81, witness_len, &p);
|
||||
memcpy(p, nonce, witness_len);
|
||||
|
||||
- /* Don't leak rbuf from above */
|
||||
- free(rbuf);
|
||||
- rbuf = NULL;
|
||||
-
|
||||
/* Send constructed data */
|
||||
- r = piv_general_io(card, 0x87, alg_id, key_ref, built,built_len, &rbuf, &rbuflen);
|
||||
+ r = piv_general_io(card, 0x87, alg_id, key_ref, built,built_len, rbuf, sizeof rbuf);
|
||||
if (r < 0) goto err;
|
||||
|
||||
/* Remove the encompassing outer TLV of 0x7C and get the data */
|
||||
@@ -1840,8 +1799,6 @@ static int piv_general_mutual_authenticate(sc_card_t *card,
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
if (locked)
|
||||
sc_unlock(card);
|
||||
- if (rbuf)
|
||||
- free(rbuf);
|
||||
if (decrypted_reponse)
|
||||
free(decrypted_reponse);
|
||||
if (built)
|
||||
@@ -1872,13 +1829,12 @@ static int piv_general_external_authenticate(sc_card_t *card,
|
||||
int outlen;
|
||||
int locked = 0;
|
||||
u8 *p;
|
||||
- u8 *rbuf = NULL;
|
||||
+ u8 rbuf[4096];
|
||||
u8 *key = NULL;
|
||||
u8 *cypher_text = NULL;
|
||||
u8 *output_buf = NULL;
|
||||
const u8 *body = NULL;
|
||||
const u8 *challenge_data = NULL;
|
||||
- size_t rbuflen;
|
||||
size_t body_len;
|
||||
size_t output_len;
|
||||
size_t challenge_len;
|
||||
@@ -1925,7 +1881,7 @@ static int piv_general_external_authenticate(sc_card_t *card,
|
||||
*p++ = 0x00;
|
||||
|
||||
/* get a challenge */
|
||||
- r = piv_general_io(card, 0x87, alg_id, key_ref, sbuf, p - sbuf, &rbuf, &rbuflen);
|
||||
+ r = piv_general_io(card, 0x87, alg_id, key_ref, sbuf, p - sbuf, rbuf, sizeof rbuf);
|
||||
if (r < 0) {
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Error getting Challenge\n");
|
||||
goto err;
|
||||
@@ -2037,7 +1993,7 @@ static int piv_general_external_authenticate(sc_card_t *card,
|
||||
goto err;
|
||||
}
|
||||
|
||||
- r = piv_general_io(card, 0x87, alg_id, key_ref, output_buf, output_len, NULL, NULL);
|
||||
+ r = piv_general_io(card, 0x87, alg_id, key_ref, output_buf, output_len, NULL, 0);
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Got response challenge\n");
|
||||
|
||||
err:
|
||||
@@ -2052,9 +2008,6 @@ static int piv_general_external_authenticate(sc_card_t *card,
|
||||
free(key);
|
||||
}
|
||||
|
||||
- if (rbuf)
|
||||
- free(rbuf);
|
||||
-
|
||||
if (cypher_text)
|
||||
free(cypher_text);
|
||||
|
||||
@@ -2221,9 +2174,9 @@ static int piv_get_challenge(sc_card_t *card, u8 *rnd, size_t len)
|
||||
{
|
||||
/* Dynamic Authentication Template (Challenge) */
|
||||
u8 sbuf[] = {0x7c, 0x02, 0x81, 0x00};
|
||||
- u8 *rbuf = NULL;
|
||||
+ u8 rbuf[4096];
|
||||
const u8 *p;
|
||||
- size_t rbuf_len = 0, out_len = 0;
|
||||
+ size_t out_len = 0;
|
||||
int r;
|
||||
unsigned int tag, cla;
|
||||
piv_private_data_t * priv = PIV_DATA(card);
|
||||
@@ -2236,7 +2189,7 @@ static int piv_get_challenge(sc_card_t *card, u8 *rnd, size_t len)
|
||||
}
|
||||
|
||||
/* NIST 800-73-3 says use 9B, previous verisons used 00 */
|
||||
- r = piv_general_io(card, 0x87, 0x00, 0x9B, sbuf, sizeof sbuf, &rbuf, &rbuf_len);
|
||||
+ r = piv_general_io(card, 0x87, 0x00, 0x9B, sbuf, sizeof sbuf, rbuf, sizeof rbuf);
|
||||
/*
|
||||
* piv_get_challenge is called in a loop.
|
||||
* some cards may allow 1 challenge expecting it to be part of
|
||||
@@ -2245,10 +2198,7 @@ static int piv_get_challenge(sc_card_t *card, u8 *rnd, size_t len)
|
||||
* Now that the card returned error, we can try one more time.
|
||||
*/
|
||||
if (r == SC_ERROR_INCORRECT_PARAMETERS) {
|
||||
- if (rbuf)
|
||||
- free(rbuf);
|
||||
- rbuf_len = 0;
|
||||
- r = piv_general_io(card, 0x87, 0x00, 0x9B, sbuf, sizeof sbuf, &rbuf, &rbuf_len);
|
||||
+ r = piv_general_io(card, 0x87, 0x00, 0x9B, sbuf, sizeof sbuf, rbuf, sizeof rbuf);
|
||||
if (r == SC_ERROR_INCORRECT_PARAMETERS) {
|
||||
r = SC_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
@@ -2256,13 +2206,12 @@ static int piv_get_challenge(sc_card_t *card, u8 *rnd, size_t len)
|
||||
LOG_TEST_GOTO_ERR(card->ctx, r, "GENERAL AUTHENTICATE failed");
|
||||
|
||||
p = rbuf;
|
||||
- r = sc_asn1_read_tag(&p, rbuf_len, &cla, &tag, &out_len);
|
||||
+ r = sc_asn1_read_tag(&p, r, &cla, &tag, &out_len);
|
||||
if (r < 0 || (cla|tag) != 0x7C) {
|
||||
LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find Dynamic Authentication Template");
|
||||
}
|
||||
|
||||
- rbuf_len = out_len;
|
||||
- r = sc_asn1_read_tag(&p, rbuf_len, &cla, &tag, &out_len);
|
||||
+ r = sc_asn1_read_tag(&p, out_len, &cla, &tag, &out_len);
|
||||
if (r < 0 || (cla|tag) != 0x81) {
|
||||
LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find Challenge");
|
||||
}
|
||||
@@ -2275,8 +2224,6 @@ static int piv_get_challenge(sc_card_t *card, u8 *rnd, size_t len)
|
||||
r = (int) out_len;
|
||||
|
||||
err:
|
||||
- free(rbuf);
|
||||
-
|
||||
LOG_FUNC_RETURN(card->ctx, r);
|
||||
|
||||
}
|
||||
@@ -2345,8 +2292,7 @@ static int piv_validate_general_authentication(sc_card_t *card,
|
||||
unsigned int real_alg_id;
|
||||
|
||||
u8 sbuf[4096]; /* needs work. for 3072 keys, needs 384+10 or so */
|
||||
- u8 *rbuf = NULL;
|
||||
- size_t rbuflen = 0;
|
||||
+ u8 rbuf[4096];
|
||||
|
||||
SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
|
||||
|
||||
@@ -2383,10 +2329,10 @@ static int piv_validate_general_authentication(sc_card_t *card,
|
||||
/* EC alg_id was already set */
|
||||
|
||||
r = piv_general_io(card, 0x87, real_alg_id, priv->key_ref,
|
||||
- sbuf, p - sbuf, &rbuf, &rbuflen);
|
||||
+ sbuf, p - sbuf, rbuf, sizeof rbuf);
|
||||
|
||||
if (r >= 0) {
|
||||
- body = sc_asn1_find_tag(card->ctx, rbuf, rbuflen, 0x7c, &bodylen);
|
||||
+ 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) {
|
||||
@@ -2398,9 +2344,6 @@ static int piv_validate_general_authentication(sc_card_t *card,
|
||||
r = SC_ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
- if (rbuf)
|
||||
- free(rbuf);
|
||||
-
|
||||
LOG_FUNC_RETURN(card->ctx, r);
|
||||
}
|
||||
|
||||
@@ -2414,7 +2357,6 @@ 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 */
|
||||
- size_t rbuflen = sizeof(rbuf);
|
||||
const u8 * body;
|
||||
size_t bodylen;
|
||||
const u8 * tag;
|
||||
@@ -2441,11 +2383,11 @@ piv_compute_signature(sc_card_t *card, const u8 * data, size_t datalen,
|
||||
}
|
||||
memset(out, 0, outlen);
|
||||
|
||||
- r = piv_validate_general_authentication(card, data, datalen, rbuf, rbuflen);
|
||||
+ r = piv_validate_general_authentication(card, data, datalen, rbuf, sizeof rbuf);
|
||||
if (r < 0)
|
||||
goto err;
|
||||
|
||||
- body = sc_asn1_find_tag(card->ctx, rbuf, rbuflen, 0x30, &bodylen);
|
||||
+ body = sc_asn1_find_tag(card->ctx, rbuf, r, 0x30, &bodylen);
|
||||
|
||||
for (i = 0; i<2; i++) {
|
||||
if (body) {
|
||||
116
backport-tcos-Reformat-insert_key.patch
Normal file
116
backport-tcos-Reformat-insert_key.patch
Normal file
@ -0,0 +1,116 @@
|
||||
From d3451faa2190e9f4c12bb00adf00149b7af1d18d Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Jelen <jjelen@redhat.com>
|
||||
Date: Mon, 16 Nov 2020 11:57:10 +0100
|
||||
Subject: [PATCH] tcos: Reformat insert_key
|
||||
|
||||
---
|
||||
src/libopensc/pkcs15-tcos.c | 65 ++++++++++++++++++++++---------------
|
||||
1 file changed, 38 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/src/libopensc/pkcs15-tcos.c b/src/libopensc/pkcs15-tcos.c
|
||||
index c62a3765f9..06cb1a9010 100644
|
||||
--- a/src/libopensc/pkcs15-tcos.c
|
||||
+++ b/src/libopensc/pkcs15-tcos.c
|
||||
@@ -99,9 +99,10 @@ static int insert_key(
|
||||
int key_length,
|
||||
unsigned char auth_id,
|
||||
const char *label
|
||||
-){
|
||||
- sc_card_t *card=p15card->card;
|
||||
- sc_context_t *ctx=p15card->card->ctx;
|
||||
+)
|
||||
+{
|
||||
+ sc_card_t *card = p15card->card;
|
||||
+ sc_context_t *ctx = p15card->card->ctx;
|
||||
sc_file_t *f;
|
||||
struct sc_pkcs15_prkey_info prkey_info;
|
||||
struct sc_pkcs15_object prkey_obj;
|
||||
@@ -121,13 +122,14 @@ static int insert_key(
|
||||
prkey_obj.auth_id.len = 1;
|
||||
prkey_obj.auth_id.value[0] = auth_id;
|
||||
|
||||
- can_sign=can_crypt=0;
|
||||
- if(card->type==SC_CARD_TYPE_TCOS_V3){
|
||||
+ can_sign = can_crypt = 0;
|
||||
+ if (card->type == SC_CARD_TYPE_TCOS_V3) {
|
||||
unsigned char buf[256];
|
||||
- int i, rec_no=0;
|
||||
- if(prkey_info.path.len>=2) prkey_info.path.len-=2;
|
||||
+ int i, rec_no = 0;
|
||||
+ if (prkey_info.path.len >= 2)
|
||||
+ prkey_info.path.len -= 2;
|
||||
sc_append_file_id(&prkey_info.path, 0x5349);
|
||||
- if(sc_select_file(card, &prkey_info.path, NULL)!=SC_SUCCESS){
|
||||
+ if (sc_select_file(card, &prkey_info.path, NULL) != SC_SUCCESS) {
|
||||
sc_log(ctx,
|
||||
"Select(%s) failed\n",
|
||||
sc_print_path(&prkey_info.path));
|
||||
@@ -135,24 +137,29 @@ static int insert_key(
|
||||
}
|
||||
sc_log(ctx,
|
||||
"Searching for Key-Ref %02X\n", key_reference);
|
||||
- while((r=sc_read_record(card, ++rec_no, buf, sizeof(buf), SC_RECORD_BY_REC_NR))>0){
|
||||
- int found=0;
|
||||
- if(buf[0]!=0xA0) continue;
|
||||
- for(i=2;i<buf[1]+2;i+=2+buf[i+1]){
|
||||
- if(buf[i]==0x83 && buf[i+1]==1 && buf[i+2]==key_reference) ++found;
|
||||
+ while ((r = sc_read_record(card, ++rec_no, buf, sizeof(buf), SC_RECORD_BY_REC_NR)) > 0) {
|
||||
+ int found = 0;
|
||||
+ if (buf[0] != 0xA0)
|
||||
+ continue;
|
||||
+ for (i = 2; i < buf[1] + 2; i += 2 + buf[i + 1]) {
|
||||
+ if (buf[i] == 0x83 && buf[i + 1] == 1 && buf[i + 2] == key_reference)
|
||||
+ ++found;
|
||||
}
|
||||
- if(found) break;
|
||||
+ if (found)
|
||||
+ break;
|
||||
}
|
||||
- if(r<=0){
|
||||
+ if (r <= 0) {
|
||||
sc_log(ctx, "No EF_KEYD-Record found\n");
|
||||
return 1;
|
||||
}
|
||||
- for(i=0;i<r;i+=2+buf[i+1]){
|
||||
- if(buf[i]==0xB6) can_sign++;
|
||||
- if(buf[i]==0xB8) can_crypt++;
|
||||
+ for (i = 0; i < r; i += 2 + buf[i + 1]) {
|
||||
+ if (buf[i] == 0xB6)
|
||||
+ can_sign++;
|
||||
+ if (buf[i] == 0xB8)
|
||||
+ can_crypt++;
|
||||
}
|
||||
} else {
|
||||
- if(sc_select_file(card, &prkey_info.path, &f)!=SC_SUCCESS
|
||||
+ if (sc_select_file(card, &prkey_info.path, &f) != SC_SUCCESS
|
||||
|| !f->prop_attr || f->prop_attr_len < 2){
|
||||
sc_log(ctx,
|
||||
"Select(%s) failed\n",
|
||||
@@ -160,15 +167,19 @@ static int insert_key(
|
||||
return 1;
|
||||
}
|
||||
- if (f->prop_attr[1] & 0x04) can_crypt=1;
|
||||
- if (f->prop_attr[1] & 0x08) can_sign=1;
|
||||
+ if (f->prop_attr[1] & 0x04)
|
||||
+ can_crypt = 1;
|
||||
+ if (f->prop_attr[1] & 0x08)
|
||||
+ can_sign = 1;
|
||||
sc_file_free(f);
|
||||
}
|
||||
- prkey_info.usage= SC_PKCS15_PRKEY_USAGE_SIGN;
|
||||
- if(can_crypt) prkey_info.usage |= SC_PKCS15_PRKEY_USAGE_ENCRYPT|SC_PKCS15_PRKEY_USAGE_DECRYPT;
|
||||
- if(can_sign) prkey_info.usage |= SC_PKCS15_PRKEY_USAGE_NONREPUDIATION;
|
||||
-
|
||||
- r=sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info);
|
||||
- if(r!=SC_SUCCESS){
|
||||
+ prkey_info.usage = SC_PKCS15_PRKEY_USAGE_SIGN;
|
||||
+ if (can_crypt)
|
||||
+ prkey_info.usage |= SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_DECRYPT;
|
||||
+ if (can_sign)
|
||||
+ prkey_info.usage |= SC_PKCS15_PRKEY_USAGE_NONREPUDIATION;
|
||||
+
|
||||
+ r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info);
|
||||
+ if(r != SC_SUCCESS) {
|
||||
sc_log(ctx, "sc_pkcs15emu_add_rsa_prkey(%s) failed\n", path);
|
||||
return 4;
|
||||
}
|
||||
21
opensc.spec
21
opensc.spec
@ -3,7 +3,7 @@
|
||||
|
||||
Name: opensc
|
||||
Version: 0.20.0
|
||||
Release: 9
|
||||
Release: 10
|
||||
License: LGPLv2.1+
|
||||
Summary: Smart card library and applications
|
||||
URL: https://github.com/OpenSC/OpenSC/wiki
|
||||
@ -22,11 +22,17 @@ Patch9: oberthur-Fix-memory-leaks.patch
|
||||
Patch10: oberthur-Avoid-memory-leaks.patch
|
||||
Patch11: oberthur-fixed-Heap-buffer-overflow.patch
|
||||
Patch12: oberthur-One-more-overlooked-buffer-overflow.patch
|
||||
Patch13: cardos-Correctly-calculate-the-left-bytes-to-avoid-b.patch
|
||||
Patch14: oberthur-Handle-1B-OIDs.patch
|
||||
Patch15: Fix-ACLs-support.patch
|
||||
Patch16: backport-tcos-Reformat-insert_pin-for-readability.patch
|
||||
Patch17: backport-CVE-2021-42780-tcos-Check-bounds-in-insert_pin.patch
|
||||
Patch13: oberthur-Handle-1B-OIDs.patch
|
||||
Patch14: Fix-ACLs-support.patch
|
||||
Patch15: backport-tcos-Reformat-insert_pin-for-readability.patch
|
||||
Patch16: backport-CVE-2021-42780-tcos-Check-bounds-in-insert_pin.patch
|
||||
Patch17: backport-simplify-PIV-IO.patch
|
||||
Patch18: backport-tcos-Reformat-insert_key.patch
|
||||
Patch19: backport-0001-CVE-2021-42782-tcos-prevent-out-of-bounds-read.patch
|
||||
Patch20: backport-0002-CVE-2021-42782-coolkey-Initialize-potentially.patch
|
||||
Patch21: backport-0003-CVE-2021-42782-cardos-Correctly-calculate-the-left.patch
|
||||
Patch22: backport-0004-CVE-2021-42782-iasecc-Prevent-stack-buffer.patch
|
||||
Patch23: backport-0005-CVE-2021-42782-PIV-Improved-parsing.patch
|
||||
|
||||
BuildRequires: openssl-devel pcsc-lite-devel bash-completion docbook-style-xsl readline-devel
|
||||
BuildRequires: desktop-file-utils /usr/bin/xsltproc autoconf automake libtool gcc
|
||||
@ -150,6 +156,9 @@ make check
|
||||
%{_sysconfdir}/xdg/autostart/pkcs11-register.desktop
|
||||
|
||||
%changelog
|
||||
* Mon May 9 2022 Hugel <gengqihu1@h-partners.com> - 0.20.0-10
|
||||
- fix CVE-2021-42782
|
||||
|
||||
* Mon May 9 2022 Hugel <gengqihu1@h-partners.com> - 0.20.0-9
|
||||
- fix CVE-2021-42780
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user