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