diff --git a/opensc-0.19.0-piv_card_matching.patch b/opensc-0.19.0-piv_card_matching.patch deleted file mode 100644 index 91451a5..0000000 --- a/opensc-0.19.0-piv_card_matching.patch +++ /dev/null @@ -1,644 +0,0 @@ -From 4ad599bf6c966310819fe3f8114f769d8f180947 Mon Sep 17 00:00:00 2001 -From: Doug Engert -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 -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ä -- * Copyright (C) 2005-2016 Douglas E. Engert -+ * Copyright (C) 2005-2018 Douglas E. Engert - * Copyright (C) 2006, Identity Alliance, Thomas Harning - * Copyright (C) 2007, EMC, Russell Larner - * -@@ -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, diff --git a/opensc-0.19.0-redundant_logging.patch b/opensc-0.19.0-redundant_logging.patch deleted file mode 100644 index 45b025b..0000000 --- a/opensc-0.19.0-redundant_logging.patch +++ /dev/null @@ -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"); diff --git a/opensc-0.19.0-rsa-pss.patch b/opensc-0.19.0-rsa-pss.patch deleted file mode 100644 index 37c7661..0000000 --- a/opensc-0.19.0-rsa-pss.patch +++ /dev/null @@ -1,2257 +0,0 @@ -From b85c0706db871828f0bc4672571dd0b9c98dd835 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Sun, 22 Jul 2018 16:23:54 +0200 -Subject: [PATCH 1/5] doc: Fix the pkcs11-tool example - -Signed-off-by: Jakub Jelen ---- - doc/tools/pkcs11-tool.1.xml | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml -index 37093f352..c609ec0e2 100644 ---- a/doc/tools/pkcs11-tool.1.xml -+++ b/doc/tools/pkcs11-tool.1.xml -@@ -568,7 +568,7 @@ - - To read the certificate with ID KEY_ID - in DER format from smart card: -- pkcs11-tool --read-object --id KEY_ID --type cert --outfile cert.der -+ pkcs11-tool --read-object --id KEY_ID --type cert --output-file cert.der - - To convert the certificate in DER format to PEM format, use OpenSSL - tools: - -From 5cc144111acb7b9982ddec7f7597a22c10c4d456 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Fri, 14 Sep 2018 14:11:18 +0200 -Subject: [PATCH 2/5] p11test: Add missing CKM_SHA224_RSA_PKCS_PSS - -Signed-off-by: Jakub Jelen ---- - src/tests/p11test/p11test_case_common.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/src/tests/p11test/p11test_case_common.c b/src/tests/p11test/p11test_case_common.c -index deb2a56fe..d44b0d8e3 100644 ---- a/src/tests/p11test/p11test_case_common.c -+++ b/src/tests/p11test/p11test_case_common.c -@@ -587,6 +587,8 @@ const char *get_mechanism_name(int mech_id) - return "RSA_PKCS_PSS"; - case CKM_SHA1_RSA_PKCS_PSS: - return "SHA1_RSA_PKCS_PSS"; -+ case CKM_SHA224_RSA_PKCS_PSS: -+ return "SHA224_RSA_PKCS_PSS"; - case CKM_SHA256_RSA_PKCS_PSS: - return "SHA256_RSA_PKCS_PSS"; - case CKM_SHA384_RSA_PKCS_PSS: - -From 5aa3dbcdd76af0197946252ff53a0636cb979ab3 Mon Sep 17 00:00:00 2001 -From: Nicholas Wilson -Date: Tue, 25 Aug 2015 12:45:27 +0100 -Subject: [PATCH 3/5] Add support for PSS padding to RSA signatures - -A card driver may declare support for computing the padding on the card, -or else the padding will be applied locally in padding.c. All five -PKCS11 PSS mechanisms are supported, for signature and verification. - -There are a few limits on what we choose to support, in particular I -don't see a need for arbitrary combinations of MGF hash, data hash, and -salt length, so I've restricted it (for the user's benefit) to the only -cases that really matter, where salt_len = hash_len and the same hash is -used for the MGF and data hashing. - ------------------------------------------------------------------------- -Reworked and extended in 2018 by Jakub Jelen against -current OpenSC master, to actually work with existing PIV cards: - * extended of missing mechanisms (SHA224, possibility to select MGF1) - * compatibility with OpenSSL 1.1+ - * Removed the ANSI padding - * Formatting cleanup, error checking - -Based on the original work from - -https://github.com/NWilson/OpenSC/commit/42f3199e66 - -Signed-off-by: Jakub Jelen ---- - src/libopensc/card-atrust-acos.c | 2 +- - src/libopensc/card-starcos.c | 4 +- - src/libopensc/internal.h | 2 +- - src/libopensc/opensc.h | 74 +++++++-- - src/libopensc/padding.c | 257 ++++++++++++++++++++++++++---- - src/libopensc/pkcs15-sec.c | 33 ++-- - src/pkcs11/framework-pkcs15.c | 265 +++++++++++++++++++++++-------- - src/pkcs11/mechanism.c | 31 +++- - src/pkcs11/openssl.c | 151 ++++++++++++++++-- - src/pkcs11/pkcs11.h | 3 +- - src/pkcs11/sc-pkcs11.h | 9 +- - 11 files changed, 674 insertions(+), 157 deletions(-) - -diff --git a/src/libopensc/card-atrust-acos.c b/src/libopensc/card-atrust-acos.c -index fb0b296c8..05ef0f441 100644 ---- a/src/libopensc/card-atrust-acos.c -+++ b/src/libopensc/card-atrust-acos.c -@@ -722,7 +722,7 @@ static int atrust_acos_compute_signature(struct sc_card *card, - flags = SC_ALGORITHM_RSA_HASH_NONE; - tmp_len = sizeof(sbuf); - r = sc_pkcs1_encode(card->ctx, flags, data, datalen, -- sbuf, &tmp_len, sizeof(sbuf)); -+ sbuf, &tmp_len, sizeof(sbuf)*8); - if (r < 0) - return r; - } else { -diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c -index 7ad132dc1..799c6a680 100644 ---- a/src/libopensc/card-starcos.c -+++ b/src/libopensc/card-starcos.c -@@ -1545,7 +1545,7 @@ static int starcos_compute_signature(sc_card_t *card, - flags = SC_ALGORITHM_RSA_HASH_NONE; - } - tmp_len = sizeof(sbuf); -- r = sc_pkcs1_encode(card->ctx, flags, data, datalen, sbuf, &tmp_len, sizeof(sbuf)); -+ r = sc_pkcs1_encode(card->ctx, flags, data, datalen, sbuf, &tmp_len, sizeof(sbuf)*8); - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "sc_pkcs1_encode failed"); - } else { - memcpy(sbuf, data, datalen); -@@ -1607,7 +1607,7 @@ static int starcos_compute_signature(sc_card_t *card, - flags = SC_ALGORITHM_RSA_HASH_NONE; - tmp_len = sizeof(sbuf); - r = sc_pkcs1_encode(card->ctx, flags, data, datalen, -- sbuf, &tmp_len, sizeof(sbuf)); -+ sbuf, &tmp_len, sizeof(sbuf)*8); - if (r < 0) - return r; - } else { -diff --git a/src/libopensc/internal.h b/src/libopensc/internal.h -index 9d6a77ffe..08d590f23 100644 ---- a/src/libopensc/internal.h -+++ b/src/libopensc/internal.h -@@ -159,7 +159,7 @@ int sc_pkcs1_strip_digest_info_prefix(unsigned int *algorithm, - * @return SC_SUCCESS on success and an error code otherwise - */ - int sc_pkcs1_encode(sc_context_t *ctx, unsigned long flags, -- const u8 *in, size_t inlen, u8 *out, size_t *outlen, size_t modlen); -+ const u8 *in, size_t inlen, u8 *out, size_t *outlen, size_t mod_bits); - /** - * Get the necessary padding and sec. env. flags. - * @param ctx IN sc_contex_t object -diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h -index b9b960d8f..a4e87d5bf 100644 ---- a/src/libopensc/opensc.h -+++ b/src/libopensc/opensc.h -@@ -93,19 +93,39 @@ extern "C" { - #define SC_ALGORITHM_NEED_USAGE 0x40000000 - #define SC_ALGORITHM_SPECIFIC_FLAGS 0x001FFFFF - --#define SC_ALGORITHM_RSA_RAW 0x00000001 - /* If the card is willing to produce a cryptogram padded with the following -- * methods, set these flags accordingly. */ --#define SC_ALGORITHM_RSA_PADS 0x0000001E --#define SC_ALGORITHM_RSA_PAD_NONE 0x00000000 --#define SC_ALGORITHM_RSA_PAD_PKCS1 0x00000002 -+ * methods, set these flags accordingly. These flags are exclusive: an RSA card -+ * must support at least one of them, and exactly one of them must be selected -+ * for a given operation. */ -+#define SC_ALGORITHM_RSA_RAW 0x00000001 -+#define SC_ALGORITHM_RSA_PADS 0x0000001F -+#define SC_ALGORITHM_RSA_PAD_NONE 0x00000001 -+#define SC_ALGORITHM_RSA_PAD_PKCS1 0x00000002 /* PKCS#1 v1.5 padding */ - #define SC_ALGORITHM_RSA_PAD_ANSI 0x00000004 - #define SC_ALGORITHM_RSA_PAD_ISO9796 0x00000008 --#define SC_ALGORITHM_RSA_PAD_PSS 0x00000010 -+#define SC_ALGORITHM_RSA_PAD_PSS 0x00000010 /* PKCS#1 v2.0 PSS */ - - /* If the card is willing to produce a cryptogram with the following -- * hash values, set these flags accordingly. */ --#define SC_ALGORITHM_RSA_HASH_NONE 0x00000100 -+ * hash values, set these flags accordingly. The interpretation of the hash -+ * flags depends on the algorithm and padding chosen: for RSA, the hash flags -+ * determine how the padding is constructed and do not describe the first -+ * hash applied to the document before padding begins. -+ * -+ * - For PAD_NONE, ANSI X9.31, (and ISO9796?), the hash value is therefore -+ * ignored. For ANSI X9.31, the input data must already have the hash -+ * identifier byte appended (eg 0x33 for SHA-1). -+ * - For PKCS1 (v1.5) the hash is recorded in the padding, and HASH_NONE is a -+ * valid value, meaning that the hash's DigestInfo has already been -+ * prepended to the data, otherwise the hash id is put on the front. -+ * - For PSS (PKCS#1 v2.0) the hash is used to derive the padding from the -+ * already-hashed message. -+ * -+ * In no case is the hash actually applied to the entire document. -+ * -+ * It's possible that the card may support different hashes for PKCS1 and PSS -+ * signatures; in this case the card driver has to pick the lowest-denominator -+ * when it sets these flags to indicate its capabilities. */ -+#define SC_ALGORITHM_RSA_HASH_NONE 0x00000100 /* only applies to PKCS1 padding */ - #define SC_ALGORITHM_RSA_HASH_SHA1 0x00000200 - #define SC_ALGORITHM_RSA_HASH_MD5 0x00000400 - #define SC_ALGORITHM_RSA_HASH_MD5_SHA1 0x00000800 -@@ -114,21 +134,39 @@ extern "C" { - #define SC_ALGORITHM_RSA_HASH_SHA384 0x00004000 - #define SC_ALGORITHM_RSA_HASH_SHA512 0x00008000 - #define SC_ALGORITHM_RSA_HASH_SHA224 0x00010000 --#define SC_ALGORITHM_RSA_HASHES 0x0001FE00 -- -+#define SC_ALGORITHM_RSA_HASHES 0x0001FF00 -+ -+/* This defines the hashes to be used with MGF1 in PSS padding */ -+#define SC_ALGORITHM_MGF1_SHA1 0x00100000 -+#define SC_ALGORITHM_MGF1_SHA256 0x00200000 -+#define SC_ALGORITHM_MGF1_SHA384 0x00400000 -+#define SC_ALGORITHM_MGF1_SHA512 0x00800000 -+#define SC_ALGORITHM_MGF1_SHA224 0x01000000 -+#define SC_ALGORITHM_MGF1_HASHES 0x01F00000 -+ -+/* These flags are exclusive: a GOST R34.10 card must support at least one or the -+ * other of the methods, and exactly one of them applies to any given operation. -+ * Note that the GOST R34.11 hash is actually applied to the data (ie if this -+ * algorithm is chosen the entire unhashed document is passed in). */ - #define SC_ALGORITHM_GOSTR3410_RAW 0x00020000 --#define SC_ALGORITHM_GOSTR3410_HASH_NONE 0x00040000 -+#define SC_ALGORITHM_GOSTR3410_HASH_NONE SC_ALGORITHM_GOSTR3410_RAW /*XXX*/ - #define SC_ALGORITHM_GOSTR3410_HASH_GOSTR3411 0x00080000 --#define SC_ALGORITHM_GOSTR3410_HASHES 0x00080000 --/*TODO: -DEE Should the above be 0x0000E000 */ --/* Or should the HASH_NONE be 0x00000010 and HASHES be 0x00008010 */ -- -+#define SC_ALGORITHM_GOSTR3410_HASHES 0x000A0000 -+/*TODO: -DEE Should the above be 0x000E0000 */ -+/* Or should the HASH_NONE be 0x00000100 and HASHES be 0x00080010 */ -+ -+/* The ECDSA flags are exclusive, and exactly one of them applies to any given -+ * operation. If ECDSA with a hash is specified, then the data passed in is -+ * the entire document, unhashed, and the hash is applied once to it before -+ * truncating and signing. These flags are distinct from the RSA hash flags, -+ * which determine the hash ids the card is willing to put in RSA message -+ * padding. */ - /* May need more bits if card can do more hashes */ - /* TODO: -DEE Will overload RSA_HASHES with EC_HASHES */ - /* Not clear if these need their own bits or not */ - /* The PIV card does not support and hashes */ --#define SC_ALGORITHM_ECDSA_RAW 0x00100000 - #define SC_ALGORITHM_ECDH_CDH_RAW 0x00200000 -+#define SC_ALGORITHM_ECDSA_RAW 0x00100000 - #define SC_ALGORITHM_ECDSA_HASH_NONE SC_ALGORITHM_RSA_HASH_NONE - #define SC_ALGORITHM_ECDSA_HASH_SHA1 SC_ALGORITHM_RSA_HASH_SHA1 - #define SC_ALGORITHM_ECDSA_HASH_SHA224 SC_ALGORITHM_RSA_HASH_SHA224 -@@ -142,7 +180,9 @@ extern "C" { - SC_ALGORITHM_ECDSA_HASH_SHA512) - - /* define mask of all algorithms that can do raw */ --#define SC_ALGORITHM_RAW_MASK (SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_GOSTR3410_RAW | SC_ALGORITHM_ECDSA_RAW) -+#define SC_ALGORITHM_RAW_MASK (SC_ALGORITHM_RSA_RAW | \ -+ SC_ALGORITHM_GOSTR3410_RAW | \ -+ SC_ALGORITHM_ECDSA_RAW) - - /* extended algorithm bits for selected mechs */ - #define SC_ALGORITHM_EXT_EC_F_P 0x00000001 -diff --git a/src/libopensc/padding.c b/src/libopensc/padding.c -index f544e5778..53a87c352 100644 ---- a/src/libopensc/padding.c -+++ b/src/libopensc/padding.c -@@ -23,6 +23,12 @@ - #include "config.h" - #endif - -+#ifdef ENABLE_OPENSSL -+#include -+#include -+#include -+#endif -+ - #include - #include - -@@ -231,22 +237,183 @@ int sc_pkcs1_strip_digest_info_prefix(unsigned int *algorithm, - return SC_ERROR_INTERNAL; - } - -+#ifdef ENABLE_OPENSSL -+ -+static const EVP_MD* hash_flag2md(unsigned int hash) -+{ -+ switch (hash & SC_ALGORITHM_RSA_HASHES) { -+ case SC_ALGORITHM_RSA_HASH_SHA1: -+ return EVP_sha1(); -+ case SC_ALGORITHM_RSA_HASH_SHA224: -+ return EVP_sha224(); -+ case SC_ALGORITHM_RSA_HASH_SHA256: -+ return EVP_sha256(); -+ case SC_ALGORITHM_RSA_HASH_SHA384: -+ return EVP_sha384(); -+ case SC_ALGORITHM_RSA_HASH_SHA512: -+ return EVP_sha512(); -+ default: -+ return NULL; -+ } -+} -+ -+static const EVP_MD* mgf1_flag2md(unsigned int mgf1) -+{ -+ switch (mgf1 & SC_ALGORITHM_MGF1_HASHES) { -+ case SC_ALGORITHM_MGF1_SHA1: -+ return EVP_sha1(); -+ case SC_ALGORITHM_MGF1_SHA224: -+ return EVP_sha224(); -+ case SC_ALGORITHM_MGF1_SHA256: -+ return EVP_sha256(); -+ case SC_ALGORITHM_MGF1_SHA384: -+ return EVP_sha384(); -+ case SC_ALGORITHM_MGF1_SHA512: -+ return EVP_sha512(); -+ default: -+ return NULL; -+ } -+} -+ -+/* add PKCS#1 v2.0 PSS padding */ -+static int sc_pkcs1_add_pss_padding(unsigned int hash, unsigned int mgf1_hash, -+ const u8 *in, size_t in_len, u8 *out, size_t *out_len, size_t mod_bits) -+{ -+ /* hLen = sLen in our case */ -+ int rv = SC_ERROR_INTERNAL, i, j, hlen, dblen, plen, round, mgf_rounds; -+ int mgf1_hlen; -+ const EVP_MD* md, *mgf1_md; -+ EVP_MD_CTX* ctx = NULL; -+ u8 buf[8]; -+ u8 salt[EVP_MAX_MD_SIZE], mask[EVP_MAX_MD_SIZE]; -+ size_t mod_length = (mod_bits + 7) / 8; -+ -+ if (*out_len < mod_length) -+ return SC_ERROR_BUFFER_TOO_SMALL; -+ -+ md = hash_flag2md(hash); -+ if (md == NULL) -+ return SC_ERROR_NOT_SUPPORTED; -+ hlen = EVP_MD_size(md); -+ dblen = mod_length - hlen - 1; /* emLen - hLen - 1 */ -+ plen = mod_length - 2*hlen - 1; -+ if (in_len != (unsigned)hlen) -+ return SC_ERROR_INVALID_ARGUMENTS; -+ if (2 * (unsigned)hlen + 2 > mod_length) -+ /* RSA key too small for chosen hash (1296 bits or higher needed for -+ * signing SHA-512 hashes) */ -+ return SC_ERROR_NOT_SUPPORTED; -+ -+ if (RAND_bytes(salt, hlen) != 1) -+ return SC_ERROR_INTERNAL; -+ -+ /* Hash M' to create H */ -+ if (!(ctx = EVP_MD_CTX_create())) -+ goto done; -+ memset(buf, 0x00, 8); -+ if (EVP_DigestInit_ex(ctx, md, NULL) != 1 || -+ EVP_DigestUpdate(ctx, buf, 8) != 1 || -+ EVP_DigestUpdate(ctx, in, hlen) != 1 || /* mHash */ -+ EVP_DigestUpdate(ctx, salt, hlen) != 1) { -+ goto done; -+ } -+ -+ /* Construct padding2, salt, H, and BC in the output block */ -+ /* DB = PS || 0x01 || salt */ -+ memset(out, 0x00, plen - 1); /* emLen - sLen - hLen - 2 */ -+ out[plen - 1] = 0x01; -+ memcpy(out + plen, salt, hlen); -+ if (EVP_DigestFinal_ex(ctx, out + dblen, NULL) != 1) { /* H */ -+ goto done; -+ } -+ out[dblen + hlen] = 0xBC; -+ /* EM = DB* || H || 0xbc -+ * *the first part is masked later */ -+ -+ /* Construct the DB mask block by block and XOR it in. */ -+ mgf1_md = mgf1_flag2md(mgf1_hash); -+ if (mgf1_md == NULL) -+ return SC_ERROR_NOT_SUPPORTED; -+ mgf1_hlen = EVP_MD_size(mgf1_md); -+ -+ mgf_rounds = (dblen + mgf1_hlen - 1) / mgf1_hlen; /* round up */ -+ for (round = 0; round < mgf_rounds; ++round) { -+ buf[0] = (round&0xFF000000U) >> 24; -+ buf[1] = (round&0x00FF0000U) >> 16; -+ buf[2] = (round&0x0000FF00U) >> 8; -+ buf[3] = (round&0x000000FFU); -+ if (EVP_DigestInit_ex(ctx, mgf1_md, NULL) != 1 || -+ EVP_DigestUpdate(ctx, out + dblen, hlen) != 1 || /* H (Z parameter of MGF1) */ -+ EVP_DigestUpdate(ctx, buf, 4) != 1 || /* C */ -+ EVP_DigestFinal_ex(ctx, mask, NULL)) { -+ goto done; -+ } -+ /* this is no longer part of the MGF1, but actually -+ * XORing mask with DB to create maskedDB inplace */ -+ for (i = round * mgf1_hlen, j = 0; i < dblen && j < mgf1_hlen; ++i, ++j) { -+ out[i] ^= mask[j]; -+ } -+ } -+ -+ /* Set leftmost N bits in leftmost octet in maskedDB to zero -+ * to make sure the result is smaller than the modulus ( +1) -+ */ -+ out[0] &= (0xff >> (8 * mod_length - mod_bits + 1)); -+ -+ *out_len = mod_length; -+ rv = SC_SUCCESS; -+ -+done: -+ OPENSSL_cleanse(salt, sizeof(salt)); -+ OPENSSL_cleanse(mask, sizeof(mask)); -+ if (ctx) { -+ EVP_MD_CTX_destroy(ctx); -+ } -+ return rv; -+} -+ -+static int hash_len2algo(size_t hash_len) -+{ -+ switch (hash_len) { -+ case SHA_DIGEST_LENGTH: -+ return SC_ALGORITHM_RSA_HASH_SHA1; -+ case SHA224_DIGEST_LENGTH: -+ return SC_ALGORITHM_RSA_HASH_SHA224; -+ case SHA256_DIGEST_LENGTH: -+ return SC_ALGORITHM_RSA_HASH_SHA256; -+ case SHA384_DIGEST_LENGTH: -+ return SC_ALGORITHM_RSA_HASH_SHA384; -+ case SHA512_DIGEST_LENGTH: -+ return SC_ALGORITHM_RSA_HASH_SHA512; -+ } -+ /* Should never happen -- the mechanism and data should be already -+ * verified to match one of the above. If not, we will fail later -+ */ -+ return SC_ALGORITHM_RSA_HASH_NONE; -+} -+#endif -+ - /* general PKCS#1 encoding function */ - int sc_pkcs1_encode(sc_context_t *ctx, unsigned long flags, -- const u8 *in, size_t in_len, u8 *out, size_t *out_len, size_t mod_len) -+ const u8 *in, size_t in_len, u8 *out, size_t *out_len, size_t mod_bits) - { - int rv, i; - size_t tmp_len = *out_len; - const u8 *tmp = in; - unsigned int hash_algo, pad_algo; -+ size_t mod_len = (mod_bits + 7) / 8; -+#ifdef ENABLE_OPENSSL -+ unsigned int mgf1_hash; -+#endif - - LOG_FUNC_CALLED(ctx); - -- hash_algo = flags & (SC_ALGORITHM_RSA_HASHES | SC_ALGORITHM_RSA_HASH_NONE); -+ hash_algo = flags & SC_ALGORITHM_RSA_HASHES; - pad_algo = flags & SC_ALGORITHM_RSA_PADS; - sc_log(ctx, "hash algorithm 0x%X, pad algorithm 0x%X", hash_algo, pad_algo); - -- if (hash_algo != SC_ALGORITHM_RSA_HASH_NONE) { -+ if ((pad_algo == SC_ALGORITHM_RSA_PAD_PKCS1 || !pad_algo) && -+ hash_algo != SC_ALGORITHM_RSA_HASH_NONE) { - i = sc_pkcs1_add_digest_info_prefix(hash_algo, in, in_len, out, &tmp_len); - if (i != SC_SUCCESS) { - sc_log(ctx, "Unable to add digest info 0x%x", hash_algo); -@@ -268,10 +435,29 @@ int sc_pkcs1_encode(sc_context_t *ctx, unsigned long flags, - /* add pkcs1 bt01 padding */ - rv = sc_pkcs1_add_01_padding(tmp, tmp_len, out, out_len, mod_len); - LOG_FUNC_RETURN(ctx, rv); -+ case SC_ALGORITHM_RSA_PAD_PSS: -+ /* add PSS padding */ -+#ifdef ENABLE_OPENSSL -+ mgf1_hash = flags & SC_ALGORITHM_MGF1_HASHES; -+ if (hash_algo == SC_ALGORITHM_RSA_HASH_NONE) { -+ /* this is generic RSA_PKCS1_PSS mechanism with hash -+ * already done outside of the module. The parameters -+ * were already checked so we need to adjust the hash -+ * algorithm to do the padding with the correct hash -+ * function. -+ */ -+ hash_algo = hash_len2algo(tmp_len); -+ } -+ rv = sc_pkcs1_add_pss_padding(hash_algo, mgf1_hash, -+ tmp, tmp_len, out, out_len, mod_bits); -+#else -+ rv = SC_ERROR_NOT_SUPPORTED; -+#endif -+ LOG_FUNC_RETURN(ctx, rv); - default: -- /* currently only pkcs1 padding is supported */ -- sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Unsupported padding algorithm 0x%x", pad_algo); -- LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); -+ /* We shouldn't be called with an unexpected padding type, we've already -+ * returned SC_ERROR_NOT_SUPPORTED if the card can't be used. */ -+ LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); - } - } - -@@ -279,42 +465,45 @@ int sc_get_encoding_flags(sc_context_t *ctx, - unsigned long iflags, unsigned long caps, - unsigned long *pflags, unsigned long *sflags) - { -- size_t i; -- - LOG_FUNC_CALLED(ctx); - if (pflags == NULL || sflags == NULL) - LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); - - sc_log(ctx, "iFlags 0x%lX, card capabilities 0x%lX", iflags, caps); -- for (i = 0; digest_info_prefix[i].algorithm != 0; i++) { -- if (iflags & digest_info_prefix[i].algorithm) { -- if (digest_info_prefix[i].algorithm != SC_ALGORITHM_RSA_HASH_NONE && -- caps & digest_info_prefix[i].algorithm) -- *sflags |= digest_info_prefix[i].algorithm; -- else -- *pflags |= digest_info_prefix[i].algorithm; -- break; -- } -- } - -- if (iflags & SC_ALGORITHM_RSA_PAD_PKCS1) { -- if (caps & SC_ALGORITHM_RSA_PAD_PKCS1) -- *sflags |= SC_ALGORITHM_RSA_PAD_PKCS1; -- else -- *pflags |= SC_ALGORITHM_RSA_PAD_PKCS1; -- } else if ((iflags & SC_ALGORITHM_RSA_PADS) == SC_ALGORITHM_RSA_PAD_NONE) { -- -- /* Work with RSA, EC and maybe GOSTR? */ -- if (!(caps & SC_ALGORITHM_RAW_MASK)) -- LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "raw encryption is not supported"); -+ /* For ECDSA and GOSTR, we don't do any padding or hashing ourselves, the -+ * card has to support the requested operation. Similarly, for RSA with -+ * raw padding (raw RSA) and ISO9796, we require the card to do it for us. -+ * Finally, for PKCS1 (v1.5 and PSS) and ASNI X9.31 we can apply the padding -+ * ourselves if the card supports raw RSA. */ - -- *sflags |= (caps & SC_ALGORITHM_RAW_MASK); /* adds in the one raw type */ -+ /* TODO: Could convert GOSTR3410_HASH_GOSTR3411 -> GOSTR3410_RAW and -+ * ECDSA_HASH_ -> ECDSA_RAW using OpenSSL (not much benefit though). */ -+ -+ if ((caps & iflags) == iflags) { -+ /* Card supports the signature operation we want to do, great, let's -+ * go with it then. */ -+ *sflags = iflags; - *pflags = 0; -- } else if (iflags & SC_ALGORITHM_RSA_PAD_PSS) { -- if (caps & SC_ALGORITHM_RSA_PAD_PSS) -- *sflags |= SC_ALGORITHM_RSA_PAD_PSS; -- else -- *pflags |= SC_ALGORITHM_RSA_PAD_PSS; -+ -+ } else if ((caps & SC_ALGORITHM_RSA_PAD_PSS) && -+ (iflags & SC_ALGORITHM_RSA_PAD_PSS)) { -+ *sflags |= SC_ALGORITHM_RSA_PAD_PSS; -+ -+ } else if (((caps & SC_ALGORITHM_RSA_RAW) && -+ (iflags & SC_ALGORITHM_RSA_PAD_PKCS1)) -+ || iflags & SC_ALGORITHM_RSA_PAD_PSS) { -+ /* Use the card's raw RSA capability on the padded input */ -+ *sflags = SC_ALGORITHM_RSA_PAD_NONE; -+ *pflags = iflags; -+ -+ } else if ((caps & (SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE)) && -+ (iflags & SC_ALGORITHM_RSA_PAD_PKCS1)) { -+ /* A corner case - the card can partially do PKCS1, if we prepend the -+ * DigestInfo bit it will do the rest. */ -+ *sflags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE; -+ *pflags = iflags & SC_ALGORITHM_RSA_HASHES; -+ - } else { - LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "unsupported algorithm"); - } -diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c -index 6ee4fa3c7..3e7e03b12 100644 ---- a/src/libopensc/pkcs15-sec.c -+++ b/src/libopensc/pkcs15-sec.c -@@ -329,7 +329,7 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, - - switch (obj->type) { - case SC_PKCS15_TYPE_PRKEY_RSA: -- modlen = prkey->modulus_length / 8; -+ modlen = (prkey->modulus_length + 7) / 8; - break; - case SC_PKCS15_TYPE_PRKEY_GOSTR3410: - modlen = (prkey->modulus_length + 7) / 8 * 2; -@@ -377,7 +377,8 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, - if (modlen > tmplen) - LOG_TEST_RET(ctx, SC_ERROR_NOT_ALLOWED, "Buffer too small, needs recompile!"); - -- r = sc_pkcs1_encode(ctx, flags, in, inlen, buf, &tmplen, modlen); -+ /* XXX Assuming RSA key here */ -+ r = sc_pkcs1_encode(ctx, flags, in, inlen, buf, &tmplen, prkey->modulus_length); - - /* no padding needed - already done */ - flags &= ~SC_ALGORITHM_RSA_PADS; -@@ -391,10 +392,15 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, - } - - -- /* If the card doesn't support the requested algorithm, see if we -- * can strip the input so a more restrictive algo can be used */ -+ /* If the card doesn't support the requested algorithm, we normally add the -+ * padding here in software and ask the card to do a raw signature. There's -+ * one exception to that, where we might be able to get the signature to -+ * succeed by stripping padding if the card only offers higher-level -+ * signature operations. The only thing we can strip is the DigestInfo -+ * block from PKCS1 padding. */ - if ((flags == (SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE)) && -- !(alg_info->flags & (SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_HASH_NONE))) { -+ !(alg_info->flags & SC_ALGORITHM_RSA_RAW) && -+ !(alg_info->flags & (SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE))) { - unsigned int algo; - size_t tmplen = sizeof(buf); - -@@ -420,19 +426,16 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, - - /* add the padding bytes (if necessary) */ - if (pad_flags != 0) { -- if (flags & SC_ALGORITHM_RSA_PAD_PSS) { -- // TODO PSS padding -- } else { -- size_t tmplen = sizeof(buf); -- -- r = sc_pkcs1_encode(ctx, pad_flags, tmp, inlen, tmp, &tmplen, modlen); -- SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Unable to add padding"); -+ size_t tmplen = sizeof(buf); - -- inlen = tmplen; -- } -+ /* XXX Assuming RSA key here */ -+ r = sc_pkcs1_encode(ctx, pad_flags, tmp, inlen, tmp, &tmplen, -+ prkey->modulus_length); -+ SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Unable to add padding"); -+ inlen = tmplen; - } - else if ( senv.algorithm == SC_ALGORITHM_RSA && -- (flags & SC_ALGORITHM_RSA_PADS) == SC_ALGORITHM_RSA_PAD_NONE) { -+ (flags & SC_ALGORITHM_RSA_PADS) == SC_ALGORITHM_RSA_PAD_NONE) { - /* Add zero-padding if input is shorter than the modulus */ - if (inlen < modlen) { - if (modlen > sizeof(buf)) -diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c -index 80f9ce89f..a75d239f4 100644 ---- a/src/pkcs11/framework-pkcs15.c -+++ b/src/pkcs11/framework-pkcs15.c -@@ -3478,7 +3478,8 @@ struct sc_pkcs11_object_ops pkcs15_cert_ops = { - NULL, /* unwrap_key */ - NULL, /* decrypt */ - NULL, /* derive */ -- NULL /* can_do */ -+ NULL, /* can_do */ -+ NULL /* init_params */ - }; - - /* -@@ -3703,53 +3704,44 @@ static CK_RV - pkcs15_prkey_check_pss_param(CK_MECHANISM_PTR pMechanism, CK_ULONG hlen) - { - CK_RSA_PKCS_PSS_PARAMS *pss_param; -- -- if (pMechanism->pParameter == NULL) -- return CKR_OK; // Support applications that don't provide CK_RSA_PKCS_PSS_PARAMS -- -- if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) -- return CKR_MECHANISM_PARAM_INVALID; -+ int i; -+ const unsigned int hash_lens[5] = { 160, 256, 385, 512, 224 }; -+ const unsigned int hashes[5] = { CKM_SHA_1, CKM_SHA256, -+ CKM_SHA384, CKM_SHA512, CKM_SHA224 }; - - pss_param = (CK_RSA_PKCS_PSS_PARAMS *)pMechanism->pParameter; - -- // Hash parameter must match mechanisms or length of data supplied for CKM_RSA_PKCS_PSS -- switch(pss_param->hashAlg) { -- case CKM_SHA_1: -- if (hlen != 20) -- return CKR_MECHANISM_PARAM_INVALID; -- break; -- case CKM_SHA256: -- if (hlen != 32) -+ // Hash parameter must match length of data supplied for CKM_RSA_PKCS_PSS -+ for (i = 0; i < 5; i++) { -+ if (pss_param->hashAlg == hashes[i] -+ && hlen != hash_lens[i]/8) - return CKR_MECHANISM_PARAM_INVALID; -- break; -- default: -- return CKR_MECHANISM_PARAM_INVALID; - } -+ /* other aspects of pss params were already verified during SignInit */ - -- // SmartCards typically only support MGFs based on the same hash as the -- // message digest -- switch(pss_param->mgf) { -- case CKG_MGF1_SHA1: -- if (hlen != 20) -- return CKR_MECHANISM_PARAM_INVALID; -+ return CKR_OK; -+} -+ -+static int mgf2flags(CK_RSA_PKCS_MGF_TYPE mgf) -+{ -+ switch (mgf) { -+ case CKG_MGF1_SHA224: -+ return SC_ALGORITHM_MGF1_SHA224; - break; - case CKG_MGF1_SHA256: -- if (hlen != 32) -- return CKR_MECHANISM_PARAM_INVALID; -- break; -+ return SC_ALGORITHM_MGF1_SHA256; -+ case CKG_MGF1_SHA384: -+ return SC_ALGORITHM_MGF1_SHA384; -+ case CKG_MGF1_SHA512: -+ return SC_ALGORITHM_MGF1_SHA512; -+ case CKG_MGF1_SHA1: -+ return SC_ALGORITHM_MGF1_SHA1; - default: -- return CKR_MECHANISM_PARAM_INVALID; -+ return -1; - } -- -- // SmartCards typically support only a salt length equal to the hash length -- if (pss_param->sLen != hlen) -- return CKR_MECHANISM_PARAM_INVALID; -- -- return CKR_OK; - } - - -- - static CK_RV - pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj, - CK_MECHANISM_PTR pMechanism, CK_BYTE_PTR pData, -@@ -3798,35 +3790,74 @@ pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj, - case CKM_SHA512_RSA_PKCS: - flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA512; - break; -+ case CKM_RIPEMD160_RSA_PKCS: -+ flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_RIPEMD160; -+ break; -+ case CKM_RSA_X_509: -+ flags = SC_ALGORITHM_RSA_RAW; -+ break; - case CKM_RSA_PKCS_PSS: -- rv = pkcs15_prkey_check_pss_param(pMechanism, (int)ulDataLen); -+ flags = SC_ALGORITHM_RSA_PAD_PSS; -+ /* The hash was done ouside of the module */ -+ flags |= SC_ALGORITHM_RSA_HASH_NONE; -+ /* Omited parameter can use MGF1-SHA1 ? */ -+ if (pMechanism->pParameter == NULL) { -+ flags |= SC_ALGORITHM_MGF1_SHA1; -+ if (ulDataLen != SHA_DIGEST_LENGTH) -+ return CKR_MECHANISM_PARAM_INVALID; -+ break; -+ } - -- if (rv != CKR_OK) -+ /* Check the data length matches the selected hash */ -+ rv = pkcs15_prkey_check_pss_param(pMechanism, (int)ulDataLen); -+ if (rv != CKR_OK) { -+ sc_log(context, "Invalid data lenght for the selected " -+ "PSS parameters"); - return rv; -+ } - -- flags = SC_ALGORITHM_RSA_PAD_PSS | SC_ALGORITHM_RSA_HASH_NONE; -- break; -- case CKM_SHA1_RSA_PKCS_PSS: -- rv = pkcs15_prkey_check_pss_param(pMechanism, 20); -- -- if (rv != CKR_OK) -- return rv; -+ /* The MGF parameter was already verified in SignInit() */ -+ flags |= mgf2flags(((CK_RSA_PKCS_PSS_PARAMS*)pMechanism->pParameter)->mgf); - -- flags = SC_ALGORITHM_RSA_PAD_PSS | SC_ALGORITHM_RSA_HASH_SHA1; -+ /* Assuming salt is the size of hash */ - break; -+ case CKM_SHA1_RSA_PKCS_PSS: -+ case CKM_SHA224_RSA_PKCS_PSS: - case CKM_SHA256_RSA_PKCS_PSS: -- rv = pkcs15_prkey_check_pss_param(pMechanism, 32); -+ case CKM_SHA384_RSA_PKCS_PSS: -+ case CKM_SHA512_RSA_PKCS_PSS: -+ flags = SC_ALGORITHM_RSA_PAD_PSS; -+ /* Omited parameter can use MGF1-SHA1 and SHA1 hash ? */ -+ if (pMechanism->pParameter == NULL) { -+ flags |= SC_ALGORITHM_RSA_HASH_SHA1; -+ flags |= SC_ALGORITHM_MGF1_SHA1; -+ break; -+ } - -- if (rv != CKR_OK) -- return rv; -+ switch (((CK_RSA_PKCS_PSS_PARAMS*)pMechanism->pParameter)->hashAlg) { -+ case CKM_SHA_1: -+ flags |= SC_ALGORITHM_RSA_HASH_SHA1; -+ break; -+ case CKM_SHA224: -+ flags |= SC_ALGORITHM_RSA_HASH_SHA224; -+ break; -+ case CKM_SHA256: -+ flags |= SC_ALGORITHM_RSA_HASH_SHA256; -+ break; -+ case CKM_SHA384: -+ flags |= SC_ALGORITHM_RSA_HASH_SHA384; -+ break; -+ case CKM_SHA512: -+ flags |= SC_ALGORITHM_RSA_HASH_SHA512; -+ break; -+ default: -+ return CKR_MECHANISM_PARAM_INVALID; -+ } - -- flags = SC_ALGORITHM_RSA_PAD_PSS | SC_ALGORITHM_RSA_HASH_SHA256; -- break; -- case CKM_RIPEMD160_RSA_PKCS: -- flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_RIPEMD160; -- break; -- case CKM_RSA_X_509: -- flags = SC_ALGORITHM_RSA_RAW; -+ /* The MGF parameter was already verified in SignInit() */ -+ flags |= mgf2flags(((CK_RSA_PKCS_PSS_PARAMS*)pMechanism->pParameter)->mgf); -+ -+ /* Assuming salt is the size of hash */ - break; - case CKM_GOSTR3410: - flags = SC_ALGORITHM_GOSTR3410_HASH_NONE; -@@ -4074,6 +4105,76 @@ pkcs15_prkey_can_do(struct sc_pkcs11_session *session, void *obj, - } - - -+static CK_RV -+pkcs15_prkey_init_params(struct sc_pkcs11_session *session, -+ CK_MECHANISM_PTR pMechanism) -+{ -+ const CK_RSA_PKCS_PSS_PARAMS *pss_params; -+ unsigned int expected_hash = 0, i; -+ unsigned int expected_salt_len = 0; -+ const unsigned int salt_lens[5] = { 160, 256, 384, 512, 224 }; -+ const unsigned int hashes[5] = { CKM_SHA_1, CKM_SHA256, -+ CKM_SHA384, CKM_SHA512, CKM_SHA224 }; -+ -+ switch (pMechanism->mechanism) { -+ case CKM_RSA_PKCS_PSS: -+ case CKM_SHA1_RSA_PKCS_PSS: -+ case CKM_SHA224_RSA_PKCS_PSS: -+ case CKM_SHA256_RSA_PKCS_PSS: -+ case CKM_SHA384_RSA_PKCS_PSS: -+ case CKM_SHA512_RSA_PKCS_PSS: -+ if (!pMechanism->pParameter || -+ pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) -+ return CKR_MECHANISM_PARAM_INVALID; -+ -+ pss_params = (CK_RSA_PKCS_PSS_PARAMS*)pMechanism->pParameter; -+ if (pss_params->mgf < CKG_MGF1_SHA1 || pss_params->mgf > CKG_MGF1_SHA224) -+ return CKR_MECHANISM_PARAM_INVALID; -+ -+ /* The hashAlg field can have any value for CKM_RSA_PKCS_PSS and must be -+ * used again in the PSS padding; for the other mechanisms it strictly -+ * must match the padding declared in the mechanism. -+ */ -+ if (pMechanism->mechanism == CKM_SHA1_RSA_PKCS_PSS) { -+ expected_hash = CKM_SHA_1; -+ expected_salt_len = 160; -+ } else if (pMechanism->mechanism == CKM_SHA224_RSA_PKCS_PSS) { -+ expected_hash = CKM_SHA224; -+ expected_salt_len = 224; -+ } else if (pMechanism->mechanism == CKM_SHA256_RSA_PKCS_PSS) { -+ expected_hash = CKM_SHA256; -+ expected_salt_len = 256; -+ } else if (pMechanism->mechanism == CKM_SHA384_RSA_PKCS_PSS) { -+ expected_hash = CKM_SHA384; -+ expected_salt_len = 384; -+ } else if (pMechanism->mechanism == CKM_SHA512_RSA_PKCS_PSS) { -+ expected_hash = CKM_SHA512; -+ expected_salt_len = 512; -+ } else if (pMechanism->mechanism == CKM_RSA_PKCS_PSS) { -+ for (i = 0; i < 5; ++i) { -+ if (hashes[i] == pss_params->hashAlg) { -+ expected_hash = hashes[i]; -+ expected_salt_len = salt_lens[i]; -+ } -+ } -+ } -+ -+ if (expected_hash != pss_params->hashAlg) -+ return CKR_MECHANISM_PARAM_INVALID; -+ -+ /* We're strict, and only do PSS signatures with a salt length that -+ * matches the digest length (any shorter is rubbish, any longer -+ * is useless). */ -+ if (pss_params->sLen != expected_salt_len / 8) -+ return CKR_MECHANISM_PARAM_INVALID; -+ -+ /* TODO support different salt lengths */ -+ break; -+ } -+ return CKR_OK; -+} -+ -+ - struct sc_pkcs11_object_ops pkcs15_prkey_ops = { - pkcs15_prkey_release, - pkcs15_prkey_set_attribute, -@@ -4084,8 +4185,9 @@ struct sc_pkcs11_object_ops pkcs15_prkey_ops = { - pkcs15_prkey_sign, - NULL, /* unwrap */ - pkcs15_prkey_decrypt, -- pkcs15_prkey_derive, -- pkcs15_prkey_can_do -+ pkcs15_prkey_derive, -+ pkcs15_prkey_can_do, -+ pkcs15_prkey_init_params, - }; - - /* -@@ -4322,7 +4424,8 @@ struct sc_pkcs11_object_ops pkcs15_pubkey_ops = { - NULL, /* unwrap_key */ - NULL, /* decrypt */ - NULL, /* derive */ -- NULL /* can_do */ -+ NULL, /* can_do */ -+ NULL /* init_params */ - }; - - -@@ -4500,7 +4603,8 @@ struct sc_pkcs11_object_ops pkcs15_dobj_ops = { - NULL, /* unwrap_key */ - NULL, /* decrypt */ - NULL, /* derive */ -- NULL /* can_do */ -+ NULL, /* can_do */ -+ NULL /* init_params */ - }; - - -@@ -4629,7 +4733,8 @@ struct sc_pkcs11_object_ops pkcs15_skey_ops = { - NULL, /* unwrap_key */ - NULL, /* decrypt */ - NULL, /* derive */ -- NULL /* can_do */ -+ NULL, /* can_do */ -+ NULL /* init_params */ - }; - - /* -@@ -5040,6 +5145,17 @@ register_mechanisms(struct sc_pkcs11_card *p11card) - /* We support PKCS1 padding in software */ - /* either the card supports it or OpenSC does */ - rsa_flags |= SC_ALGORITHM_RSA_PAD_PKCS1; -+#ifdef ENABLE_OPENSSL -+ rsa_flags |= SC_ALGORITHM_RSA_PAD_PSS; -+#endif -+ } -+ -+ if (rsa_flags & SC_ALGORITHM_RSA_PAD_ISO9796) { -+ /* Supported in hardware only, if the card driver declares it. */ -+ mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_9796, &mech_info, CKK_RSA, NULL, NULL); -+ rc = sc_pkcs11_register_mechanism(p11card, mt); -+ if (rc != CKR_OK) -+ return rc; - } - - #ifdef ENABLE_OPENSSL -@@ -5098,23 +5214,40 @@ register_mechanisms(struct sc_pkcs11_card *p11card) - #endif /* ENABLE_OPENSSL */ - } - -- /* TODO support other padding mechanisms */ -- - if (rsa_flags & SC_ALGORITHM_RSA_PAD_PSS) { -- mech_info.flags &= ~(CKF_DECRYPT|CKF_VERIFY); -- -+ mech_info.flags &= ~(CKF_DECRYPT|CKF_ENCRYPT); - mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_PKCS_PSS, &mech_info, CKK_RSA, NULL, NULL); - rc = sc_pkcs11_register_mechanism(p11card, mt); - if (rc != CKR_OK) - return rc; - - if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA1) { -- rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, CKM_SHA1_RSA_PKCS_PSS, CKM_SHA_1, mt); -+ rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, -+ CKM_SHA1_RSA_PKCS_PSS, CKM_SHA_1, mt); -+ if (rc != CKR_OK) -+ return rc; -+ } -+ if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA224) { -+ rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, -+ CKM_SHA224_RSA_PKCS_PSS, CKM_SHA224, mt); - if (rc != CKR_OK) - return rc; - } - if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA256) { -- rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, CKM_SHA256_RSA_PKCS_PSS, CKM_SHA256, mt); -+ rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, -+ CKM_SHA256_RSA_PKCS_PSS, CKM_SHA256, mt); -+ if (rc != CKR_OK) -+ return rc; -+ } -+ if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA384) { -+ rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, -+ CKM_SHA384_RSA_PKCS_PSS, CKM_SHA384, mt); -+ if (rc != CKR_OK) -+ return rc; -+ } -+ if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA512) { -+ rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, -+ CKM_SHA512_RSA_PKCS_PSS, CKM_SHA512, mt); - if (rc != CKR_OK) - return rc; - } -diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c -index 5f006c839..d4ce7fef5 100644 ---- a/src/pkcs11/mechanism.c -+++ b/src/pkcs11/mechanism.c -@@ -262,11 +262,20 @@ sc_pkcs11_sign_init(struct sc_pkcs11_session *session, CK_MECHANISM_PTR pMechani - if (mt->key_type != key_type) - LOG_FUNC_RETURN(context, CKR_KEY_TYPE_INCONSISTENT); - -+ if (pMechanism->pParameter && -+ pMechanism->ulParameterLen > sizeof(operation->mechanism_params)) -+ LOG_FUNC_RETURN(context, CKR_ARGUMENTS_BAD); -+ - rv = session_start_operation(session, SC_PKCS11_OPERATION_SIGN, mt, &operation); - if (rv != CKR_OK) - LOG_FUNC_RETURN(context, rv); - - memcpy(&operation->mechanism, pMechanism, sizeof(CK_MECHANISM)); -+ if (pMechanism->pParameter) { -+ memcpy(&operation->mechanism_params, pMechanism->pParameter, -+ pMechanism->ulParameterLen); -+ operation->mechanism.pParameter = &operation->mechanism_params; -+ } - rv = mt->sign_init(operation, key); - if (rv != CKR_OK) - session_stop_operation(session, SC_PKCS11_OPERATION_SIGN); -@@ -387,6 +396,16 @@ sc_pkcs11_signature_init(sc_pkcs11_operation_t *operation, - } - } - -+ /* Validate the mechanism parameters */ -+ if (key->ops->init_params) { -+ rv = key->ops->init_params(operation->session, &operation->mechanism); -+ if (rv != CKR_OK) { -+ /* Probably bad arguments */ -+ free(data); -+ LOG_FUNC_RETURN(context, rv); -+ } -+ } -+ - /* If this is a signature with hash operation, - * and card cannot perform itself signature with hash operation, - * set up the hash operation */ -@@ -636,6 +655,16 @@ sc_pkcs11_verify_init(sc_pkcs11_operation_t *operation, - } - } - -+ /* Validate the mechanism parameters */ -+ if (key->ops->init_params) { -+ rv = key->ops->init_params(operation->session, &operation->mechanism); -+ if (rv != CKR_OK) { -+ /* Probably bad arguments */ -+ free(data); -+ LOG_FUNC_RETURN(context, rv); -+ } -+ } -+ - /* If this is a verify with hash operation, set up the - * hash operation */ - info = (struct hash_signature_info *) operation->type->mech_data; -@@ -729,7 +758,7 @@ sc_pkcs11_verify_final(sc_pkcs11_operation_t *operation, - - rv = sc_pkcs11_verify_data(pubkey_value, attr.ulValueLen, - params, sizeof(params), -- operation->mechanism.mechanism, data->md, -+ &operation->mechanism, data->md, - data->buffer, data->buffer_len, pSignature, ulSignatureLen); - - done: -diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c -index 59de1210d..e8b246145 100644 ---- a/src/pkcs11/openssl.c -+++ b/src/pkcs11/openssl.c -@@ -68,6 +68,23 @@ static sc_pkcs11_mechanism_type_t openssl_sha1_mech = { - NULL, /* free_mech_data */ - }; - -+static sc_pkcs11_mechanism_type_t openssl_sha224_mech = { -+ CKM_SHA224, -+ { 0, 0, CKF_DIGEST }, -+ 0, -+ sizeof(struct sc_pkcs11_operation), -+ sc_pkcs11_openssl_md_release, -+ sc_pkcs11_openssl_md_init, -+ sc_pkcs11_openssl_md_update, -+ sc_pkcs11_openssl_md_final, -+ NULL, NULL, NULL, NULL, /* sign_* */ -+ NULL, NULL, NULL, /* verif_* */ -+ NULL, NULL, /* decrypt_* */ -+ NULL, /* derive */ -+ NULL, /* mech_data */ -+ NULL, /* free_mech_data */ -+}; -+ - #if OPENSSL_VERSION_NUMBER >= 0x00908000L - static sc_pkcs11_mechanism_type_t openssl_sha256_mech = { - CKM_SHA256, -@@ -231,6 +248,8 @@ sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *p11card) - - openssl_sha1_mech.mech_data = EVP_sha1(); - sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_sha1_mech, sizeof openssl_sha1_mech)); -+ openssl_sha224_mech.mech_data = EVP_sha224(); -+ sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_sha224_mech, sizeof openssl_sha224_mech)); - #if OPENSSL_VERSION_NUMBER >= 0x00908000L - openssl_sha256_mech.mech_data = EVP_sha256(); - sc_pkcs11_register_mechanism(p11card, dup_mem(&openssl_sha256_mech, sizeof openssl_sha256_mech)); -@@ -396,7 +415,7 @@ static CK_RV gostr3410_verify_data(const unsigned char *pubkey, int pubkey_len, - */ - CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, - const unsigned char *pubkey_params, int pubkey_params_len, -- CK_MECHANISM_TYPE mech, sc_pkcs11_operation_t *md, -+ CK_MECHANISM_PTR mech, sc_pkcs11_operation_t *md, - unsigned char *data, int data_len, - unsigned char *signat, int signat_len) - { -@@ -405,7 +424,7 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, - EVP_PKEY *pkey = NULL; - const unsigned char *pubkey_tmp = NULL; - -- if (mech == CKM_GOSTR3410) -+ if (mech->mechanism == CKM_GOSTR3410) - { - #if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC) - return gostr3410_verify_data(pubkey, pubkey_len, -@@ -429,37 +448,53 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, - if (pkey == NULL) - return CKR_GENERAL_ERROR; - -- if (md != NULL) { -+ if (md != NULL && (mech->mechanism == CKM_SHA1_RSA_PKCS -+ || mech->mechanism == CKM_SHA224_RSA_PKCS -+ || mech->mechanism == CKM_SHA256_RSA_PKCS -+ || mech->mechanism == CKM_SHA384_RSA_PKCS -+ || mech->mechanism == CKM_SHA512_RSA_PKCS)) { - EVP_MD_CTX *md_ctx = DIGEST_CTX(md); - -+ /* This does not really use the data argument, but the data -+ * are already collected in the md_ctx -+ */ -+ sc_log(context, "Trying to verify using EVP"); - res = EVP_VerifyFinal(md_ctx, signat, signat_len, pkey); - EVP_PKEY_free(pkey); - if (res == 1) - return CKR_OK; -- else if (res == 0) -+ else if (res == 0) { -+ sc_log(context, "EVP_VerifyFinal(): Signature invalid"); - return CKR_SIGNATURE_INVALID; -- else { -+ } else { - sc_log(context, "EVP_VerifyFinal() returned %d\n", res); - return CKR_GENERAL_ERROR; - } -- } -- else { -+ } else { - RSA *rsa; - unsigned char *rsa_out = NULL, pad; - int rsa_outlen = 0; - -- switch(mech) { -+ sc_log(context, "Trying to verify using low-level API"); -+ switch (mech->mechanism) { - case CKM_RSA_PKCS: - pad = RSA_PKCS1_PADDING; - break; -- case CKM_RSA_X_509: -- pad = RSA_NO_PADDING; -- break; -- /* TODO support more then RSA */ -- default: -+ case CKM_RSA_X_509: -+ pad = RSA_NO_PADDING; -+ break; -+ case CKM_RSA_PKCS_PSS: -+ case CKM_SHA1_RSA_PKCS_PSS: -+ case CKM_SHA224_RSA_PKCS_PSS: -+ case CKM_SHA256_RSA_PKCS_PSS: -+ case CKM_SHA384_RSA_PKCS_PSS: -+ case CKM_SHA512_RSA_PKCS_PSS: -+ pad = RSA_NO_PADDING; -+ break; -+ default: - EVP_PKEY_free(pkey); -- return CKR_ARGUMENTS_BAD; -- } -+ return CKR_ARGUMENTS_BAD; -+ } - - rsa = EVP_PKEY_get1_RSA(pkey); - EVP_PKEY_free(pkey); -@@ -473,13 +508,95 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, - } - - rsa_outlen = RSA_public_decrypt(signat_len, signat, rsa_out, rsa, pad); -- RSA_free(rsa); -- if(rsa_outlen <= 0) { -+ if (rsa_outlen <= 0) { - free(rsa_out); - sc_log(context, "RSA_public_decrypt() returned %d\n", rsa_outlen); - return CKR_GENERAL_ERROR; - } - -+ /* For PSS mechanisms we can not simply compare the "decrypted" -+ * data -- we need to verify the PSS padding is valid -+ */ -+ if (mech->mechanism == CKM_RSA_PKCS_PSS || -+ mech->mechanism == CKM_SHA1_RSA_PKCS_PSS || -+ mech->mechanism == CKM_SHA224_RSA_PKCS_PSS || -+ mech->mechanism == CKM_SHA256_RSA_PKCS_PSS || -+ mech->mechanism == CKM_SHA384_RSA_PKCS_PSS || -+ mech->mechanism == CKM_SHA512_RSA_PKCS_PSS) { -+ CK_RSA_PKCS_PSS_PARAMS* param = NULL; -+ const EVP_MD *mgf_md, *pss_md; -+ unsigned char digest[EVP_MAX_MD_SIZE]; -+ -+ if (mech->pParameter == NULL) { -+ sc_log(context, "PSS mechanism requires parameter"); -+ return CKR_MECHANISM_PARAM_INVALID; -+ } -+ -+ param = (CK_RSA_PKCS_PSS_PARAMS*)mech->pParameter; -+ switch (param->mgf) { -+ case CKG_MGF1_SHA1: -+ mgf_md = EVP_sha1(); -+ break; -+ case CKG_MGF1_SHA224: -+ mgf_md = EVP_sha224(); -+ break; -+ case CKG_MGF1_SHA256: -+ mgf_md = EVP_sha256(); -+ break; -+ case CKG_MGF1_SHA384: -+ mgf_md = EVP_sha384(); -+ break; -+ case CKG_MGF1_SHA512: -+ mgf_md = EVP_sha512(); -+ break; -+ default: -+ return CKR_MECHANISM_PARAM_INVALID; -+ } -+ -+ switch (param->hashAlg) { -+ case CKM_SHA_1: -+ pss_md = EVP_sha1(); -+ break; -+ case CKM_SHA224: -+ pss_md = EVP_sha224(); -+ break; -+ case CKM_SHA256: -+ pss_md = EVP_sha256(); -+ break; -+ case CKM_SHA384: -+ pss_md = EVP_sha384(); -+ break; -+ case CKM_SHA512: -+ pss_md = EVP_sha512(); -+ break; -+ default: -+ return CKR_MECHANISM_PARAM_INVALID; -+ } -+ -+ /* for the mechanisms with hash algorithm, the data -+ * is already added to the hash buffer, so we need -+ * to finish the hash operation here -+ */ -+ if (mech->mechanism != CKM_RSA_PKCS_PSS) { -+ EVP_MD_CTX *md_ctx = DIGEST_CTX(md); -+ unsigned char *tmp = digest; -+ unsigned int tmp_len; -+ -+ EVP_DigestFinal(md_ctx, tmp, &tmp_len); -+ data = tmp; -+ data_len = tmp_len; -+ } -+ rv = CKR_SIGNATURE_INVALID; -+ if (data_len == EVP_MD_size(pss_md) && -+ RSA_verify_PKCS1_PSS_mgf1(rsa, data, pss_md, mgf_md, -+ rsa_out, EVP_MD_size(pss_md)/*sLen*/) == 1) -+ rv = CKR_OK; -+ RSA_free(rsa); -+ sc_log(context, "Returning %lu", rv); -+ return rv; -+ } -+ RSA_free(rsa); -+ - if (rsa_outlen == data_len && memcmp(rsa_out, data, data_len) == 0) - rv = CKR_OK; - else -diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h -index 61a5050df..8219b961b 100644 ---- a/src/pkcs11/pkcs11.h -+++ b/src/pkcs11/pkcs11.h -@@ -480,8 +480,6 @@ struct ck_date - - typedef unsigned long ck_mechanism_type_t; - --typedef unsigned long int ck_rsa_pkcs_mgf_type_t; -- - #define CKM_RSA_PKCS_KEY_PAIR_GEN (0UL) - #define CKM_RSA_PKCS (1UL) - #define CKM_RSA_9796 (2UL) -@@ -764,6 +762,7 @@ typedef struct CK_ECDH1_DERIVE_PARAMS { - unsigned char * pPublicData; - } CK_ECDH1_DERIVE_PARAMS; - -+typedef unsigned long ck_rsa_pkcs_mgf_type_t; - typedef unsigned long CK_RSA_PKCS_OAEP_SOURCE_TYPE; - - typedef struct CK_RSA_PKCS_OAEP_PARAMS { -diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h -index 843245882..f0115ed04 100644 ---- a/src/pkcs11/sc-pkcs11.h -+++ b/src/pkcs11/sc-pkcs11.h -@@ -119,6 +119,9 @@ struct sc_pkcs11_object_ops { - /* Check compatibility of PKCS#15 object usage and an asked PKCS#11 mechanism. */ - CK_RV (*can_do)(struct sc_pkcs11_session *, void *, CK_MECHANISM_TYPE, unsigned int); - -+ /* General validation of mechanism parameters (sign, encrypt, etc) */ -+ CK_RV (*init_params)(struct sc_pkcs11_session *, CK_MECHANISM_PTR); -+ - /* Others to be added when implemented */ - }; - -@@ -290,6 +293,10 @@ typedef struct sc_pkcs11_mechanism_type sc_pkcs11_mechanism_type_t; - struct sc_pkcs11_operation { - sc_pkcs11_mechanism_type_t *type; - CK_MECHANISM mechanism; -+ union { -+ CK_RSA_PKCS_PSS_PARAMS pss; -+ CK_RSA_PKCS_OAEP_PARAMS oaep; -+ } mechanism_params; - struct sc_pkcs11_session *session; - void * priv_data; - }; -@@ -434,7 +441,7 @@ CK_RV sc_pkcs11_register_sign_and_hash_mechanism(struct sc_pkcs11_card *, - #ifdef ENABLE_OPENSSL - CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, - const unsigned char *pubkey_params, int pubkey_params_len, -- CK_MECHANISM_TYPE mech, sc_pkcs11_operation_t *md, -+ CK_MECHANISM_PTR mech, sc_pkcs11_operation_t *md, - unsigned char *inp, int inp_len, - unsigned char *signat, int signat_len); - #endif - -From 2f36612d116ed1fb3ed305a5657871fa12f75011 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Sun, 22 Jul 2018 16:29:19 +0200 -Subject: [PATCH 4/5] pkcs11-tool: Support for signature verification - -Signed-off-by: Jakub Jelen ---- - doc/tools/pkcs11-tool.1.xml | 14 ++ - src/tools/pkcs11-tool.c | 273 +++++++++++++++++++++++++++--------- - 2 files changed, 222 insertions(+), 65 deletions(-) - -diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml -index c609ec0e2..fd823c06e 100644 ---- a/doc/tools/pkcs11-tool.1.xml -+++ b/doc/tools/pkcs11-tool.1.xml -@@ -481,6 +481,13 @@ - non-zero number. - - -+ -+ -+ , -+ -+ Verify signature of some data. -+ -+ - - - , -@@ -530,6 +537,13 @@ - cert/privkey/pubkey). - - -+ -+ -+ filename -+ -+ The path to the signature file for signature verification -+ -+ - - - format -diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c -index 64525f6ad..e3c52e2f8 100644 ---- a/src/tools/pkcs11-tool.c -+++ b/src/tools/pkcs11-tool.c -@@ -150,6 +150,8 @@ enum { - OPT_HASH_ALGORITHM, - OPT_MGF, - OPT_SALT, -+ OPT_VERIFY, -+ OPT_SIGNATURE_FILE, - }; - - static const struct option options[] = { -@@ -161,6 +163,7 @@ static const struct option options[] = { - { "list-objects", 0, NULL, 'O' }, - - { "sign", 0, NULL, 's' }, -+ { "verify", 0, NULL, OPT_VERIFY }, - { "decrypt", 0, NULL, OPT_DECRYPT }, - { "hash", 0, NULL, 'h' }, - { "derive", 0, NULL, OPT_DERIVE }, -@@ -203,6 +206,7 @@ static const struct option options[] = { - { "set-id", 1, NULL, 'e' }, - { "attr-from", 1, NULL, OPT_ATTR_FROM }, - { "input-file", 1, NULL, 'i' }, -+ { "signature-file", 1, NULL, OPT_SIGNATURE_FILE }, - { "output-file", 1, NULL, 'o' }, - { "signature-format", 1, NULL, 'f' }, - -@@ -230,6 +234,7 @@ static const char *option_help[] = { - "Show objects on token", - - "Sign some data", -+ "Verify a signature of some data", - "Decrypt some data", - "Hash some data", - "Derive a secret key using another key and some data", -@@ -272,6 +277,7 @@ static const char *option_help[] = { - "Set the CKA_ID of an object, = the (new) CKA_ID", - "Use to create some attributes when writing an object", - "Specify the input file", -+ "Specify the file with signature for verification", - "Specify the output file", - "Format for ECDSA signature : 'rs' (default), 'sequence', 'openssl'", - -@@ -293,6 +299,7 @@ static const char * app_name = "pkcs11-tool"; /* for utils.c */ - static int verbose = 0; - static const char * opt_input = NULL; - static const char * opt_output = NULL; -+static const char * opt_signature_file = NULL; - static const char * opt_module = DEFAULT_PKCS11_PROVIDER; - static int opt_slot_set = 0; - static CK_SLOT_ID opt_slot = 0; -@@ -331,8 +338,8 @@ static int opt_derive_pass_der = 0; - static unsigned long opt_random_bytes = 0; - static CK_MECHANISM_TYPE opt_hash_alg = 0; - static unsigned long opt_mgf = 0; --static long salt_len = 0; --static int salt_len_given = 0; /* 0 - not given, 1 - given with input parameters */ -+static long opt_salt_len = 0; -+static int opt_salt_len_given = 0; /* 0 - not given, 1 - given with input parameters */ - - static void *module = NULL; - static CK_FUNCTION_LIST_PTR p11 = NULL; -@@ -396,6 +403,7 @@ static void show_key(CK_SESSION_HANDLE, CK_OBJECT_HANDLE); - static void show_cert(CK_SESSION_HANDLE, CK_OBJECT_HANDLE); - static void show_dobj(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj); - static void sign_data(CK_SLOT_ID, CK_SESSION_HANDLE, CK_OBJECT_HANDLE); -+static void verify_signature(CK_SLOT_ID, CK_SESSION_HANDLE, CK_OBJECT_HANDLE); - static void decrypt_data(CK_SLOT_ID, CK_SESSION_HANDLE, CK_OBJECT_HANDLE); - static void hash_data(CK_SLOT_ID, CK_SESSION_HANDLE); - static void derive_key(CK_SLOT_ID, CK_SESSION_HANDLE, CK_OBJECT_HANDLE); -@@ -532,6 +540,7 @@ int main(int argc, char * argv[]) - int do_list_mechs = 0; - int do_list_objects = 0; - int do_sign = 0; -+ int do_verify = 0; - int do_decrypt = 0; - int do_hash = 0; - int do_derive = 0; -@@ -685,6 +694,9 @@ int main(int argc, char * argv[]) - case 'i': - opt_input = optarg; - break; -+ case OPT_SIGNATURE_FILE: -+ opt_signature_file = optarg; -+ break; - case 'l': - need_session |= NEED_SESSION_RW; - opt_login = 1; -@@ -700,8 +712,8 @@ int main(int argc, char * argv[]) - opt_mgf = p11_name_to_mgf(optarg); - break; - case OPT_SALT: -- salt_len = (CK_ULONG) strtoul(optarg, NULL, 0); -- salt_len_given = 1; -+ opt_salt_len = (CK_ULONG) strtoul(optarg, NULL, 0); -+ opt_salt_len_given = 1; - break; - case 'o': - opt_output = optarg; -@@ -726,6 +738,11 @@ int main(int argc, char * argv[]) - do_sign = 1; - action_count++; - break; -+ case OPT_VERIFY: -+ need_session |= NEED_SESSION_RO; -+ do_verify = 1; -+ action_count++; -+ break; - case OPT_DECRYPT: - need_session |= NEED_SESSION_RW; - do_decrypt = 1; -@@ -1037,6 +1054,16 @@ int main(int argc, char * argv[]) - util_fatal("Private key not found"); - } - -+ if (do_verify) { -+ if (!find_object(session, CKO_PUBLIC_KEY, &object, -+ opt_object_id_len ? opt_object_id : NULL, -+ opt_object_id_len, 0) && -+ !find_object(session, CKO_CERTIFICATE, &object, -+ opt_object_id_len ? opt_object_id : NULL, -+ opt_object_id_len, 0)) -+ util_fatal("Public key nor certificate not found"); -+ } -+ - /* before list objects, so we can see a derived key */ - if (do_derive) - derive_key(opt_slot, session, object); -@@ -1047,6 +1074,9 @@ int main(int argc, char * argv[]) - if (do_sign) - sign_data(opt_slot, session, object); - -+ if (do_verify) -+ verify_signature(opt_slot, session, object); -+ - if (do_decrypt) - decrypt_data(opt_slot, session, object); - -@@ -1636,7 +1666,7 @@ static int unlock_pin(CK_SLOT_ID slot, CK_SESSION_HANDLE sess, int login_type) - } - - /* return digest length in bytes */ --static unsigned long figure_pss_salt_length(const int hash) { -+static unsigned long hash_length(const int hash) { - unsigned long sLen = 0; - switch (hash) { - case CKM_SHA_1: -@@ -1662,26 +1692,16 @@ static unsigned long figure_pss_salt_length(const int hash) { - return sLen; - } - --static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, -- CK_OBJECT_HANDLE key) -+static unsigned long -+parse_pss_params(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, -+ CK_MECHANISM *mech, CK_RSA_PKCS_PSS_PARAMS *pss_params) - { -- unsigned char in_buffer[1025], sig_buffer[512]; -- CK_MECHANISM mech; -- CK_RSA_PKCS_PSS_PARAMS pss_params; -- CK_RV rv; -- CK_ULONG sig_len; -- int fd, r; -+ unsigned long hashlen = 0; - -- unsigned long hashlen = 0, modlen = 0; -- -- if (!opt_mechanism_used) -- if (!find_mechanism(slot, CKF_SIGN|CKF_HW, NULL, 0, &opt_mechanism)) -- util_fatal("Sign mechanism not supported"); -+ if (pss_params == NULL) -+ return 0; - -- fprintf(stderr, "Using signature algorithm %s\n", p11_mechanism_to_name(opt_mechanism)); -- memset(&mech, 0, sizeof(mech)); -- mech.mechanism = opt_mechanism; -- pss_params.hashAlg = 0; -+ pss_params->hashAlg = 0; - - if (opt_hash_alg != 0 && opt_mechanism != CKM_RSA_PKCS_PSS) - util_fatal("The hash-algorithm is applicable only to " -@@ -1690,93 +1710,118 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, - /* set "default" MGF and hash algorithms. We can overwrite MGF later */ - switch (opt_mechanism) { - case CKM_RSA_PKCS_PSS: -- pss_params.hashAlg = opt_hash_alg; -+ pss_params->hashAlg = opt_hash_alg; - - switch (opt_hash_alg) { - case CKM_SHA224: -- pss_params.mgf = CKG_MGF1_SHA224; -+ pss_params->mgf = CKG_MGF1_SHA224; - break; - case CKM_SHA256: -- pss_params.mgf = CKG_MGF1_SHA256; -+ pss_params->mgf = CKG_MGF1_SHA256; - break; - case CKM_SHA384: -- pss_params.mgf = CKG_MGF1_SHA384; -+ pss_params->mgf = CKG_MGF1_SHA384; - break; - case CKM_SHA512: -- pss_params.mgf = CKG_MGF1_SHA512; -+ pss_params->mgf = CKG_MGF1_SHA512; - break; - default: - /* the PSS should use SHA-1 if not specified */ -- pss_params.hashAlg = CKM_SHA_1; -+ pss_params->hashAlg = CKM_SHA_1; - /* fallthrough */ - case CKM_SHA_1: -- pss_params.mgf = CKG_MGF1_SHA1; -+ pss_params->mgf = CKG_MGF1_SHA1; - } - break; - - case CKM_SHA1_RSA_PKCS_PSS: -- pss_params.hashAlg = CKM_SHA_1; -- pss_params.mgf = CKG_MGF1_SHA1; -+ pss_params->hashAlg = CKM_SHA_1; -+ pss_params->mgf = CKG_MGF1_SHA1; - break; - - case CKM_SHA224_RSA_PKCS_PSS: -- pss_params.hashAlg = CKM_SHA224; -- pss_params.mgf = CKG_MGF1_SHA224; -+ pss_params->hashAlg = CKM_SHA224; -+ pss_params->mgf = CKG_MGF1_SHA224; - break; - - case CKM_SHA256_RSA_PKCS_PSS: -- pss_params.hashAlg = CKM_SHA256; -- pss_params.mgf = CKG_MGF1_SHA256; -+ pss_params->hashAlg = CKM_SHA256; -+ pss_params->mgf = CKG_MGF1_SHA256; - break; - - case CKM_SHA384_RSA_PKCS_PSS: -- pss_params.hashAlg = CKM_SHA384; -- pss_params.mgf = CKG_MGF1_SHA384; -+ pss_params->hashAlg = CKM_SHA384; -+ pss_params->mgf = CKG_MGF1_SHA384; - break; - - case CKM_SHA512_RSA_PKCS_PSS: -- pss_params.hashAlg = CKM_SHA512; -- pss_params.mgf = CKG_MGF1_SHA512; -+ pss_params->hashAlg = CKM_SHA512; -+ pss_params->mgf = CKG_MGF1_SHA512; - break; - } - - /* One of RSA-PSS mechanisms above: They need parameters */ -- if (pss_params.hashAlg) { -+ if (pss_params->hashAlg) { - if (opt_mgf != 0) -- pss_params.mgf = opt_mgf; -+ pss_params->mgf = opt_mgf; - -- hashlen = figure_pss_salt_length(pss_params.hashAlg); -+ hashlen = hash_length(pss_params->hashAlg); - -- if (salt_len_given == 1) { /* salt size explicitly given */ -- if (salt_len < 0 && salt_len != -1 && salt_len != -2) -- util_fatal("Salt length must be greater or equal \ --to zero, or equal to -1 (meaning: use digest size) or to -2 \ --(meaning: use maximum permissible size"); -+ if (opt_salt_len_given == 1) { /* salt size explicitly given */ -+ unsigned long modlen = 0; -+ if (opt_salt_len < 0 && opt_salt_len != -1 && opt_salt_len != -2) -+ util_fatal("Salt length must be greater or equal " -+ "to zero, or equal to -1 (meaning: use digest size) " -+ "or to -2 (meaning: use maximum permissible size"); - - modlen = (get_private_key_length(session, key) + 7) / 8; -- switch(salt_len) { -+ switch (opt_salt_len) { - case -1: /* salt size equals to digest size */ -- pss_params.sLen = hashlen; -+ pss_params->sLen = hashlen; - break; - case -2: /* maximum permissible salt len */ -- pss_params.sLen = modlen - hashlen -2; -+ pss_params->sLen = modlen - hashlen -2; - break; - default: /* use given size but its value must be >= 0 */ -- pss_params.sLen = salt_len; -+ pss_params->sLen = opt_salt_len; - break; -- } /* end switch (salt_len_given) */ -+ } /* end switch (opt_salt_len_given) */ - } else { /* use default: salt len of digest size */ -- pss_params.sLen = hashlen; -+ pss_params->sLen = hashlen; - } - -- mech.pParameter = &pss_params; -- mech.ulParameterLen = sizeof(pss_params); -+ mech->pParameter = pss_params; -+ mech->ulParameterLen = sizeof(*pss_params); - - fprintf(stderr, "PSS parameters: hashAlg=%s, mgf=%s, salt_len=%lu B\n", -- p11_mechanism_to_name(pss_params.hashAlg), -- p11_mgf_to_name(pss_params.mgf), -- pss_params.sLen); -+ p11_mechanism_to_name(pss_params->hashAlg), -+ p11_mgf_to_name(pss_params->mgf), -+ pss_params->sLen); - } -+ return hashlen; -+} -+ -+static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, -+ CK_OBJECT_HANDLE key) -+{ -+ unsigned char in_buffer[1025], sig_buffer[512]; -+ CK_MECHANISM mech; -+ CK_RSA_PKCS_PSS_PARAMS pss_params; -+ CK_RV rv; -+ CK_ULONG sig_len; -+ int fd, r; -+ unsigned long hashlen; -+ -+ if (!opt_mechanism_used) -+ if (!find_mechanism(slot, CKF_SIGN|CKF_HW, NULL, 0, &opt_mechanism)) -+ util_fatal("Sign mechanism not supported"); -+ -+ fprintf(stderr, "Using signature algorithm %s\n", p11_mechanism_to_name(opt_mechanism)); -+ memset(&mech, 0, sizeof(mech)); -+ mech.mechanism = opt_mechanism; -+ hashlen = parse_pss_params(session, key, &mech, &pss_params); -+ if (hashlen == 0) -+ util_fatal("Invalid RSA-PSS parameters"); - - if (opt_input == NULL) - fd = 0; -@@ -1787,12 +1832,15 @@ to zero, or equal to -1 (meaning: use digest size) or to -2 \ - if (r < 0) - util_fatal("Cannot read from %s: %m", opt_input); - -- if (opt_mechanism == CKM_RSA_PKCS_PSS && (unsigned long)r != hashlen) -- util_fatal("For %s mechanism, message size (got %d bytes) must be equal to specified digest length (%lu)\n", -- p11_mechanism_to_name(opt_mechanism), r, hashlen); -+ if (opt_mechanism == CKM_RSA_PKCS_PSS) { -+ if ((unsigned long)r != hashlen) -+ util_fatal("For %s mechanism, message size (got %d bytes) " -+ "must be equal to specified digest length (%lu)\n", -+ p11_mechanism_to_name(opt_mechanism), r, hashlen); -+ } - - rv = CKR_CANCEL; -- if (r < (int) sizeof(in_buffer)) { -+ if (r < (int) sizeof(in_buffer)) { - rv = p11->C_SignInit(session, &mech, key); - if (rv != CKR_OK) - p11_fatal("C_SignInit", rv); -@@ -1833,12 +1881,16 @@ to zero, or equal to -1 (meaning: use digest size) or to -2 \ - util_fatal("failed to open %s: %m", opt_output); - } - -- if (opt_mechanism == CKM_ECDSA || opt_mechanism == CKM_ECDSA_SHA1 || opt_mechanism == CKM_ECDSA_SHA256 || opt_mechanism == CKM_ECDSA_SHA384 || opt_mechanism == CKM_ECDSA_SHA512 || opt_mechanism == CKM_ECDSA_SHA224) { -- if (opt_sig_format && (!strcmp(opt_sig_format, "openssl") || !strcmp(opt_sig_format, "sequence"))) { -+ if (opt_mechanism == CKM_ECDSA || opt_mechanism == CKM_ECDSA_SHA1 || -+ opt_mechanism == CKM_ECDSA_SHA256 || opt_mechanism == CKM_ECDSA_SHA384 || -+ opt_mechanism == CKM_ECDSA_SHA512 || opt_mechanism == CKM_ECDSA_SHA224) { -+ if (opt_sig_format && (!strcmp(opt_sig_format, "openssl") || -+ !strcmp(opt_sig_format, "sequence"))) { - unsigned char *seq; - size_t seqlen; - -- if (sc_asn1_sig_value_rs_to_sequence(NULL, sig_buffer, sig_len, &seq, &seqlen)) { -+ if (sc_asn1_sig_value_rs_to_sequence(NULL, sig_buffer, -+ sig_len, &seq, &seqlen)) { - util_fatal("Failed to convert signature to ASN.1 sequence format"); - } - -@@ -1856,6 +1908,97 @@ to zero, or equal to -1 (meaning: use digest size) or to -2 \ - close(fd); - } - -+static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, -+ CK_OBJECT_HANDLE key) -+{ -+ unsigned char in_buffer[1025], sig_buffer[512]; -+ CK_MECHANISM mech; -+ CK_RSA_PKCS_PSS_PARAMS pss_params; -+ CK_RV rv; -+ CK_ULONG sig_len; -+ int fd, fd2, r, r2; -+ unsigned long hashlen; -+ -+ if (!opt_mechanism_used) -+ if (!find_mechanism(slot, CKF_VERIFY|CKF_HW, NULL, 0, &opt_mechanism)) -+ util_fatal("Mechanism not supported for signature verification"); -+ -+ fprintf(stderr, "Using signature algorithm %s\n", p11_mechanism_to_name(opt_mechanism)); -+ memset(&mech, 0, sizeof(mech)); -+ mech.mechanism = opt_mechanism; -+ hashlen = parse_pss_params(session, key, &mech, &pss_params); -+ if (hashlen == 0) -+ util_fatal("Invalid RSA-PSS parameters"); -+ -+ /* Open a signature file */ -+ if (opt_signature_file == NULL) -+ util_fatal("No file with signature provided. Use --signature-file"); -+ else if ((fd2 = open(opt_signature_file, O_RDONLY|O_BINARY)) < 0) -+ util_fatal("Cannot open %s: %m", opt_signature_file); -+ -+ r2 = read(fd2, sig_buffer, sizeof(sig_buffer)); -+ if (r2 < 0) -+ util_fatal("Cannot read from %s: %m", opt_signature_file); -+ -+ close(fd2); -+ -+ /* Open the data file */ -+ if (opt_input == NULL) -+ fd = 0; -+ else if ((fd = open(opt_input, O_RDONLY|O_BINARY)) < 0) -+ util_fatal("Cannot open %s: %m", opt_input); -+ -+ r = read(fd, in_buffer, sizeof(in_buffer)); -+ if (r < 0) -+ util_fatal("Cannot read from %s: %m", opt_input); -+ -+ if (opt_mechanism == CKM_RSA_PKCS_PSS) { -+ if ((unsigned long)r != hashlen) -+ util_fatal("For %s mechanism, message size (got %d bytes)" -+ " must be equal to specified digest length (%lu)\n", -+ p11_mechanism_to_name(opt_mechanism), r, hashlen); -+ } -+ -+ rv = CKR_CANCEL; -+ if (r < (int) sizeof(in_buffer)) { -+ rv = p11->C_VerifyInit(session, &mech, key); -+ if (rv != CKR_OK) -+ p11_fatal("C_VerifyInit", rv); -+ -+ sig_len = r2; -+ rv = p11->C_Verify(session, in_buffer, r, sig_buffer, sig_len); -+ } -+ -+ if (rv != CKR_OK) { -+ rv = p11->C_VerifyInit(session, &mech, key); -+ if (rv != CKR_OK) -+ p11_fatal("C_VerifyInit", rv); -+ -+ do { -+ rv = p11->C_VerifyUpdate(session, in_buffer, r); -+ if (rv != CKR_OK) -+ p11_fatal("C_VerifyUpdate", rv); -+ -+ r = read(fd, in_buffer, sizeof(in_buffer)); -+ } while (r > 0); -+ -+ sig_len = sizeof(sig_buffer); -+ rv = p11->C_VerifyFinal(session, sig_buffer, sig_len); -+ if (rv != CKR_OK) -+ p11_fatal("C_VerifyFinal", rv); -+ } -+ -+ if (fd != 0) -+ close(fd); -+ -+ if (rv == CKR_OK) -+ printf("Signature is valid\n"); -+ else if (rv == CKR_SIGNATURE_INVALID) -+ printf("Invalid signature\n"); -+ else -+ printf("Cryptoki returned erorr: %s\n", CKR2Str(rv)); -+} -+ - - static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, - CK_OBJECT_HANDLE key) - -From 256502bed97d56a6813c0b4a7d4c64ee1ff0606e Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Fri, 14 Sep 2018 17:27:11 +0200 -Subject: [PATCH 5/5] slot: Switch cleanup steps to avoid segfaults on errors - -and some more sanity checking - -Signed-off-by: Jakub Jelen ---- - src/pkcs11/framework-pkcs15.c | 2 +- - src/pkcs11/slot.c | 4 ++-- - 2 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c -index a75d239f4..85e12df66 100644 ---- a/src/pkcs11/framework-pkcs15.c -+++ b/src/pkcs11/framework-pkcs15.c -@@ -365,7 +365,7 @@ pkcs15_unbind(struct sc_pkcs11_card *p11card) - - unlock_card(fw_data); - -- if (fw_data->p15_card) { -+ if (fw_data->p15_card && fw_data->p15_card->card) { - if (idx == 0) { - int rc = sc_detect_card_presence(fw_data->p15_card->card->reader); - if (rc <= 0 || rc & SC_READER_CARD_CHANGED) { -diff --git a/src/pkcs11/slot.c b/src/pkcs11/slot.c -index fe322e68e..3102bf986 100644 ---- a/src/pkcs11/slot.c -+++ b/src/pkcs11/slot.c -@@ -374,10 +374,10 @@ CK_RV card_detect(sc_reader_t *reader) - - fail: - if (free_p11card) { -- if (p11card->card != NULL) -- sc_disconnect_card(p11card->card); - if (p11card->framework) - p11card->framework->unbind(p11card); -+ if (p11card->card != NULL) -+ sc_disconnect_card(p11card->card); - free(p11card); - } - -From 2fd8e278f5d3664555cad706d7270229c87cae56 Mon Sep 17 00:00:00 2001 -From: Doug Engert -Date: Wed, 17 Oct 2018 16:07:20 -0500 -Subject: [PATCH] pkcs11/openssl.c - add missing mechanisms fixes #1497 - - On branch pkcs11-openssl-c - Changes to be committed: - modified: ../pkcs11/openssl.c ---- - src/pkcs11/openssl.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c -index 00b9814e4..fb9f8fea8 100644 ---- a/src/pkcs11/openssl.c -+++ b/src/pkcs11/openssl.c -@@ -449,6 +449,8 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, - return CKR_GENERAL_ERROR; - - if (md != NULL && (mech->mechanism == CKM_SHA1_RSA_PKCS -+ || mech->mechanism == CKM_MD5_RSA_PKCS -+ || mech->mechanism == CKM_RIPEMD160_RSA_PKCS - || mech->mechanism == CKM_SHA224_RSA_PKCS - || mech->mechanism == CKM_SHA256_RSA_PKCS - || mech->mechanism == CKM_SHA384_RSA_PKCS -@@ -478,6 +480,8 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, - sc_log(context, "Trying to verify using low-level API"); - switch (mech->mechanism) { - case CKM_RSA_PKCS: -+ case CKM_MD5_RSA_PKCS: -+ case CKM_RIPEMD160_RSA_PKCS: - pad = RSA_PKCS1_PADDING; - break; - case CKM_RSA_X_509: - - -From 9b289e074bff22f7e2339b7d3f9428c3233efb71 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Wed, 31 Oct 2018 11:46:37 +0100 -Subject: [PATCH 2/7] coolkey: Check return values from list initialization - (coverity) - ->>> CID 324484: Error handling issues (CHECKED_RETURN) ->>> Calling "list_init" without checking return value (as is done elsewhere 8 out of 9 times). ---- - src/libopensc/card-coolkey.c | 13 ++++++++++--- - 1 file changed, 10 insertions(+), 3 deletions(-) - -diff --git a/src/libopensc/card-coolkey.c b/src/libopensc/card-coolkey.c -index c1c09b662..e320290df 100644 ---- a/src/libopensc/card-coolkey.c -+++ b/src/libopensc/card-coolkey.c -@@ -784,18 +784,25 @@ size_t coolkey_list_meter(const void *el) { - return sizeof(sc_cardctl_coolkey_object_t); - } - -+static void coolkey_free_private_data(coolkey_private_data_t *priv); -+ - static coolkey_private_data_t *coolkey_new_private_data(void) - { - coolkey_private_data_t *priv; -+ - /* allocate priv and zero all the fields */ - priv = calloc(1, sizeof(coolkey_private_data_t)); - if (!priv) - return NULL; -+ - /* set other fields as appropriate */ - priv->key_id = COOLKEY_INVALID_KEY; -- list_init(&priv->objects_list); -- list_attributes_comparator(&priv->objects_list, coolkey_compare_id); -- list_attributes_copy(&priv->objects_list, coolkey_list_meter, 1); -+ if (list_init(&priv->objects_list) != 0 || -+ list_attributes_comparator(&priv->objects_list, coolkey_compare_id) != 0 || -+ list_attributes_copy(&priv->objects_list, coolkey_list_meter, 1) != 0) { -+ coolkey_free_private_data(priv); -+ return NULL; -+ } - - return priv; - } - -From a32fbd0525ea6e21e73b03086e29862481761848 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Wed, 31 Oct 2018 15:02:00 +0100 -Subject: [PATCH 3/7] framework-pkcs15.c: Reformat - - * Reasonable line lengths - * Correct indentation - * Add missing SHA224 mechanism ---- - src/pkcs11/framework-pkcs15.c | 40 +++++++++++++++++++++++------------ - 1 file changed, 26 insertions(+), 14 deletions(-) - -diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c -index 85e12df66..3657bcbdd 100644 ---- a/src/pkcs11/framework-pkcs15.c -+++ b/src/pkcs11/framework-pkcs15.c -@@ -5159,18 +5159,14 @@ register_mechanisms(struct sc_pkcs11_card *p11card) - } - - #ifdef ENABLE_OPENSSL -- /* all our software hashes are in OpenSSL */ -- /* Only if card did not list the hashes, will we -- * help it a little, by adding all the OpenSSL hashes -- * that have PKCS#11 mechanisms. -- */ -- if (!(rsa_flags & SC_ALGORITHM_RSA_HASHES)) { -- rsa_flags |= SC_ALGORITHM_RSA_HASHES; --#if OPENSSL_VERSION_NUMBER < 0x00908000L -- /* turn off hashes not in openssl 0.9.8 */ -- rsa_flags &= ~(SC_ALGORITHM_RSA_HASH_SHA256 | SC_ALGORITHM_RSA_HASH_SHA384 | SC_ALGORITHM_RSA_HASH_SHA512 | SC_ALGORITHM_RSA_HASH_SHA224); --#endif -- } -+ /* all our software hashes are in OpenSSL */ -+ /* Only if card did not list the hashes, will we -+ * help it a little, by adding all the OpenSSL hashes -+ * that have PKCS#11 mechanisms. -+ */ -+ if (!(rsa_flags & SC_ALGORITHM_RSA_HASHES)) { -+ rsa_flags |= SC_ALGORITHM_RSA_HASHES; -+ } - #endif - - /* No need to Check for PKCS1 We support it in software and turned it on above so always added it */ -@@ -5182,32 +5182,44 @@ register_mechanisms(struct sc_pkcs11_card *p11card) - * Either the card set the hashes or we helped it above */ - - if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA1) { -- rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, CKM_SHA1_RSA_PKCS, CKM_SHA_1, mt); -+ rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, -+ CKM_SHA1_RSA_PKCS, CKM_SHA_1, mt); -+ if (rc != CKR_OK) -+ return rc; -+ } -+ if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA224) { -+ rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, -+ CKM_SHA224_RSA_PKCS, CKM_SHA224, mt); - if (rc != CKR_OK) - return rc; - } - if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA256) { -- rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, CKM_SHA256_RSA_PKCS, CKM_SHA256, mt); -+ rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, -+ CKM_SHA256_RSA_PKCS, CKM_SHA256, mt); - if (rc != CKR_OK) - return rc; - } - if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA384) { -- rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, CKM_SHA384_RSA_PKCS, CKM_SHA384, mt); -+ rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, -+ CKM_SHA384_RSA_PKCS, CKM_SHA384, mt); - if (rc != CKR_OK) - return rc; - } - if (rsa_flags & SC_ALGORITHM_RSA_HASH_SHA512) { -- rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, CKM_SHA512_RSA_PKCS, CKM_SHA512, mt); -+ rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, -+ CKM_SHA512_RSA_PKCS, CKM_SHA512, mt); - if (rc != CKR_OK) - return rc; - } - if (rsa_flags & SC_ALGORITHM_RSA_HASH_MD5) { -- rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, CKM_MD5_RSA_PKCS, CKM_MD5, mt); -+ rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, -+ CKM_MD5_RSA_PKCS, CKM_MD5, mt); - if (rc != CKR_OK) - return rc; - } - if (rsa_flags & SC_ALGORITHM_RSA_HASH_RIPEMD160) { -- rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, CKM_RIPEMD160_RSA_PKCS, CKM_RIPEMD160, mt); -+ rc = sc_pkcs11_register_sign_and_hash_mechanism(p11card, -+ CKM_RIPEMD160_RSA_PKCS, CKM_RIPEMD160, mt); - if (rc != CKR_OK) - return rc; - } - -From 7461c259c96f086621a35baeb699cf3cdc2968dd Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Wed, 31 Oct 2018 15:03:40 +0100 -Subject: [PATCH 4/7] framework-pkcs15.c: Add PKCS#1 mechanisms also if - SC_ALGORITHM_RSA_HASH_NONE is defined - ---- - src/pkcs11/framework-pkcs15.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c -index 3657bcbdd..cac39b821 100644 ---- a/src/pkcs11/framework-pkcs15.c -+++ b/src/pkcs11/framework-pkcs15.c -@@ -5164,7 +5164,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card) - * help it a little, by adding all the OpenSSL hashes - * that have PKCS#11 mechanisms. - */ -- if (!(rsa_flags & SC_ALGORITHM_RSA_HASHES)) { -+ if (!(rsa_flags & (SC_ALGORITHM_RSA_HASHES & ~SC_ALGORITHM_RSA_HASH_NONE))) { - rsa_flags |= SC_ALGORITHM_RSA_HASHES; - } - #endif - -From 56a9dab5c0a3bc91175266296a70aea94cb5747b Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Wed, 31 Oct 2018 15:35:25 +0100 -Subject: [PATCH 5/7] p11test: Do not report incomplete key pairs - ---- - src/tests/p11test/p11test_case_pss_oaep.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/src/tests/p11test/p11test_case_pss_oaep.c b/src/tests/p11test/p11test_case_pss_oaep.c -index d0b8392fd..019471192 100644 ---- a/src/tests/p11test/p11test_case_pss_oaep.c -+++ b/src/tests/p11test/p11test_case_pss_oaep.c -@@ -815,6 +815,10 @@ void pss_oaep_test(void **state) { - for (i = 0; i < objects.count; i++) { - test_cert_t *o = &objects.data[i]; - -+ /* Do not go through incomplete pairs */ -+ if (o->private_handle == CK_INVALID_HANDLE) -+ continue; -+ - /* Do not list non-RSA keys here */ - if (o->type != EVP_PK_RSA) - continue; - -From 21d6d8092c98e572c89853593f3f680d219a06d9 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Wed, 31 Oct 2018 15:39:56 +0100 -Subject: [PATCH 6/7] framework-pkcs15.c: Add SHA224 mechanism for PKCS#1.5 - ---- - src/pkcs11/framework-pkcs15.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c -index cac39b821..6948e31d4 100644 ---- a/src/pkcs11/framework-pkcs15.c -+++ b/src/pkcs11/framework-pkcs15.c -@@ -3781,6 +3781,9 @@ pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj, - case CKM_SHA1_RSA_PKCS: - flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA1; - break; -+ case CKM_SHA224_RSA_PKCS: -+ flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA224; -+ break; - case CKM_SHA256_RSA_PKCS: - flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA256; - break; - -From 7d4fa67efc22bf085863ead342b9fc55513425f1 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Wed, 31 Oct 2018 17:50:08 +0100 -Subject: [PATCH 7/7] padding: Fix error checking in RSA-PSS - ---- - src/libopensc/padding.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/libopensc/padding.c b/src/libopensc/padding.c -index 75c92b651..f0e2263b8 100644 ---- a/src/libopensc/padding.c -+++ b/src/libopensc/padding.c -@@ -345,7 +345,7 @@ static int sc_pkcs1_add_pss_padding(unsigned int hash, unsigned int mgf1_hash, - if (EVP_DigestInit_ex(ctx, mgf1_md, NULL) != 1 || - EVP_DigestUpdate(ctx, out + dblen, hlen) != 1 || /* H (Z parameter of MGF1) */ - EVP_DigestUpdate(ctx, buf, 4) != 1 || /* C */ -- EVP_DigestFinal_ex(ctx, mask, NULL)) { -+ EVP_DigestFinal_ex(ctx, mask, NULL) != 1) { - goto done; - } - /* this is no longer part of the MGF1, but actually - -From e5d8395a7b8e5d6d1493d893c31fac321f45433a Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Tue, 20 Nov 2018 09:29:53 +0100 -Subject: [PATCH] pkcs11-tool: Unbreak signature and verification in - pkcs11-tool - ---- - src/tools/pkcs11-tool.c | 25 +++++++++++-------------- - 1 file changed, 11 insertions(+), 14 deletions(-) - -diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c -index df4a0ef3..ff1c00ac 100644 ---- a/src/tools/pkcs11-tool.c -+++ b/src/tools/pkcs11-tool.c -@@ -1758,6 +1758,9 @@ parse_pss_params(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, - pss_params->hashAlg = CKM_SHA512; - pss_params->mgf = CKG_MGF1_SHA512; - break; -+ -+ default: /* The non-RSA-PSS algorithms do not need any parameters */ -+ return 0; - } - - /* One of RSA-PSS mechanisms above: They need parameters */ -@@ -1820,8 +1823,6 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, - memset(&mech, 0, sizeof(mech)); - mech.mechanism = opt_mechanism; - hashlen = parse_pss_params(session, key, &mech, &pss_params); -- if (hashlen == 0) -- util_fatal("Invalid RSA-PSS parameters"); - - if (opt_input == NULL) - fd = 0; -@@ -1832,11 +1833,10 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, - if (r < 0) - util_fatal("Cannot read from %s: %m", opt_input); - -- if (opt_mechanism == CKM_RSA_PKCS_PSS) { -- if ((unsigned long)r != hashlen) -- util_fatal("For %s mechanism, message size (got %d bytes) " -- "must be equal to specified digest length (%lu)\n", -- p11_mechanism_to_name(opt_mechanism), r, hashlen); -+ if (opt_mechanism == CKM_RSA_PKCS_PSS && (unsigned long)r != hashlen) { -+ util_fatal("For %s mechanism, message size (got %d bytes) " -+ "must be equal to specified digest length (%lu)\n", -+ p11_mechanism_to_name(opt_mechanism), r, hashlen); - } - - rv = CKR_CANCEL; -@@ -1927,8 +1927,6 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, - memset(&mech, 0, sizeof(mech)); - mech.mechanism = opt_mechanism; - hashlen = parse_pss_params(session, key, &mech, &pss_params); -- if (hashlen == 0) -- util_fatal("Invalid RSA-PSS parameters"); - - /* Open a signature file */ - if (opt_signature_file == NULL) -@@ -1952,11 +1950,10 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session, - if (r < 0) - util_fatal("Cannot read from %s: %m", opt_input); - -- if (opt_mechanism == CKM_RSA_PKCS_PSS) { -- if ((unsigned long)r != hashlen) -- util_fatal("For %s mechanism, message size (got %d bytes)" -- " must be equal to specified digest length (%lu)\n", -- p11_mechanism_to_name(opt_mechanism), r, hashlen); -+ if (opt_mechanism == CKM_RSA_PKCS_PSS && (unsigned long)r != hashlen) { -+ util_fatal("For %s mechanism, message size (got %d bytes)" -+ " must be equal to specified digest length (%lu)\n", -+ p11_mechanism_to_name(opt_mechanism), r, hashlen); - } - - rv = CKR_CANCEL; --- -2.19.1 diff --git a/opensc-0.19.0.tar.gz b/opensc-0.19.0.tar.gz deleted file mode 100644 index 3b0a5cd..0000000 --- a/opensc-0.19.0.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2c5a0e4df9027635290b9c0f3addbbf0d651db5ddb0ab789cb0e978f02fd5826 -size 2080320 diff --git a/opensc-0.21.0.tar.gz b/opensc-0.21.0.tar.gz new file mode 100644 index 0000000..ff0d1d6 --- /dev/null +++ b/opensc-0.21.0.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2bfbbb1dcb4b8d8d75685a3e95c30798fb6411d4efab3690fd89d2cb25f3325e +size 2210878 diff --git a/opensc.changes b/opensc.changes index ce0e3dc..0aca6a5 100644 --- a/opensc.changes +++ b/opensc.changes @@ -1,3 +1,112 @@ +------------------------------------------------------------------- +Fri Nov 27 19:27:30 UTC 2020 - Andreas Stieger + +- 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 diff --git a/opensc.spec b/opensc.spec index d0bf3b6..b297c17 100644 --- a/opensc.spec +++ b/opensc.spec @@ -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