Accepting request 854174 from security:chipcard

OBS-URL: https://build.opensuse.org/request/show/854174
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/opensc?expand=0&rev=47
This commit is contained in:
Dominique Leuenberger 2020-12-09 21:21:58 +00:00 committed by Git OBS Bridge
commit 145d9095e8
7 changed files with 118 additions and 2929 deletions

View File

@ -1,644 +0,0 @@
From 4ad599bf6c966310819fe3f8114f769d8f180947 Mon Sep 17 00:00:00 2001
From: Doug Engert <deengert@gmail.com>
Date: Wed, 5 Dec 2018 14:12:07 -0600
Subject: [PATCH 1/5] PIV - Improved Card Matching for Dual CAC/PIV and PIVKEY
cards.
Not all PIV applets are the same. Different versions of NIST 800-73 and improperly implemented
or not implemented required features of NIST 800-73 cases problems. Have a look at the card_issues
listed in card-piv.c. The PIV driver has tried to detect the differences based on clues found in
the ATR historical bytes and vendor version numbers for some cards.
At the same time it has tried to support the possibility there are multiple applets
on a card that the user may want to use at the same time from different applications.
This has lead to some detection problems with Dual CAC/PIV cards. The same cards
sold by the vendor may have only a PIV applet that may not be the same PIV applet that
is on the Dual PIV/CAC cards.
http://www.cac.mil/Portals/53/Documents/CAC-utilziation-and-variation-matrix-v2.03-20May2016.doc
defines a number of official CAC cards in active service. A table of the ATRs for these is now used
to detect these cards. The PIV version of the CCC is also read to see if any CAC PKI objects
are defined in the CCC, indicating it is a Dual CAC/PIV, even if the ATR is not listed.
A more conservative approach to try and handle multiple applets on a card is used. Based
on issues with the implementation of the PIV applet this may not be possible to do.
So for many cards no additional detection will be done at the start of every transaction,
and the login state can not be detected correctly.
ATRs for PIVKEY are also in the match table, as these cards have a log of issues.
Other PIV cards in the future or not yet tested may not be covered properly by this patch.
Extra debugging was added with "PIV_MATCH" to help with these other cards.
With "debug = 7;", `grep PIV_MATCH opensc-debug.log` can be used to see how a card
type and card_issues are derived.
________________________________
From 974ffd8166f961c9def8ececa6087dfaf73c866b Mon Sep 17 00:00:00 2001
From: Doug Engert <deengert@gmail.com>
Date: Sat, 8 Dec 2018 18:16:40 -0600
Subject: [PATCH 2/5] PIV - Improved error handling of get_challenge
Random data from PIV card is obtained using GENERAL AUTHENTICATE command
for a request of a Challenge from the card. "00 87 00 9B 04 7C 02 81 00"
Usually 8 bytes are returned.
NIST 800-73-3_PART2, "A.1 Authentication of the PIV Card Application Administrator"
"Table 11. Authentication of PIV Card Application Administrator" shows an example of
how to do this.
Some cards (one I have: 3b:7d:96:00:00:80:31:80:65:b0:83:11:17:d6:83:00:90:00)
will not allow 2 of these commands in a row. (Maybe assuming command is only
used as in Table 11 and is expecting the second command.)
Code was added to card-piv.c so if "6A 80" is returned, try the command one more time.
For any other GENERAL AUTHENTICATE failure, SC_ERROR_NOT_SUPPORTED is returned.
piv_get_challenge may be called within a loop from sc_get_challenge if more random
data is needed thus causing the the 2 commands to sent in a row.
Index: opensc-0.19.0/src/libopensc/card-piv.c
===================================================================
--- opensc-0.19.0.orig/src/libopensc/card-piv.c
+++ opensc-0.19.0/src/libopensc/card-piv.c
@@ -3,7 +3,7 @@
* card-default.c: Support for cards with no driver
*
* Copyright (C) 2001, 2002 Juha Yrjölä <juha.yrjola@iki.fi>
- * Copyright (C) 2005-2016 Douglas E. Engert <deengert@gmail.com>
+ * Copyright (C) 2005-2018 Douglas E. Engert <deengert@gmail.com>
* Copyright (C) 2006, Identity Alliance, Thomas Harning <thomas.harning@identityalliance.com>
* Copyright (C) 2007, EMC, Russell Larner <rlarner@rsa.com>
*
@@ -53,6 +53,7 @@
#ifdef ENABLE_ZLIB
#include "compression.h"
#endif
+#include "simpletlv.h"
enum {
PIV_OBJ_CCC = 0,
@@ -146,6 +147,16 @@ enum {
PIV_STATE_INIT
};
+/* ccc_flags */
+#define PIV_CCC_FOUND 0x00000001
+#define PIV_CCC_F0_PIV 0x00000002
+#define PIV_CCC_F0_CAC 0x00000004
+#define PIV_CCC_F0_JAVA 0x00000008
+#define PIV_CCC_F3_CAC_PKI 0x00000010
+
+#define PIV_CCC_TAG_F0 0xF0
+#define PIV_CCC_TAG_F3 0xF3
+
typedef struct piv_private_data {
int enumtag;
int selected_obj; /* The index into the piv_objects last selected */
@@ -174,6 +185,7 @@ typedef struct piv_private_data {
unsigned int card_issues; /* card_issues flags for this card */
int object_test_verify; /* Can test this object to set verification state of card */
int yubico_version; /* 3 byte version number of NEO or Yubikey4 as integer */
+ unsigned int ccc_flags; /* From CCC indicate if CAC card */
} piv_private_data_t;
#define PIV_DATA(card) ((piv_private_data_t*)card->drv_data)
@@ -198,6 +210,39 @@ struct piv_aid {
* These can be discovered by trying GET DATA
*/
+/* ATRs of cards known to have PIV applet. But must still be tested for a PIV applet */
+static const struct sc_atr_table piv_atrs[] = {
+ /* CAC cards with PIV from: CAC-utilziation-and-variation-matrix-v2.03-20May2016.doc */
+ /* Oberthur Card Systems (PIV Endpoint) with PIV endpoint applet and PIV auth cert OBSOLETE */
+ { "3B:DB:96:00:80:1F:03:00:31:C0:64:77:E3:03:00:82:90.00:C1", NULL, NULL, SC_CARD_TYPE_PIV_II_OBERTHUR, 0, NULL },
+
+ /* Gemalto (PIV Endpoint) with PIV endpoint applet and PIV auth cert OBSOLETE */
+ { "3B 7D 96 00 00 80 31 80 65 B0 83 11 13 AC 83 00 90 00", NULL, NULL, SC_CARD_TYPE_PIV_II_GEMALTO, 0, NULL },
+
+ /* Gemalto (PIV Endpoint) 2 entries */
+ { "3B:7D:96:00:00:80:31:80:65:B0:83:11:17:D6:83:00:90:00", NULL, NULL, SC_CARD_TYPE_PIV_II_GEMALTO, 0, NULL },
+
+ /* Oberthur Card System (PIV Endpoint) 2 entries*/
+ { "3B:DB:96:00:80:1F:03:00:31:C0:64:B0:F3:10:00:07:90:00:80", NULL, NULL, SC_CARD_TYPE_PIV_II_OBERTHUR, 0, NULL },
+ /* Oberthur Card System with LCS 0F - Some VA cards have Terminated state */
+ { "3B:DB:96:00:80:1F:03:00:31:C0:64:B0:F3:10:00:0F:90:00:88", NULL, NULL, SC_CARD_TYPE_PIV_II_OBERTHUR, 0, NULL },
+
+ /* Giesecke & Devrient (PIV Endpoint) 2 entries */
+ { "3B:7A:18:00:00:73:66:74:65:20:63:64:31:34:34", NULL, NULL, SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC, 0, NULL },
+
+ /* PIVKEY from Taligo */
+ /* PIVKEY T600 token and T800 on Feitian eJAVA */
+ { "3B:FC:18:00:00:81:31:80:45:90:67:46:4A:00:64:2D:70:C1:72:FE:E0:FE", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL },
+
+ /* PIVKEY C910 */
+ { "3b:fc:18:00:00:81:31:80:45:90:67:46:4a:00:64:16:06:f2:72:7e:00:e0", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL },
+
+ /* PIVKEY C980 */
+ { "3B:f9:96:00:00:81:31:fe:45:53:50:49:56:4b:45:59:37:30:28", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL },
+
+ { NULL, NULL, NULL, 0, 0, NULL }
+};
+
/* all have same AID */
static struct piv_aid piv_aids[] = {
{SC_CARD_TYPE_PIV_II_GENERIC, /* TODO not really card type but what PIV AID is supported */
@@ -209,9 +254,10 @@ static struct piv_aid piv_aids[] = {
#define CI_VERIFY_630X 0x00000001U /* VERIFY tries left returns 630X rather then 63CX */
#define CI_VERIFY_LC0_FAIL 0x00000002U /* VERIFY Lc=0 never returns 90 00 if PIN not needed */
/* will also test after first PIN verify if protected object can be used instead */
+#define CI_NO_RANDOM 0x00000004U /* can not use Challenge to get random data or no 9B key */
#define CI_CANT_USE_GETDATA_FOR_STATE 0x00000008U /* No object to test verification inplace of VERIFY Lc=0 */
#define CI_LEAKS_FILE_NOT_FOUND 0x00000010U /* GET DATA of empty object returns 6A 82 even if PIN not verified */
-#define CI_DISCOVERY_USELESS 0x00000020U /* Discovery can not be used to query active AID */
+#define CI_DISCOVERY_USELESS 0x00000020U /* Discovery can not be used to query active AID invalid or no data returned */
#define CI_PIV_AID_LOSE_STATE 0x00000040U /* PIV AID can lose the login state run with out it*/
#define CI_OTHER_AID_LOSE_STATE 0x00000100U /* Other drivers match routines may reset our security state and lose AID!!! */
@@ -219,7 +265,7 @@ static struct piv_aid piv_aids[] = {
#define CI_NO_RSA2048 0x00010000U /* does not have RSA 2048 */
#define CI_NO_EC384 0x00020000U /* does not have EC 384 */
-
+#define CI_NO_EC 0x00040000U /* No EC at all */
/*
* Flags in the piv_object:
@@ -2233,11 +2279,33 @@ static int piv_get_challenge(sc_card_t *
size_t rbuf_len = 0, out_len = 0;
int r;
unsigned int tag, cla;
+ piv_private_data_t * priv = PIV_DATA(card);
LOG_FUNC_CALLED(card->ctx);
+ if (priv->card_issues & CI_NO_RANDOM) {
+ r = SC_ERROR_NOT_SUPPORTED;
+ LOG_TEST_GOTO_ERR(card->ctx, r, "No support for random data");
+ }
+
/* 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);
+ /*
+ * piv_get_challenge is called in a loop.
+ * some cards may allow 1 challenge expecting it to be part of
+ * NIST 800-73-3 part 2 "Authentication of PIV Card Application Administrator"
+ * and return "6A 80" if last command was a get_challenge.
+ * 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);
+ if (r == SC_ERROR_INCORRECT_PARAMETERS) {
+ r = SC_ERROR_NOT_SUPPORTED;
+ }
+ }
LOG_TEST_GOTO_ERR(card->ctx, r, "GENERAL AUTHENTICATE failed");
p = rbuf;
@@ -2653,6 +2721,89 @@ err:
LOG_FUNC_RETURN(card->ctx, r);
}
+/*
+ * parse a CCC to test if this is a Dual CAC/PIV
+ * We read teh CCC using the PIV API.
+ * Look for CAC RID=A0 00 00 00 79
+ */
+ static int piv_parse_ccc(sc_card_t *card, u8* rbuf, size_t rbuflen)
+{
+ int r = 0;
+ const u8 * body;
+ size_t bodylen;
+ unsigned int cla_out, tag_out;
+
+ u8 tag;
+ const u8 * end;
+ size_t len;
+
+ piv_private_data_t * priv = PIV_DATA(card);
+
+ SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
+
+ if (rbuf == NULL || rbuflen == 0) {
+ r = SC_ERROR_WRONG_LENGTH;
+ goto err;
+ }
+
+ /* Outer layer is a DER tlv */
+ body = rbuf;
+ if ((r = sc_asn1_read_tag(&body, rbuflen, &cla_out, &tag_out, &bodylen)) != SC_SUCCESS) {
+ sc_log(card->ctx, "DER problem %d",r);
+ r = SC_ERROR_INVALID_ASN1_OBJECT;
+ goto err;
+ }
+
+ priv->ccc_flags |= PIV_CCC_FOUND;
+
+ /* CCC entries are simple tlv */
+ end = body + bodylen;
+ for(; (body < end); body += len) {
+ r = sc_simpletlv_read_tag((u8**)&body, end - body , &tag, &len);
+ if (r < 0)
+ goto err;
+ switch (tag) {
+ case PIV_CCC_TAG_F0:
+ if (len == 0x15) {
+ if (memcmp(body ,"\xA0\x00\x00\x03\08", 5) == 0)
+ priv->ccc_flags |= PIV_CCC_F0_PIV;
+ else if (memcmp(body ,"\xA0\x00\x00\x00\x79", 5) == 0)
+ priv->ccc_flags |= PIV_CCC_F0_CAC;
+ if (*(body + 6) == 0x02)
+ priv->ccc_flags |= PIV_CCC_F0_JAVA;
+ }
+ break;
+ case PIV_CCC_TAG_F3:
+ if (len == 0x10) {
+ if (memcmp(body ,"\xA0\x00\x00\x00\x79\x04", 6) == 0)
+ priv->ccc_flags |= PIV_CCC_F3_CAC_PKI;
+ }
+ break;
+ }
+ }
+
+err:
+ LOG_FUNC_RETURN(card->ctx, r);
+}
+
+static int piv_process_ccc(sc_card_t *card)
+{
+ int r = 0;
+ u8 * rbuf = NULL;
+ size_t rbuflen = 0;
+
+ SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
+ r = piv_get_cached_data(card, PIV_OBJ_CCC, &rbuf, &rbuflen);
+
+ if (r < 0)
+ goto err;
+
+ /* the object is now cached, see what we have */
+ r = piv_parse_ccc(card, rbuf, rbuflen);
+err:
+ LOG_FUNC_RETURN(card->ctx, r);
+}
+
static int piv_find_discovery(sc_card_t *card)
{
@@ -2948,6 +3099,7 @@ static int piv_match_card(sc_card_t *car
{
int r = 0;
+ sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d\n", card->type);
/* piv_match_card may be called with card->type, set by opensc.conf */
/* user provide card type must be one we know */
switch (card->type) {
@@ -2956,7 +3108,13 @@ static int piv_match_card(sc_card_t *car
case SC_CARD_TYPE_PIV_II_HIST:
case SC_CARD_TYPE_PIV_II_NEO:
case SC_CARD_TYPE_PIV_II_YUBIKEY4:
+ case SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC:
case SC_CARD_TYPE_PIV_II_GI_DE:
+ case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC:
+ case SC_CARD_TYPE_PIV_II_GEMALTO:
+ case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC:
+ case SC_CARD_TYPE_PIV_II_OBERTHUR:
+ case SC_CARD_TYPE_PIV_II_PIVKEY:
break;
default:
return 0; /* can not handle the card */
@@ -2975,6 +3133,7 @@ static int piv_match_card(sc_card_t *car
piv_finish(card);
}
+ sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r:%d\n", card->type,r);
return r;
}
@@ -2998,12 +3157,19 @@ static int piv_match_card_continued(sc_c
case SC_CARD_TYPE_PIV_II_HIST:
case SC_CARD_TYPE_PIV_II_NEO:
case SC_CARD_TYPE_PIV_II_YUBIKEY4:
+ case SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC:
case SC_CARD_TYPE_PIV_II_GI_DE:
+ case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC:
+ case SC_CARD_TYPE_PIV_II_GEMALTO:
+ case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC:
+ case SC_CARD_TYPE_PIV_II_OBERTHUR:
+ case SC_CARD_TYPE_PIV_II_PIVKEY:
type = card->type;
break;
default:
return 0; /* can not handle the card */
}
+ sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d type:%d\n", card->type, type);
if (type == -1) {
/*
@@ -3022,18 +3188,6 @@ static int piv_match_card_continued(sc_c
!(memcmp(card->reader->atr_info.hist_bytes, "Yubikey", 7))) {
type = SC_CARD_TYPE_PIV_II_NEO;
}
- /*
- * https://csrc.nist.gov/csrc/media/projects/cryptographic-module-validation-program/documents/security-policies/140sp1239.pdf
- * lists 2 ATRS with historical bytes:
- * 73 66 74 65 2D 63 64 30 38 30
- * 73 66 74 65 20 63 64 31 34 34
- * will check for 73 66 74 65
- */
- else if (card->reader->atr_info.hist_bytes_len >= 4
- && !(memcmp(card->reader->atr_info.hist_bytes, "sfte", 4))) {
- type = SC_CARD_TYPE_PIV_II_GI_DE;
- }
-
else if (card->reader->atr_info.hist_bytes_len > 0
&& card->reader->atr_info.hist_bytes[0] == 0x80u) { /* compact TLV */
size_t datalen;
@@ -3054,10 +3208,17 @@ static int piv_match_card_continued(sc_c
}
}
}
- if (type == -1)
- type = SC_CARD_TYPE_PIV_II_GENERIC;
+ sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d type:%d\n", card->type, type);
+
+ if (type == -1) {
+ /* use known ATRs */
+ i = _sc_match_atr(card, piv_atrs, &type);
+ if (i < 0)
+ type = SC_CARD_TYPE_PIV_II_GENERIC; /* may still be CAC with PIV Endpoint */
+ }
}
+ sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d type:%d\n", card->type, type);
/* allocate and init basic fields */
priv = calloc(1, sizeof(piv_private_data_t));
@@ -3083,38 +3244,104 @@ static int piv_match_card_continued(sc_c
sc_lock(card);
/*
- * detect if active AID is PIV. NIST 800-73 says Only one PIV application per card
- * and PIV must be the default application
- * This can avoid doing doing a select_aid and losing the login state on some cards
+ * Detect if active AID is PIV. NIST 800-73 says only one PIV application per card
+ * and PIV must be the default application.
+ * Try to avoid doing a select_aid and losing the login state on some cards.
* We may get interference on some cards by other drivers trying SELECT_AID before
- * we get to see if PIV application is still active.
+ * we get to see if PIV application is still active
* putting PIV driver first might help.
- * This may fail if the wrong AID is active
+ * This may fail if the wrong AID is active.
+ * Discovery Object introduced in 800-73-3 so will return 0 if found and PIV applet active.
+ * Will fail with SC_ERROR_FILE_NOT_FOUND if 800-73-3 and no Discovery object.
+ * But some other card could also return SC_ERROR_FILE_NOT_FOUND.
+ * Will fail for other reasons if wrong applet is selected, or bad PIV implimentation.
*/
- i = piv_find_discovery(card);
+ sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d CI:%08x\n", card->type, priv->card_issues);
+ if (priv->card_issues & CI_DISCOVERY_USELESS) /* TODO may be in wrong place */
+ i = -1;
+ else
+ i = piv_find_discovery(card);
+
+ sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d i:%d CI:%08x\n", card->type, i, priv->card_issues);
if (i < 0) {
/* Detect by selecting applet */
i = piv_find_aid(card);
}
if (i >= 0) {
+ int iccc = 0;
+ /* We now know PIV AID is active, test CCC object 800-73-* say CCC is required */
+ switch (card->type) {
+ /*
+ * For cards that may also be CAC, try and read the CCC
+ * CCC is required and all Dual PIV/CAC will have a CCC
+ * Currently Dual PIV/CAC are based on NIST 800-73-1 which does not have Discovery or History
+ */
+ case SC_CARD_TYPE_PIV_II_GENERIC: /* i.e. really dont know what this is */
+ case SC_CARD_TYPE_PIV_II_HIST:
+ case SC_CARD_TYPE_PIV_II_GI_DE:
+ case SC_CARD_TYPE_PIV_II_GEMALTO:
+ case SC_CARD_TYPE_PIV_II_OBERTHUR:
+ iccc = piv_process_ccc(card);
+ sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d iccc:%d ccc_flags:%08x CI:%08x\n",
+ card->type, iccc, priv->ccc_flags, priv->card_issues);
+ /* ignore an error? */
+ /* if CCC says it has CAC with PKI on card set to one of the SC_CARD_TYPE_PIV_II_*_DUAL_CAC */
+ if (priv->ccc_flags & PIV_CCC_F3_CAC_PKI) {
+ switch (card->type) {
+ case SC_CARD_TYPE_PIV_II_GENERIC:
+ case SC_CARD_TYPE_PIV_II_HIST:
+ case SC_CARD_TYPE_PIV_II_GI_DE:
+ card->type = SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC;
+ priv->card_issues |= CI_DISCOVERY_USELESS;
+ priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT;
+ break;
+ case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC:
+ case SC_CARD_TYPE_PIV_II_GEMALTO:
+ card->type = SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC;
+ priv->card_issues |= CI_DISCOVERY_USELESS;
+ priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT;
+ break;
+ case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC:
+ case SC_CARD_TYPE_PIV_II_OBERTHUR:
+ card->type = SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC;
+ priv->card_issues |= CI_DISCOVERY_USELESS;
+ priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT;
+ break;
+ }
+ }
+ break;
+
+ /* if user forced it to be one of the CAC types, assume it is CAC */
+ case SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC:
+ case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC:
+ case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC:
+ priv->card_issues |= CI_DISCOVERY_USELESS;
+ priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT;
+ break;
+ }
+ }
+ sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d i:%d CI:%08x\n", card->type, i, priv->card_issues);
+ if (i >= 0 && (priv->card_issues & CI_DISCOVERY_USELESS) == 0) {
/*
- * We now know PIV AID is active, test DISCOVERY object
- * Some CAC cards with PIV don't support DISCOVERY and return
- * SC_ERROR_INCORRECT_PARAMETERS. Any error other then
- * SC_ERROR_FILE_NOT_FOUND means we cannot use discovery
+ * We now know PIV AID is active, test DISCOVERY object again
+ * Some PIV don't support DISCOVERY and return
+ * SC_ERROR_INCORRECT_PARAMETERS. Any error
+ * including SC_ERROR_FILE_NOT_FOUND means we cannot use discovery
* to test for active AID.
*/
int i7e = piv_find_discovery(card);
- if (i7e != 0 && i7e != SC_ERROR_FILE_NOT_FOUND) {
+ sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d i7e:%d CI:%08x\n", card->type, i7e, priv->card_issues);
+ if (i7e < 0) {
priv->card_issues |= CI_DISCOVERY_USELESS;
priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT;
}
}
+ sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d i:%d CI:%08x\n", card->type, i, priv->card_issues);
if (i < 0) {
/* don't match. Does not have a PIV applet. */
sc_unlock(card);
@@ -3123,6 +3350,7 @@ static int piv_match_card_continued(sc_c
return 0;
}
+ sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d i:%d CI:%08x\n", card->type, i, priv->card_issues);
/* Matched, caller will use or free priv and sc_lock as needed */
priv->pstate=PIV_STATE_INIT;
return 1; /* match */
@@ -3143,7 +3371,7 @@ static int piv_init(sc_card_t *card)
/* continue the matching get a lock and the priv */
r = piv_match_card_continued(card);
if (r != 1) {
- sc_log(card->ctx,"piv_match_card_continued failed");
+ sc_log(card->ctx,"piv_match_card_continued failed card->type:%d", card->type);
piv_finish(card);
/* tell sc_connect_card to try other drivers */
LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD);
@@ -3166,6 +3394,7 @@ static int piv_init(sc_card_t *card)
* Set card_issues based on card type either set by piv_match_card or by opensc.conf
*/
+ sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d CI:%08x\n", card->type, priv->card_issues);
switch(card->type) {
case SC_CARD_TYPE_PIV_II_NEO:
case SC_CARD_TYPE_PIV_II_YUBIKEY4:
@@ -3197,6 +3426,7 @@ static int piv_init(sc_card_t *card)
* may be set earlier or later then in the following code.
*/
+ sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d CI:%08x\n", card->type, priv->card_issues);
switch(card->type) {
case SC_CARD_TYPE_PIV_II_NEO:
priv->card_issues |= CI_NO_EC384
@@ -3215,14 +3445,23 @@ static int piv_init(sc_card_t *card)
priv->card_issues |= CI_VERIFY_LC0_FAIL;
break;
+ case SC_CARD_TYPE_PIV_II_GI_DE:
+ case SC_CARD_TYPE_PIV_II_OBERTHUR:
+ case SC_CARD_TYPE_PIV_II_GEMALTO:
+ priv->card_issues |= 0; /* could add others here */
+ break;
+
case SC_CARD_TYPE_PIV_II_HIST:
- priv->card_issues |= 0;
+ priv->card_issues |= 0; /* could add others here */
break;
- case SC_CARD_TYPE_PIV_II_GI_DE:
+ case SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC:
+ case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC:
+ case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC:
priv->card_issues |= CI_VERIFY_LC0_FAIL
| CI_PIV_AID_LOSE_STATE
- | CI_OTHER_AID_LOSE_STATE;;
+ | CI_NO_RANDOM
+ | CI_OTHER_AID_LOSE_STATE;
/* TODO may need more research */
break;
@@ -3232,13 +3471,26 @@ static int piv_init(sc_card_t *card)
/* TODO may need more research */
break;
+ case SC_CARD_TYPE_PIV_II_PIVKEY:
+ priv->card_issues |= CI_VERIFY_LC0_FAIL
+ | CI_PIV_AID_LOSE_STATE /* be conservative */
+ | CI_NO_EC384 | CI_NO_EC
+ | CI_NO_RANDOM; /* does not have 9B key */
+ /* Discovery object returns 6A 82 so is not on card by default */
+ /* TODO may need more research */
+ break;
+
default:
- priv->card_issues = 0; /* opensc.conf may have it wrong, continue anyway */
- sc_log(card->ctx, "Unknown PIV card->type %d", card->type);
- card->type = SC_CARD_TYPE_PIV_II_BASE;
+ priv->card_issues |= CI_VERIFY_LC0_FAIL
+ | CI_OTHER_AID_LOSE_STATE;
+ /* opensc.conf may have it wrong, continue anyway */
+ sc_log(card->ctx, "Unknown PIV card->type %d", card->type);
+ card->type = SC_CARD_TYPE_PIV_II_GENERIC;
}
sc_log(card->ctx, "PIV card-type=%d card_issues=0x%08x", card->type, priv->card_issues);
+ sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d CI:%08x\n", card->type, priv->card_issues);
+
priv->enumtag = piv_aids[0].enumtag;
/* PKCS#11 may try to generate session keys, and get confused
@@ -3252,15 +3504,20 @@ static int piv_init(sc_card_t *card)
_sc_card_add_rsa_alg(card, 2048, flags, 0); /* optional */
_sc_card_add_rsa_alg(card, 3072, flags, 0); /* optional */
- flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ECDSA_HASH_NONE;
- ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES;
+ if (!(priv->card_issues & CI_NO_EC)) {
+ flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ECDSA_HASH_NONE;
+ ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES;
+
+ _sc_card_add_ec_alg(card, 256, flags, ext_flags, NULL);
+ if (!(priv->card_issues & CI_NO_EC384))
+ _sc_card_add_ec_alg(card, 384, flags, ext_flags, NULL);
+ }
- _sc_card_add_ec_alg(card, 256, flags, ext_flags, NULL);
- if (!(priv->card_issues & CI_NO_EC384))
- _sc_card_add_ec_alg(card, 384, flags, ext_flags, NULL);
+ if (!(priv->card_issues & CI_NO_RANDOM))
+ card->caps |= SC_CARD_CAP_RNG;
- /* TODO may turn off SC_CARD_CAP_ISO7816_PIN_INFO later */
- card->caps |= SC_CARD_CAP_RNG | SC_CARD_CAP_ISO7816_PIN_INFO;
+ /* May turn off SC_CARD_CAP_ISO7816_PIN_INFO later */
+ card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO;
/*
* 800-73-3 cards may have a history object and/or a discovery object
@@ -3580,11 +3837,13 @@ static int piv_card_reader_lock_obtained
r = SC_ERROR_NO_CARD_SUPPORT;
} else {
r = piv_find_discovery(card);
+ sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH piv_find_discovery card->type:%d r:%d\n", card->type, r);
}
if (r < 0) {
if (was_reset > 0 || !(priv->card_issues & CI_PIV_AID_LOSE_STATE)) {
r = piv_select_aid(card, piv_aids[0].value, piv_aids[0].len_short, temp, &templen);
+ sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH piv_select_aid card->type:%d r:%d\n", card->type, r);
} else {
r = 0; /* cant do anything with this card, hope there was no interference */
}
Index: opensc-0.19.0/src/libopensc/cards.h
===================================================================
--- opensc-0.19.0.orig/src/libopensc/cards.h
+++ opensc-0.19.0/src/libopensc/cards.h
@@ -138,7 +138,13 @@ enum {
SC_CARD_TYPE_PIV_II_HIST,
SC_CARD_TYPE_PIV_II_NEO,
SC_CARD_TYPE_PIV_II_YUBIKEY4,
+ SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC,
SC_CARD_TYPE_PIV_II_GI_DE,
+ SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC,
+ SC_CARD_TYPE_PIV_II_GEMALTO,
+ SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC,
+ SC_CARD_TYPE_PIV_II_OBERTHUR,
+ SC_CARD_TYPE_PIV_II_PIVKEY,
/* MuscleApplet */
SC_CARD_TYPE_MUSCLE_BASE = 15000,

View File

@ -1,12 +0,0 @@
Index: opensc-0.19.0/src/pkcs15init/pkcs15-oberthur.c
===================================================================
--- opensc-0.19.0.orig/src/pkcs15init/pkcs15-oberthur.c
+++ opensc-0.19.0/src/pkcs15init/pkcs15-oberthur.c
@@ -70,7 +70,6 @@ cosm_write_tokeninfo (struct sc_pkcs15_c
ctx = p15card->card->ctx;
SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
- sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "cosm_write_tokeninfo() label '%s'; flags 0x%X", label, flags);
if (sc_profile_get_file(profile, COSM_TITLE"-token-info", &file)) {
rv = SC_ERROR_INCONSISTENT_PROFILE;
SC_TEST_GOTO_ERR(ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot find "COSM_TITLE"-token-info");

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2c5a0e4df9027635290b9c0f3addbbf0d651db5ddb0ab789cb0e978f02fd5826
size 2080320

3
opensc-0.21.0.tar.gz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2bfbbb1dcb4b8d8d75685a3e95c30798fb6411d4efab3690fd89d2cb25f3325e
size 2210878

View File

@ -1,3 +1,112 @@
-------------------------------------------------------------------
Fri Nov 27 19:27:30 UTC 2020 - Andreas Stieger <andreas.stieger@gmx.de>
- OpenSC 0.21.0:
* CVE-2020-26571: stack-based buffer overflow in the gemsafe GPK
smart card software driver (boo#1177380)
* CVE-2020-26572: stack-based buffer overflow in the TCOS smart
card software driver (boo#1177378)
* CVE-2020-26570: heap-based buffer overflow in the Oberthur
smart card software driver (boo#1177364)
* CardOS 5.x support boo#1179291
* Support for OAEP encryption, make SHA256 default
* New separate debug level for PIN commands
* Fix handling of card/reader insertion/removal events in pcscd
* Fixes of removed readers handling
* Fix Firefox crash because of invalid pcsc context
* PKCS#11: Return CKR_TOKEN_NOT_RECOGNIZED for not recognized cards
* Propagate ignore_user_content to PKCS#11 layer not to confuse applications
* Minidriver: Fix check of ATR length (2-to 33 characters inclusive)
* pkcs11-tool: allow using SW tokens
* opensc-explorer asn1 accepts offsets and decode records
* opensc-explorer cat accepts records
* OpenPGP: Add new ec curves supported by GNUK
* First steps supporting OpenPGP 3.4
* OpenPGP: Add support for EC key import
* Rutoken: Add ATR for Rutoken ECP SC NFC
* Improve detection of various CardOS 5 configurations
* DNIe: Add new DNIe CA structure for the secure channel
* ePass2003: Improve ECC support
* ePass2003: Fix erase sequence
* IAS-ECC: Fix support for Idemia Cosmo cards
* IAS-ECC: PIN padding settings are now used from PKCS#15 info when available
* IAS-ECC: Added PIN-pad support for PIN unblock
* New driver for Gemalto IDPrime (only some types)
* eDo: New driver with initial support for Polish eID card (e-dowód, eDO)
* MCRD: Remove unused and broken RSA EstEID support
* TCOS: Add missing encryption certificates
* PIV: Add ATR of DOD Yubikey
* fixed PIV global pin bug
* CAC1: Support changing PIN with CAC Alt tokens
- includes changes from 0.20.0
* CVE-2019-6502: memory leak in libopensc (boo#1122756)
* CVE-2019-15946: out-of-bounds access of an ASN.1 Octet string (boo#1149747)
* CVE-2019-15945: out-of-bounds access of an ASN.1 Bitstring (boo#1149746)
* CVE-2019-19479: incorrect read operation during parsing of a SETCOS file attribute (boo#1158256)
* CVE-2019-19480: improper free operation in sc_pkcs15_decode_prkdf_entry (boo#1158307)
* Support RSA-PSS signature mechanisms using RSA-RAW
* Added memory locking for secrets
* added support for terminal colors
* PC/SC driver: Fixed error handling in case of changing or removing the card reader
* rename md_read_only to read_only and use it for PKCS#11 and Minidriver
* allow global use of ignore_private_certificate
* PKCS#11: Implement write protection (CKF_WRITE_PROTECTED) based on the card profile
* PKCS#11: Add C_WrapKey and C_UnwrapKey implementations
* PKCS#11: Handle CKA_ALWAYS_AUTHENTICATE when creating key objects
* PKCS#11: Truncate long PKCS#11 labels with ...
* PKCS#11: Fixed recognition of a token when being unplugged and reinserted
* Minidriver: Register for CardOS5 cards
* Minidriver: Add support for RSA-PSS
* tools: Harmonize the use of option -r/--reader
* goid-tool: GoID personalization with fingerprint
* openpgp-tool: replace the options -L/--key-length with -t/--key-type
* openpgp-tool: add options -C/--card-info and -K/--key-info
* opensc-explorer: add command pin_info, extend random
* pkcs11-register: Auto-configuration of applications for use of OpenSC PKCS#11
* pkcd11-register: Autostart
* opensc-tool: Show ATR also for cards not recognized by OpenSC
* pkcs11-spy: parse CKM_AES_GCM, EC Derive parameters
* pkcs11-spy: Add support for CKA_OTP_* and CKM_*_PSS values
* pkcs11-tool: Support for signature verification via --verify
* pkcs11-tool: Add object type secrkey for --type option
* pkcs11-tool: Implement Secret Key write object
* pkcs11-tool: Add GOSTR3410-2012 support
* pkcs11-tool: Add support for testing CKM_RSA_PKCS_OAEP
* pkcs11-tool: Add extractable option to key import
* pkcs11-tool: list more key access flags when listing keys
* pkcs11-tool: Add support for CKA_ALLOWED_MECHANISMS when creating new objects and listing keys
* pkcs15-crypt: *Handle keys with user consent
* New separate CAC1 driver using the old CAC specification (#1502)
* CardOS: Add support for 4K RSA keys in CardOS 5
* CardOS: Fixed decryption with CardOS 5
* Enable CoolKey driver to handle 2048-bit keys
* EstEID: add support for a minimalistic, small and fast card profile based on IAS-ECC issued since December 2018
* GIDS Decipher fix (#1881)
* GIDS: Allow RSA 4K support
* MICARDO: Remove long expired EstEID 1.0/1.1 card support
* MyEID: Add support for unwrapping a secret key with an RSA key or secret key
* MyEID Add support for wrapping a secret key with a secret key
* Support for MyEID 4K RSA
* Support for OsEID
* Gemalto GemSafe: add new PTeID ATRs, add support for 4K RSA keys
* OpenPGP Card v3 ECC support
* Add Rutoken ECP SC
* Add Rutoken Lite
* Add SmartCard-HSM 4K ATR
* Add missing secp384r1 curve parameter
* Stacros: Fix decipher with 2.3
* Stacros: Add ATR for 2nd gen. eGK
* Stacros: Add new ATR for 3.5
* Stacros: Detect and allow Globalplatform PIN encoding
* Fix TCOS IDKey support
* TCOS: add encryption certificate for IDKey
* Infocamere, Postecert, Cnipa: Remove profiles
* Remove incomplete acos5 driver
- drop patches now upstream:
* opensc-0.19.0-piv_card_matching.patch
* opensc-0.19.0-redundant_logging.patch
* opensc-0.19.0-rsa-pss.patch
-------------------------------------------------------------------
Sun Aug 18 01:35:45 UTC 2019 - Jason Sikes <jsikes@suse.com>

View File

@ -1,7 +1,7 @@
#
# spec file for package opensc
#
# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
# Copyright (c) 2020 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@ -18,7 +18,7 @@
%define completionsdir %(pkg-config --variable completionsdir bash-completion)
Name: opensc
Version: 0.19.0
Version: 0.21.0
Release: 0
Summary: Smart Card Utilities
License: LGPL-2.1-or-later
@ -30,18 +30,14 @@ Source2: %{name}-rpmlintrc
# Register with p11-kit
# https://web.archive.org/web/20111225073733/http://www.opensc-project.org/opensc/ticket/390
Source3: opensc.module
Patch1: opensc-0.19.0-rsa-pss.patch
Patch2: opensc-0.19.0-redundant_logging.patch
Patch3: opensc-0.19.0-piv_card_matching.patch
BuildRequires: docbook-xsl-stylesheets
BuildRequires: libtool
BuildRequires: libxslt
BuildRequires: pkgconfig
BuildRequires: readline-devel
BuildRequires: zlib-devel
BuildRequires: pkgconfig(bash-completion)
BuildRequires: pkgconfig(libpcsclite)
BuildRequires: pkgconfig(openssl)
BuildRequires: pkgconfig(libpcsclite) >= 1.8.22
BuildRequires: pkgconfig(openssl) >= 1.0.1
Requires: pcsc-lite
# There is no more devel package.
Obsoletes: opensc-devel < %{version}
@ -63,18 +59,14 @@ may require third party proprietary software.
%prep
%setup -q
%patch1 -p1
%patch2 -p1
%patch3 -p1
%build
autoreconf -fvi
%configure \
--docdir=%{_docdir}/%{name} \
--disable-static \
--enable-doc \
--disable-silent-rules
make %{?_smp_mflags}
%make_build
%install
%make_install
@ -96,6 +88,7 @@ install -D -m 644 %{SOURCE3} %{buildroot}%{_sysconfdir}/pkcs11/modules/opensc.mo
%doc %{_docdir}/%{name}/opensc.conf
%{_bindir}/*
%{_datadir}/applications/*.desktop
%{_sysconfdir}/xdg/autostart/pkcs11-register.desktop
%{_datadir}/opensc
# Note: .la and .so must be in the main package, required by ltdl:
%{_libdir}/*.la