- 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>
206 lines
6.5 KiB
Diff
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
|
|
|