openssl-pkcs11/openssl-pkcs11-0.4.10-add-support-pin-source.patch
Anderson Toshiyuki Sasaki 20a5cf8c33 Backport recent bug fixes and enhancements
- Added support for "pin-source" within PKCS#11 URI (bz#1670026)
- Search objects in all matching tokens (bz#1760751)
- Set flag RSA_FLAG_EXT_PKEY for RSA keys (bz#1760541)
- Fixed various bugs

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
2019-10-11 12:53:49 +02:00

206 lines
6.5 KiB
Diff

From cf7ea69fe12f61a31c052a08352109646b16650f Mon Sep 17 00:00:00 2001
From: Stanislav Levin <slev@altlinux.org>
Date: Wed, 11 Sep 2019 15:40:34 +0300
Subject: [PATCH] Add support for pin-source within PKCS11 URI
According to https://tools.ietf.org/html/rfc7512#page-9:
"""
2.4. PKCS #11 URI Scheme Query Attribute Semantics
An application can always ask for a PIN by any means it decides to.
What is more, in order not to limit PKCS #11 URI portability, the
"pin-source" attribute value format and interpretation is left to be
implementation specific. However, the following rules SHOULD be
followed in descending order for the value of the "pin-source"
attribute:
o If the value represents a URI, it SHOULD be treated as an object
containing the PIN. Such a URI may be "file:", "https:", another
PKCS #11 URI, or something else.
o If the value contains "|<absolute-command-path>", the
implementation SHOULD read the PIN from the output of an
application specified with absolute path "<absolute-command-
path>". Note that character "|" representing a pipe does not have
to be percent-encoded in the query component of a PKCS #11 URI.
o Interpret the value as needed in an implementation-dependent way.
"""
This patch is based on:
https://github.com/OpenSC/libp11/pull/236,
but implements only the first clause of RFC, since the second one
is considered as dangerous.
For example, such functionality is required by FreeIPA
(Bind + OpenDNSSEC).
Fixes: https://github.com/OpenSC/libp11/issues/273
Co-authored-by: Ortigali Bazarov <ortigali.bazarov@gmail.com>
Signed-off-by: Stanislav Levin <slev@altlinux.org>
(cherry picked from commit 10295b7eb531aef1a9f7e990d5f2527c420b3b72)
---
src/eng_parse.c | 55 ++++++++++++++++++++++++++++++++++-
tests/rsa-evp-sign.softhsm | 59 ++++++++++++++++++++++++--------------
2 files changed, 91 insertions(+), 23 deletions(-)
diff --git a/src/eng_parse.c b/src/eng_parse.c
index f9d69e4..0c164c9 100644
--- a/src/eng_parse.c
+++ b/src/eng_parse.c
@@ -30,6 +30,10 @@
#include <stdio.h>
#include <string.h>
+#if defined(_WIN32) || defined(_WIN64)
+#define strncasecmp _strnicmp
+#endif
+
static int hex_to_bin(ENGINE_CTX *ctx,
const char *in, unsigned char *out, size_t *outlen)
{
@@ -263,6 +267,51 @@ static int parse_uri_attr(ENGINE_CTX *ctx,
return ret;
}
+static int read_from_file(ENGINE_CTX *ctx,
+ const char *path, char *field, size_t *field_len)
+{
+ BIO *fp;
+
+ fp = BIO_new_file(path, "r");
+ if (fp == NULL) {
+ ctx_log(ctx, 0, "Could not open file %s\n", path);
+ return 0;
+ }
+ if (BIO_gets(fp, field, *field_len) > 0) {
+ *field_len = strlen(field);
+ } else {
+ *field_len = 0;
+ }
+
+ BIO_free(fp);
+ return 1;
+}
+
+static int parse_pin_source(ENGINE_CTX *ctx,
+ const char *attr, int attrlen, unsigned char *field,
+ size_t *field_len)
+{
+ unsigned char *val;
+ int ret = 1;
+
+ if (!parse_uri_attr(ctx, attr, attrlen, &val, NULL)) {
+ return 0;
+ }
+
+ if (!strncasecmp((const char *)val, "file:", 5)) {
+ ret = read_from_file(ctx, (const char *)(val + 5), (char *)field, field_len);
+ } else if (*val == '|') {
+ ret = 0;
+ ctx_log(ctx, 0, "Unsupported pin-source syntax\n");
+ /* 'pin-source=/foo/bar' is commonly used */
+ } else {
+ ret = read_from_file(ctx, (const char *)val, (char *)field, field_len);
+ }
+ OPENSSL_free(val);
+
+ return ret;
+}
+
int parse_pkcs11_uri(ENGINE_CTX *ctx,
const char *uri, PKCS11_TOKEN **p_tok,
unsigned char *id, size_t *id_len, char *pin, size_t *pin_len,
@@ -309,7 +358,11 @@ int parse_pkcs11_uri(ENGINE_CTX *ctx,
id_set = 1;
} else if (!strncmp(p, "pin-value=", 10)) {
p += 10;
- rv = parse_uri_attr(ctx, p, end - p, (void *)&pin, pin_len);
+ rv = pin_set ? 0 : parse_uri_attr(ctx, p, end - p, (void *)&pin, pin_len);
+ pin_set = 1;
+ } else if (!strncmp(p, "pin-source=", 11)) {
+ p += 11;
+ rv = pin_set ? 0 : parse_pin_source(ctx, p, end - p, (unsigned char *)pin, pin_len);
pin_set = 1;
} else if (!strncmp(p, "type=", 5) || !strncmp(p, "object-type=", 12)) {
p = strchr(p, '=') + 1;
diff --git a/tests/rsa-evp-sign.softhsm b/tests/rsa-evp-sign.softhsm
index 7ef993d..bcc1cad 100755
--- a/tests/rsa-evp-sign.softhsm
+++ b/tests/rsa-evp-sign.softhsm
@@ -26,33 +26,48 @@ common_init
sed -e "s|@MODULE_PATH@|${MODULE}|g" -e "s|@ENGINE_PATH@|../src/.libs/pkcs11.so|g" <"${srcdir}/engines.cnf.in" >"${outdir}/engines.cnf"
+echo -n $PIN > $outdir/pin.txt
+
export OPENSSL_ENGINES="../src/.libs/"
-PRIVATE_KEY="pkcs11:token=libp11-test;id=%01%02%03%04;object=server-key;type=private;pin-value=1234"
-PUBLIC_KEY="pkcs11:token=libp11-test;id=%01%02%03%04;object=server-key;type=public;pin-value=1234"
-./evp-sign ctrl false "${outdir}/engines.cnf" ${PRIVATE_KEY} ${PUBLIC_KEY} ${MODULE}
-if test $? != 0;then
- echo "Basic PKCS #11 test, using ctrl failed"
- exit 1;
-fi
+KEY_ID="pkcs11:token=libp11-test;id=%01%02%03%04;object=server-key"
-./evp-sign default false "${outdir}/engines.cnf" ${PRIVATE_KEY} ${PUBLIC_KEY} ${MODULE}
-if test $? != 0;then
- echo "Basic PKCS #11 test, using default failed"
- exit 1;
-fi
+for PIN_ATTR in \
+ "pin-value=1234" \
+ "pin-source=$outdir/pin.txt" \
+ "pin-source=file:$outdir/pin.txt"
+do
-./evp-sign ctrl 1234 "${outdir}/engines.cnf" ${PRIVATE_KEY} ${PUBLIC_KEY} ${MODULE}
-if test $? != 0;then
- echo "Basic PKCS #11 test without pin-value, using ctrl failed"
- exit 1;
-fi
+ PRIVATE_KEY="$KEY_ID;type=private;$PIN_ATTR"
+ PUBLIC_KEY="$KEY_ID;type=public;$PIN_ATTR"
-./evp-sign default 1234 "${outdir}/engines.cnf" ${PRIVATE_KEY} ${PUBLIC_KEY} ${MODULE}
-if test $? != 0;then
- echo "Basic PKCS #11 test without pin-value, using default failed"
- exit 1;
-fi
+ echo $PRIVATE_KEY
+
+ ./evp-sign ctrl false "${outdir}/engines.cnf" ${PRIVATE_KEY} ${PUBLIC_KEY} ${MODULE}
+ if test $? != 0;then
+ echo "Basic PKCS #11 test, using ctrl failed"
+ exit 1;
+ fi
+
+ ./evp-sign default false "${outdir}/engines.cnf" ${PRIVATE_KEY} ${PUBLIC_KEY} ${MODULE}
+ if test $? != 0;then
+ echo "Basic PKCS #11 test, using default failed"
+ exit 1;
+ fi
+
+ ./evp-sign ctrl 1234 "${outdir}/engines.cnf" ${PRIVATE_KEY} ${PUBLIC_KEY} ${MODULE}
+ if test $? != 0;then
+ echo "Basic PKCS #11 test without pin-value, using ctrl failed"
+ exit 1;
+ fi
+
+ ./evp-sign default 1234 "${outdir}/engines.cnf" ${PRIVATE_KEY} ${PUBLIC_KEY} ${MODULE}
+ if test $? != 0;then
+ echo "Basic PKCS #11 test without pin-value, using default failed"
+ exit 1;
+ fi
+
+done
./evp-sign ctrl 1234 "${outdir}/engines.cnf" "label_server-key" "label_server-key" ${MODULE}
if test $? != 0;then
--
2.21.0