openssl-pkcs11 -- update to 0.4.12 (#9067)

Updated to openssl-pkcs11 version 0.4.12, tweaking only slightly from fedora 40
This commit is contained in:
Tobias Brick 2024-05-09 17:37:05 -07:00 коммит произвёл GitHub
Родитель e5eeecca41
Коммит 707651a4ee
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
10 изменённых файлов: 724 добавлений и 1258 удалений

Просмотреть файл

@ -1,205 +0,0 @@
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

Просмотреть файл

@ -1,868 +0,0 @@
From 8f39a0f78abff259b772339426d84578f50fd932 Mon Sep 17 00:00:00 2001
From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Date: Thu, 5 Sep 2019 18:29:53 +0200
Subject: [PATCH 1/2] tests/rsa-common: Add function to create various tokens
This allows the creation of multiple devices in the test scripts.
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 712e869189610f900ebf8c50090e228167b6bf8f)
---
tests/rsa-common.sh | 54 +++++++++++++++++++++++++++++++++++----------
1 file changed, 42 insertions(+), 12 deletions(-)
diff --git a/tests/rsa-common.sh b/tests/rsa-common.sh
index 7db5ba0..e6e12cb 100755
--- a/tests/rsa-common.sh
+++ b/tests/rsa-common.sh
@@ -86,13 +86,13 @@ init_db () {
# Create a new device
init_card () {
- PIN="$1"
- PUK="$2"
- DEV_LABEL="$3"
+ pin="$1"
+ puk="$2"
+ dev_label="$3"
- echo -n "* Initializing smart card... "
- ${SOFTHSM_TOOL} --init-token ${SLOT} --label "${DEV_LABEL}" \
- --so-pin "${PUK}" --pin "${PIN}" >/dev/null
+ echo -n "* Initializing smart card ${dev_label}..."
+ ${SOFTHSM_TOOL} --init-token ${SLOT} --label "${dev_label}" \
+ --so-pin "${puk}" --pin "${pin}" >/dev/null
if test $? = 0; then
echo ok
else
@@ -103,22 +103,26 @@ init_card () {
# Import objects to the token
import_objects () {
- ID=$1
- OBJ_LABEL=$2
+ id=$1
+ obj_label=$2
+ token_label=$3
- pkcs11-tool -p ${PIN} --module ${MODULE} -d ${ID} -a ${OBJ_LABEL} -l -w \
+ pkcs11-tool -p ${PIN} --module ${MODULE} -d ${id} \
+ --token-label ${token_label} -a ${obj_label} -l -w \
${srcdir}/rsa-prvkey.der -y privkey >/dev/null
if test $? != 0;then
exit 1;
fi
- pkcs11-tool -p ${PIN} --module ${MODULE} -d ${ID} -a ${OBJ_LABEL} -l -w \
+ pkcs11-tool -p ${PIN} --module ${MODULE} -d ${id} \
+ --token-label ${token_label} -a ${obj_label} -l -w \
${srcdir}/rsa-pubkey.der -y pubkey >/dev/null
if test $? != 0;then
exit 1;
fi
- pkcs11-tool -p ${PIN} --module ${MODULE} -d ${ID} -a ${OBJ_LABEL} -l -w \
+ pkcs11-tool -p ${PIN} --module ${MODULE} -d ${id} \
+ --token-label ${token_label} -a ${obj_label} -l -w \
${srcdir}/rsa-cert.der -y cert >/dev/null
if test $? != 0;then
exit 1;
@@ -148,8 +152,34 @@ common_init () {
echo Importing
# Import the used objects (private key, public key, and certificate)
- import_objects 01020304 "server-key"
+ import_objects 01020304 "server-key" "libp11-test"
# List the imported objects
list_objects
}
+
+create_devices () {
+ num_devices=$1
+ pin="$2"
+ puk="$3"
+ common_label="$4"
+ object_label="$5"
+
+ i=0
+ while [ $i -le ${num_devices} ]; do
+ init_card ${pin} ${puk} "${common_label}-$i"
+
+ echo "Importing objects to token ${common_label}-$i"
+ # Import objects with different labels
+ import_objects 01020304 "${object_label}-$i" "${common_label}-$i"
+
+ pkcs11-tool -p ${pin} --module ${MODULE} -l -O --token-label \
+ "${common_label}-$i"
+ if test $? != 0;then
+ echo Failed!
+ exit 1;
+ fi
+
+ i=$(($i + 1))
+ done
+}
--
2.21.0
From 8502b459544619286979ffa3ef6d4748d8066daa Mon Sep 17 00:00:00 2001
From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Date: Tue, 3 Sep 2019 19:04:27 +0200
Subject: [PATCH 2/2] eng_back: Search objects in all matching tokens
Previously, the search for objects would stop in the first matching
token when a more generic PKCS#11 URI was provided (e.g.
"pkcs11:type=public"). This change makes the search continue past the
first matching token if the object was not found.
In ctx_load_{key, cert}(), the search will try to login only if a single
token matched the search. This is to avoid trying the provided PIN
against all matching tokens which could lock the devices.
This also makes the search for objects to ignore uninitialized tokens
and to avoid trying to login when the token does not require login.
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 85a91f4502d48371df0d392d19cecfbced2388c0)
---
src/eng_back.c | 393 +++++++++++++++--------
tests/Makefile.am | 4 +-
tests/pkcs11-uri-without-token.softhsm | 62 ++++
tests/search-all-matching-tokens.softhsm | 106 ++++++
4 files changed, 426 insertions(+), 139 deletions(-)
create mode 100755 tests/pkcs11-uri-without-token.softhsm
create mode 100755 tests/search-all-matching-tokens.softhsm
diff --git a/src/eng_back.c b/src/eng_back.c
index 39a685a..afa6271 100644
--- a/src/eng_back.c
+++ b/src/eng_back.c
@@ -375,7 +375,7 @@ static X509 *ctx_load_cert(ENGINE_CTX *ctx, const char *s_slot_cert_id,
const int login)
{
PKCS11_SLOT *slot;
- PKCS11_SLOT *found_slot = NULL;
+ PKCS11_SLOT *found_slot = NULL, **matched_slots = NULL;
PKCS11_TOKEN *tok, *match_tok = NULL;
PKCS11_CERT *certs, *selected_cert = NULL;
X509 *x509;
@@ -387,6 +387,7 @@ static X509 *ctx_load_cert(ENGINE_CTX *ctx, const char *s_slot_cert_id,
size_t tmp_pin_len = MAX_PIN_LENGTH;
int slot_nr = -1;
char flags[64];
+ size_t matched_count = 0;
if (ctx_init_libp11(ctx)) /* Delayed libp11 initialization */
return NULL;
@@ -401,11 +402,9 @@ static X509 *ctx_load_cert(ENGINE_CTX *ctx, const char *s_slot_cert_id,
"The certificate ID is not a valid PKCS#11 URI\n"
"The PKCS#11 URI format is defined by RFC7512\n");
ENGerr(ENG_F_CTX_LOAD_CERT, ENG_R_INVALID_ID);
- return NULL;
+ goto error;
}
if (tmp_pin_len > 0 && tmp_pin[0] != 0) {
- if (!login)
- return NULL; /* Process on second attempt */
ctx_destroy_pin(ctx);
ctx->pin = OPENSSL_malloc(MAX_PIN_LENGTH+1);
if (ctx->pin != NULL) {
@@ -424,7 +423,7 @@ static X509 *ctx_load_cert(ENGINE_CTX *ctx, const char *s_slot_cert_id,
"The legacy ENGINE_pkcs11 ID format is also "
"still accepted for now\n");
ENGerr(ENG_F_CTX_LOAD_CERT, ENG_R_INVALID_ID);
- return NULL;
+ goto error;
}
}
ctx_log(ctx, 1, "Looking in slot %d for certificate: ",
@@ -440,6 +439,13 @@ static X509 *ctx_load_cert(ENGINE_CTX *ctx, const char *s_slot_cert_id,
ctx_log(ctx, 1, "\n");
}
+ matched_slots = (PKCS11_SLOT **)calloc(ctx->slot_count,
+ sizeof(PKCS11_SLOT *));
+ if (matched_slots == NULL) {
+ ctx_log(ctx, 0, "Could not allocate memory for matched slots\n");
+ goto error;
+ }
+
for (n = 0; n < ctx->slot_count; n++) {
slot = ctx->slot_list + n;
flags[0] = '\0';
@@ -463,6 +469,7 @@ static X509 *ctx_load_cert(ENGINE_CTX *ctx, const char *s_slot_cert_id,
slot_nr == (int)PKCS11_get_slotid_from_slot(slot)) {
found_slot = slot;
}
+
if (match_tok && slot->token &&
(match_tok->label == NULL ||
!strcmp(match_tok->label, slot->token->label)) &&
@@ -483,75 +490,115 @@ static X509 *ctx_load_cert(ENGINE_CTX *ctx, const char *s_slot_cert_id,
slot->token->label : "no label");
}
ctx_log(ctx, 1, "\n");
- }
- if (match_tok) {
- OPENSSL_free(match_tok->model);
- OPENSSL_free(match_tok->manufacturer);
- OPENSSL_free(match_tok->serialnr);
- OPENSSL_free(match_tok->label);
- OPENSSL_free(match_tok);
- }
- if (found_slot) {
- slot = found_slot;
- } else if (match_tok) {
- ctx_log(ctx, 0, "Specified object not found\n");
- return NULL;
- } else if (slot_nr == -1) {
- if (!(slot = PKCS11_find_token(ctx->pkcs11_ctx,
- ctx->slot_list, ctx->slot_count))) {
- ctx_log(ctx, 0, "No tokens found\n");
- return NULL;
- }
- } else {
- ctx_log(ctx, 0, "Invalid slot number: %d\n", slot_nr);
- return NULL;
- }
- tok = slot->token;
+ if (found_slot && found_slot->token && !found_slot->token->initialized)
+ ctx_log(ctx, 0, "Found uninitialized token\n");
- if (tok == NULL) {
- ctx_log(ctx, 0, "Empty token found\n");
- return NULL;
+ /* Ignore slots without tokens or with uninitialized token */
+ if (found_slot && found_slot->token && found_slot->token->initialized) {
+ matched_slots[matched_count] = found_slot;
+ matched_count++;
+ }
+ found_slot = NULL;
}
- ctx_log(ctx, 1, "Found slot: %s\n", slot->description);
- ctx_log(ctx, 1, "Found token: %s\n", slot->token->label);
+ if (matched_count == 0) {
+ if (match_tok) {
+ ctx_log(ctx, 0, "Specified object not found\n");
+ goto error;
+ }
- /* In several tokens certificates are marked as private */
- if (login && !ctx_login(ctx, slot, tok,
- ctx->ui_method, ctx->callback_data)) {
- ctx_log(ctx, 0, "Login to token failed, returning NULL...\n");
- return NULL;
+ /* If the legacy slot ID format was used */
+ if (slot_nr != -1) {
+ ctx_log(ctx, 0, "Invalid slot number: %d\n", slot_nr);
+ goto error;
+ } else {
+ found_slot = PKCS11_find_token(ctx->pkcs11_ctx,
+ ctx->slot_list, ctx->slot_count);
+ /* Ignore if the the token is not initialized */
+ if (found_slot && found_slot->token &&
+ found_slot->token->initialized) {
+ matched_slots[matched_count] = found_slot;
+ matched_count++;
+ } else {
+ ctx_log(ctx, 0, "No tokens found\n");
+ goto error;
+ }
+ }
}
- if (PKCS11_enumerate_certs(tok, &certs, &cert_count)) {
- ctx_log(ctx, 0, "Unable to enumerate certificates\n");
- return NULL;
- }
+ for (n = 0; n < matched_count; n++) {
+ slot = matched_slots[n];
+ tok = slot->token;
+ if (tok == NULL) {
+ ctx_log(ctx, 0, "Empty token found\n");
+ break;
+ }
- ctx_log(ctx, 1, "Found %u cert%s:\n", cert_count,
- (cert_count <= 1) ? "" : "s");
- if ((s_slot_cert_id && *s_slot_cert_id) &&
- (cert_id_len != 0 || cert_label != NULL)) {
- for (n = 0; n < cert_count; n++) {
- PKCS11_CERT *k = certs + n;
+ ctx_log(ctx, 1, "Found slot: %s\n", slot->description);
+ ctx_log(ctx, 1, "Found token: %s\n", slot->token->label);
+
+ /* In several tokens certificates are marked as private */
+ if (login) {
+ /* Only try to login if login is required */
+ if (tok->loginRequired) {
+ /* Only try to login if a single slot matched to avoiding trying
+ * the PIN against all matching slots */
+ if (matched_count == 1) {
+ if (!ctx_login(ctx, slot, tok,
+ ctx->ui_method, ctx->callback_data)) {
+ ctx_log(ctx, 0, "Login to token failed, returning NULL...\n");
+ goto error;
+ }
+ } else {
+ ctx_log(ctx, 0, "Multiple matching slots (%lu); will not try to"
+ " login\n", matched_count);
+ for (m = 0; m < matched_count; m++){
+ slot = matched_slots[m];
+ ctx_log(ctx, 0, "[%u] %s: %s\n", m + 1,
+ slot->description? slot->description:
+ "(no description)",
+ (slot->token && slot->token->label)?
+ slot->token->label: "no label");
+ }
+ goto error;
+ }
+ }
+ }
- if (cert_label != NULL && strcmp(k->label, cert_label) == 0)
- selected_cert = k;
- if (cert_id_len != 0 && k->id_len == cert_id_len &&
- memcmp(k->id, cert_id, cert_id_len) == 0)
- selected_cert = k;
+ if (PKCS11_enumerate_certs(tok, &certs, &cert_count)) {
+ ctx_log(ctx, 0, "Unable to enumerate certificates\n");
+ continue;
}
- } else {
- for (n = 0; n < cert_count; n++) {
- PKCS11_CERT *k = certs + n;
- if (k->id && *(k->id)) {
- selected_cert = k; /* Use the first certificate with nonempty id */
- break;
+
+ ctx_log(ctx, 1, "Found %u cert%s:\n", cert_count,
+ (cert_count <= 1) ? "" : "s");
+ if ((s_slot_cert_id && *s_slot_cert_id) &&
+ (cert_id_len != 0 || cert_label != NULL)) {
+ for (m = 0; m < cert_count; m++) {
+ PKCS11_CERT *k = certs + m;
+
+ if (cert_label != NULL && strcmp(k->label, cert_label) == 0)
+ selected_cert = k;
+ if (cert_id_len != 0 && k->id_len == cert_id_len &&
+ memcmp(k->id, cert_id, cert_id_len) == 0)
+ selected_cert = k;
+ }
+ } else {
+ for (m = 0; m < cert_count; m++) {
+ PKCS11_CERT *k = certs + m;
+ if (k->id && *(k->id)) {
+ selected_cert = k; /* Use the first certificate with nonempty id */
+ break;
+ }
}
+ if (!selected_cert)
+ selected_cert = certs; /* Use the first certificate */
+ }
+
+ if (selected_cert) {
+ break;
}
- if (!selected_cert)
- selected_cert = certs; /* Use the first certificate */
}
if (selected_cert != NULL) {
@@ -561,8 +608,20 @@ static X509 *ctx_load_cert(ENGINE_CTX *ctx, const char *s_slot_cert_id,
ctx_log(ctx, 0, "Certificate not found.\n");
x509 = NULL;
}
+error:
+ /* Free the searched token data */
+ if (match_tok) {
+ OPENSSL_free(match_tok->model);
+ OPENSSL_free(match_tok->manufacturer);
+ OPENSSL_free(match_tok->serialnr);
+ OPENSSL_free(match_tok->label);
+ OPENSSL_free(match_tok);
+ }
+
if (cert_label != NULL)
OPENSSL_free(cert_label);
+ if (matched_slots != NULL)
+ free(matched_slots);
return x509;
}
@@ -605,7 +664,7 @@ static EVP_PKEY *ctx_load_key(ENGINE_CTX *ctx, const char *s_slot_key_id,
const int isPrivate, const int login)
{
PKCS11_SLOT *slot;
- PKCS11_SLOT *found_slot = NULL;
+ PKCS11_SLOT *found_slot = NULL, **matched_slots = NULL;
PKCS11_TOKEN *tok, *match_tok = NULL;
PKCS11_KEY *keys, *selected_key = NULL;
EVP_PKEY *pk = NULL;
@@ -617,6 +676,7 @@ static EVP_PKEY *ctx_load_key(ENGINE_CTX *ctx, const char *s_slot_key_id,
char tmp_pin[MAX_PIN_LENGTH+1];
size_t tmp_pin_len = MAX_PIN_LENGTH;
char flags[64];
+ size_t matched_count = 0;
if (ctx_init_libp11(ctx)) /* Delayed libp11 initialization */
goto error;
@@ -637,7 +697,9 @@ static EVP_PKEY *ctx_load_key(ENGINE_CTX *ctx, const char *s_slot_key_id,
goto error;
}
if (tmp_pin_len > 0 && tmp_pin[0] != 0) {
- if (!login)
+ /* If the searched key is public, try without login once even
+ * when the PIN is provided */
+ if (!login && isPrivate)
goto error; /* Process on second attempt */
ctx_destroy_pin(ctx);
ctx->pin = OPENSSL_malloc(MAX_PIN_LENGTH+1);
@@ -673,6 +735,13 @@ static EVP_PKEY *ctx_load_key(ENGINE_CTX *ctx, const char *s_slot_key_id,
ctx_log(ctx, 1, "\n");
}
+ matched_slots = (PKCS11_SLOT **)calloc(ctx->slot_count,
+ sizeof(PKCS11_SLOT *));
+ if (matched_slots == NULL) {
+ ctx_log(ctx, 0, "Could not allocate memory for matched slots\n");
+ goto error;
+ }
+
for (n = 0; n < ctx->slot_count; n++) {
slot = ctx->slot_list + n;
flags[0] = '\0';
@@ -696,6 +765,7 @@ static EVP_PKEY *ctx_load_key(ENGINE_CTX *ctx, const char *s_slot_key_id,
slot_nr == (int)PKCS11_get_slotid_from_slot(slot)) {
found_slot = slot;
}
+
if (match_tok && slot->token &&
(match_tok->label == NULL ||
!strcmp(match_tok->label, slot->token->label)) &&
@@ -716,92 +786,128 @@ static EVP_PKEY *ctx_load_key(ENGINE_CTX *ctx, const char *s_slot_key_id,
slot->token->label : "no label");
}
ctx_log(ctx, 1, "\n");
- }
- if (match_tok) {
- OPENSSL_free(match_tok->model);
- OPENSSL_free(match_tok->manufacturer);
- OPENSSL_free(match_tok->serialnr);
- OPENSSL_free(match_tok->label);
- OPENSSL_free(match_tok);
+ if (found_slot && found_slot->token && !found_slot->token->initialized)
+ ctx_log(ctx, 0, "Found uninitialized token\n");
+
+ /* Ignore slots without tokens or with uninitialized token */
+ if (found_slot && found_slot->token && found_slot->token->initialized) {
+ matched_slots[matched_count] = found_slot;
+ matched_count++;
+ }
+ found_slot = NULL;
}
- if (found_slot) {
- slot = found_slot;
- } else if (match_tok) {
- ctx_log(ctx, 0, "Specified object not found\n");
- goto error;
- } else if (slot_nr == -1) {
- if (!(slot = PKCS11_find_token(ctx->pkcs11_ctx,
- ctx->slot_list, ctx->slot_count))) {
- ctx_log(ctx, 0, "No tokens found\n");
+
+ if (matched_count == 0) {
+ if (match_tok) {
+ ctx_log(ctx, 0, "Specified object not found\n");
goto error;
}
- } else {
- ctx_log(ctx, 0, "Invalid slot number: %d\n", slot_nr);
- goto error;
- }
- tok = slot->token;
- if (tok == NULL) {
- ctx_log(ctx, 0, "Found empty token\n");
- goto error;
+ /* If the legacy slot ID format was used */
+ if (slot_nr != -1) {
+ ctx_log(ctx, 0, "Invalid slot number: %d\n", slot_nr);
+ goto error;
+ } else {
+ found_slot = PKCS11_find_token(ctx->pkcs11_ctx,
+ ctx->slot_list, ctx->slot_count);
+ /* Ignore if the the token is not initialized */
+ if (found_slot && found_slot->token &&
+ found_slot->token->initialized) {
+ matched_slots[matched_count] = found_slot;
+ matched_count++;
+ } else {
+ ctx_log(ctx, 0, "No tokens found\n");
+ goto error;
+ }
+ }
}
- /* The following check is non-critical to ensure interoperability
- * with some other (which ones?) PKCS#11 libraries */
- if (!tok->initialized)
- ctx_log(ctx, 0, "Found uninitialized token\n");
- ctx_log(ctx, 1, "Found slot: %s\n", slot->description);
- ctx_log(ctx, 1, "Found token: %s\n", slot->token->label);
+ for (n = 0; n < matched_count; n++) {
+ slot = matched_slots[n];
+ tok = slot->token;
+ if (tok == NULL) {
+ ctx_log(ctx, 0, "Found empty token\n");
+ break;
+ }
- /* Both private and public keys can have the CKA_PRIVATE attribute
- * set and thus require login (even to retrieve attributes!) */
- if (login && !ctx_login(ctx, slot, tok, ui_method, callback_data)) {
- ctx_log(ctx, 0, "Login to token failed, returning NULL...\n");
- goto error;
- }
+ ctx_log(ctx, 1, "Found slot: %s\n", slot->description);
+ ctx_log(ctx, 1, "Found token: %s\n", slot->token->label);
+
+ /* Both private and public keys can have the CKA_PRIVATE attribute
+ * set and thus require login (even to retrieve attributes!) */
+ if (login) {
+ /* Try to login only if login is required */
+ if (tok->loginRequired) {
+ /* Try to login only if a single slot matched to avoiding trying
+ * the PIN against all matching slots */
+ if (matched_count == 1) {
+ if (!ctx_login(ctx, slot, tok, ui_method, callback_data)) {
+ ctx_log(ctx, 0, "Login to token failed, returning NULL...\n");
+ goto error;
+ }
+ } else {
+ ctx_log(ctx, 0, "Multiple matching slots (%lu); will not try to"
+ " login\n", matched_count);
+ for (m = 0; m < matched_count; m++){
+ slot = matched_slots[m];
+ ctx_log(ctx, 1, "[%u] %s: %s\n", m + 1,
+ slot->description? slot->description:
+ "(no description)",
+ (slot->token && slot->token->label)?
+ slot->token->label: "no label");
+ }
+ goto error;
+ }
+ }
+ }
- if (isPrivate) {
- /* Make sure there is at least one private key on the token */
- if (PKCS11_enumerate_keys(tok, &keys, &key_count)) {
- ctx_log(ctx, 0, "Unable to enumerate private keys\n");
- goto error;
+ if (isPrivate) {
+ /* Make sure there is at least one private key on the token */
+ if (PKCS11_enumerate_keys(tok, &keys, &key_count)) {
+ ctx_log(ctx, 0, "Unable to enumerate private keys\n");
+ continue;
+ }
+ } else {
+ /* Make sure there is at least one public key on the token */
+ if (PKCS11_enumerate_public_keys(tok, &keys, &key_count)) {
+ ctx_log(ctx, 0, "Unable to enumerate public keys\n");
+ continue;
+ }
}
- } else {
- /* Make sure there is at least one public key on the token */
- if (PKCS11_enumerate_public_keys(tok, &keys, &key_count)) {
- ctx_log(ctx, 0, "Unable to enumerate public keys\n");
- goto error;
+ if (key_count == 0) {
+ if (login) /* Only print the error on the second attempt */
+ ctx_log(ctx, 0, "No %s keys found.\n",
+ (char *)(isPrivate ? "private" : "public"));
+ continue;
}
- }
- if (key_count == 0) {
- if (login) /* Only print the error on the second attempt */
- ctx_log(ctx, 0, "No %s keys found.\n",
- (char *)(isPrivate ? "private" : "public"));
- goto error;
- }
- ctx_log(ctx, 1, "Found %u %s key%s:\n", key_count,
- (char *)(isPrivate ? "private" : "public"),
- (key_count == 1) ? "" : "s");
-
- if (s_slot_key_id && *s_slot_key_id &&
- (key_id_len != 0 || key_label != NULL)) {
- for (n = 0; n < key_count; n++) {
- PKCS11_KEY *k = keys + n;
-
- ctx_log(ctx, 1, " %2u %c%c id=", n + 1,
- k->isPrivate ? 'P' : ' ',
- k->needLogin ? 'L' : ' ');
- dump_hex(ctx, 1, k->id, k->id_len);
- ctx_log(ctx, 1, " label=%s\n", k->label);
- if (key_label != NULL && strcmp(k->label, key_label) == 0)
- selected_key = k;
- if (key_id_len != 0 && k->id_len == key_id_len
- && memcmp(k->id, key_id, key_id_len) == 0)
- selected_key = k;
+ ctx_log(ctx, 1, "Found %u %s key%s:\n", key_count,
+ (char *)(isPrivate ? "private" : "public"),
+ (key_count == 1) ? "" : "s");
+
+ if (s_slot_key_id && *s_slot_key_id &&
+ (key_id_len != 0 || key_label != NULL)) {
+ for (m = 0; m < key_count; m++) {
+ PKCS11_KEY *k = keys + m;
+
+ ctx_log(ctx, 1, " %2u %c%c id=", m + 1,
+ k->isPrivate ? 'P' : ' ',
+ k->needLogin ? 'L' : ' ');
+ dump_hex(ctx, 1, k->id, k->id_len);
+ ctx_log(ctx, 1, " label=%s\n", k->label);
+ if (key_label != NULL && strcmp(k->label, key_label) == 0)
+ selected_key = k;
+ if (key_id_len != 0 && k->id_len == key_id_len
+ && memcmp(k->id, key_id, key_id_len) == 0)
+ selected_key = k;
+ }
+ } else {
+ selected_key = keys; /* Use the first key */
+ }
+
+ if (selected_key) {
+ break;
}
- } else {
- selected_key = keys; /* Use the first key */
}
if (selected_key != NULL) {
@@ -813,9 +919,20 @@ static EVP_PKEY *ctx_load_key(ENGINE_CTX *ctx, const char *s_slot_key_id,
ctx_log(ctx, 0, "Key not found.\n");
pk = NULL;
}
+
error:
+ /* Free the searched token data */
+ if (match_tok) {
+ OPENSSL_free(match_tok->model);
+ OPENSSL_free(match_tok->manufacturer);
+ OPENSSL_free(match_tok->serialnr);
+ OPENSSL_free(match_tok->label);
+ OPENSSL_free(match_tok);
+ }
if (key_label != NULL)
OPENSSL_free(key_label);
+ if (matched_slots != NULL)
+ free(matched_slots);
return pk;
}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index e7d61ee..4fa22dc 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -28,7 +28,9 @@ dist_check_SCRIPTS = \
rsa-pss-sign.softhsm \
rsa-oaep.softhsm \
case-insensitive.softhsm \
- ec-check-privkey.softhsm
+ ec-check-privkey.softhsm \
+ pkcs11-uri-without-token.softhsm \
+ search-all-matching-tokens.softhsm
dist_check_DATA = \
rsa-cert.der rsa-prvkey.der rsa-pubkey.der \
ec-cert.der ec-prvkey.der ec-pubkey.der
diff --git a/tests/pkcs11-uri-without-token.softhsm b/tests/pkcs11-uri-without-token.softhsm
new file mode 100755
index 0000000..f82e1f4
--- /dev/null
+++ b/tests/pkcs11-uri-without-token.softhsm
@@ -0,0 +1,62 @@
+#!/bin/sh
+
+# Copyright (C) 2015 Nikos Mavrogiannopoulos
+#
+# GnuTLS is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+#
+# GnuTLS is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GnuTLS; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# This test checks if it is possible to use the keys without specifying the
+# token if there is only one initialized token available.
+
+outdir="output.$$"
+
+# Load common test functions
+. ${srcdir}/rsa-common.sh
+
+# Do the common test initialization
+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"
+
+export OPENSSL_ENGINES="../src/.libs/"
+export OPENSSL_CONF="${outdir}/engines.cnf"
+
+# These URIs don't contain the token specification
+PRIVATE_KEY="pkcs11:object=server-key;type=private;pin-value=1234"
+PUBLIC_KEY="pkcs11:object=server-key;type=public;pin-value=1234"
+
+# Create input file
+echo "secret" >"${outdir}/in.txt"
+
+# Generate signature without specifying the token in the PKCS#11 URI
+openssl pkeyutl -engine pkcs11 -keyform engine -inkey "${PRIVATE_KEY}" \
+ -sign -out "${outdir}/signature.bin" -in "${outdir}/in.txt"
+if test $? != 0;then
+ echo "Failed to generate signature using PKCS#11 URI ${PRIVATE_KEY}"
+ exit 1;
+fi
+
+# Verify the signature without specifying the token in the PKCS#11 URI
+openssl pkeyutl -engine pkcs11 -keyform engine -pubin -inkey "${PUBLIC_KEY}" \
+ -verify -sigfile "${outdir}/signature.bin" -in "${outdir}/in.txt"
+if test $? != 0;then
+ echo "Failed to verify signature using PKCS#11 URI ${PUBLIC_KEY}"
+ exit 1;
+fi
+
+rm -rf "$outdir"
+
+exit 0
diff --git a/tests/search-all-matching-tokens.softhsm b/tests/search-all-matching-tokens.softhsm
new file mode 100755
index 0000000..d0810c4
--- /dev/null
+++ b/tests/search-all-matching-tokens.softhsm
@@ -0,0 +1,106 @@
+#!/bin/sh
+
+# Copyright (C) 2015 Nikos Mavrogiannopoulos
+#
+# GnuTLS is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+#
+# GnuTLS is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GnuTLS; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# This test checks if the search for objects in tokens will continue past the
+# first token found.
+#
+# Generic PKCS#11 URIs are used to make the search to match more than one
+# token. The search should be able to find the objects in each device, which are
+# labeled differently per token.
+#
+# This test also contains a negative test to verify that the engine will not try
+# to login to a token if more than one token matched the search. This is why it
+# is required to have only one match to be able to use a private key.
+
+outdir="output.$$"
+
+# Load common test functions
+. ${srcdir}/rsa-common.sh
+
+PIN=1234
+PUK=1234
+
+NUM_DEVICES=5
+
+# Initialize the SoftHSM DB
+init_db
+
+# Create some devices
+create_devices $NUM_DEVICES $PIN $PUK "libp11-test" "label"
+
+sed -e "s|@MODULE_PATH@|${MODULE}|g" -e "s|@ENGINE_PATH@|../src/.libs/pkcs11.so|g" <"${srcdir}/engines.cnf.in" >"${outdir}/engines.cnf"
+
+export OPENSSL_ENGINES="../src/.libs/"
+export OPENSSL_CONF="${outdir}/engines.cnf"
+
+PRIVATE_KEY="pkcs11:token=libp11-test-3;object=label-3;type=private;pin-value=1234"
+PRIVATE_KEY_WITHOUT_TOKEN="pkcs11:object=label-3;type=private;pin-value=1234"
+PUBLIC_KEY_ANY="pkcs11:type=public"
+CERTIFICATE="pkcs11:object=label-3;type=cert;pin-value=1234"
+
+# Create input file
+echo "secret" > "${outdir}/in.txt"
+
+# Verify that it doesn't try to login if more than one token matched the search
+openssl pkeyutl -engine pkcs11 -keyform engine \
+ -inkey "${PRIVATE_KEY_WITHOUT_TOKEN}" \
+ -sign -out "${outdir}/signature.bin" -in "${outdir}/in.txt"
+if test $? = 0;then
+ echo "Did not fail when the PKCS#11 URI matched multiple tokens"
+fi
+
+# Generate signature specifying the token in the PKCS#11 URI
+openssl pkeyutl -engine pkcs11 -keyform engine -inkey "${PRIVATE_KEY}" \
+ -sign -out "${outdir}/signature.bin" -in "${outdir}/in.txt"
+if test $? != 0;then
+ echo "Failed to sign file using PKCS#11 URI ${PRIVATE_KEY}"
+ exit 1;
+fi
+
+# Verify the signature using the public key from each token
+i=0
+while [ $i -le ${NUM_DEVICES} ]; do
+ pubkey="pkcs11:object=label-$i;type=public;pin-value=1234"
+ openssl pkeyutl -engine pkcs11 -keyform engine -pubin -inkey "${pubkey}" \
+ -verify -sigfile "${outdir}/signature.bin" -in "${outdir}/in.txt"
+ if test $? != 0;then
+ echo "Failed to verify the signature using the PKCS#11 URI ${pubkey}"
+ exit 1;
+ fi
+ i=$(($i + 1))
+done
+
+# Verify the signature using a certificate without specifying the token
+openssl pkeyutl -engine pkcs11 -keyform engine -pubin -inkey "${CERTIFICATE}" \
+ -verify -sigfile "${outdir}/signature.bin" -in "${outdir}/in.txt"
+if test $? != 0;then
+ echo "Failed to verify the signature using the PKCS#11 URI ${CERTIFICATE}"
+ exit 1;
+fi
+
+# Verify the signature using the first public key found
+openssl pkeyutl -engine pkcs11 -keyform engine -pubin -inkey "${PUBLIC_KEY_ANY}" \
+ -verify -sigfile "${outdir}/signature.bin" -in "${outdir}/in.txt"
+if test $? != 0;then
+ echo "Failed to verify the signature using the PKCS#11 URI ${PUBLIC_KEY_ANY}."
+ exit 1;
+fi
+
+rm -rf "$outdir"
+
+exit 0
--
2.21.0

Просмотреть файл

@ -1,7 +1,7 @@
--- a/src/p11_rsa.c 2019-04-03 21:58:18.000000000 +0200
+++ b/src/p11_rsa.c 2019-11-28 15:46:18.898258545 +0100
@@ -478,7 +478,7 @@
if (ops == NULL)
if (!ops)
return NULL;
RSA_meth_set1_name(ops, "libp11 RSA method");
- RSA_meth_set_flags(ops, 0);

Просмотреть файл

@ -1,47 +0,0 @@
From e7ecd9298c8744a7e3f253178e6d1f12c5310dde Mon Sep 17 00:00:00 2001
From: Stanislav Levin <slev@altlinux.org>
Date: Tue, 17 Sep 2019 10:05:28 +0300
Subject: [PATCH] Set RSA_FLAG_EXT_PKEY flag
From docs:
"""
This flag means the private key operations will be handled by
rsa_mod_exp and that they do not depend on the private key
components being present:
for example a key stored in external hardware. Without this flag
bn_mod_exp gets called when private key components are absent.
"""
Setting this flag allows BIND to identify RSA key (stored on a HSM)
as a private key. Otherwise, BIND fails to sign and to verify signs.
Fixes: https://github.com/OpenSC/libp11/issues/304
Signed-off-by: Stanislav Levin <slev@altlinux.org>
(cherry picked from commit b487da5a0f69576139949d7235b988e822137cab)
---
src/p11_rsa.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/p11_rsa.c b/src/p11_rsa.c
index e699009..66db996 100644
--- a/src/p11_rsa.c
+++ b/src/p11_rsa.c
@@ -273,8 +273,14 @@ static EVP_PKEY *pkcs11_get_evp_key_rsa(PKCS11_KEY *key)
}
EVP_PKEY_set1_RSA(pk, rsa); /* Also increments the rsa ref count */
- if (key->isPrivate)
+ if (key->isPrivate) {
RSA_set_method(rsa, PKCS11_get_rsa_method());
+#if OPENSSL_VERSION_NUMBER >= 0x10100005L && !defined(LIBRESSL_VERSION_NUMBER)
+ RSA_set_flags(rsa, RSA_FLAG_EXT_PKEY);
+#else
+ rsa->flags |= RSA_FLAG_EXT_PKEY;
+#endif
+ }
/* TODO: Retrieve the RSA private key object attributes instead,
* unless the key has the "sensitive" attribute set */
--
2.21.0

Просмотреть файл

@ -1,112 +0,0 @@
From fd49562b40c21b1ce920a10fe76bdbaf4e4de7d2 Mon Sep 17 00:00:00 2001
From: Henrik Riomar <henrik.riomar@gmail.com>
Date: Wed, 10 Apr 2019 13:54:17 +0200
Subject: [PATCH 1/3] add needed include for getpid()
Fixes:
p11_atfork.c: In function '_P11_get_forkid':
p11_atfork.c:78:9: warning: implicit declaration of function 'getpid'; did you mean 'getenv'? [-Wimplicit-function-declaration]
return getpid();
(cherry picked from commit 97700cb51ac1e84f5ac8bc402e6f9e0fc271d76b)
---
src/p11_atfork.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/p11_atfork.c b/src/p11_atfork.c
index 8fc8689..43c38f7 100644
--- a/src/p11_atfork.c
+++ b/src/p11_atfork.c
@@ -23,6 +23,7 @@
#include "libp11-int.h"
#ifndef _WIN32
+#include <unistd.h>
#ifndef __STDC_VERSION__
/* older than C90 */
--
2.21.0
From 859fe17862f44e4dc266bcdf67b91c87ffe756c6 Mon Sep 17 00:00:00 2001
From: ucq <ucq@cyberdefense.jp>
Date: Tue, 14 May 2019 12:17:45 +0900
Subject: [PATCH 2/3] fix use-after-free on PKCS11_pkey_meths.
(cherry picked from commit e64496a198d4d2eb0310a22dc21be8b81367d319)
---
src/p11_pkey.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/src/p11_pkey.c b/src/p11_pkey.c
index 7eaf761..2995881 100644
--- a/src/p11_pkey.c
+++ b/src/p11_pkey.c
@@ -666,8 +666,8 @@ int PKCS11_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth,
EVP_PKEY_EC,
0
};
- static EVP_PKEY_METHOD *pkey_method_rsa = NULL;
- static EVP_PKEY_METHOD *pkey_method_ec = NULL;
+ EVP_PKEY_METHOD *pkey_method_rsa = NULL;
+ EVP_PKEY_METHOD *pkey_method_ec = NULL;
(void)e; /* squash the unused parameter warning */
/* all PKCS#11 engines currently share the same pkey_meths */
@@ -680,16 +680,14 @@ int PKCS11_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth,
/* get the EVP_PKEY_METHOD */
switch (nid) {
case EVP_PKEY_RSA:
- if (pkey_method_rsa == NULL)
- pkey_method_rsa = pkcs11_pkey_method_rsa();
+ pkey_method_rsa = pkcs11_pkey_method_rsa();
if (pkey_method_rsa == NULL)
return 0;
*pmeth = pkey_method_rsa;
return 1; /* success */
#ifndef OPENSSL_NO_EC
case EVP_PKEY_EC:
- if (pkey_method_ec == NULL)
- pkey_method_ec = pkcs11_pkey_method_ec();
+ pkey_method_ec = pkcs11_pkey_method_ec();
if (pkey_method_ec == NULL)
return 0;
*pmeth = pkey_method_ec;
--
2.21.0
From 1031cae70b8f91089ea2ef4e70e954ba9258bfc7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Trojnara?= <Michal.Trojnara@stunnel.org>
Date: Wed, 14 Aug 2019 15:23:41 +0200
Subject: [PATCH 3/3] Remove an unused variable
(cherry picked from commit 5d48d2ff75918409684a6aefe5b1f3e5d8ec7f0d)
---
src/p11_pkey.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/p11_pkey.c b/src/p11_pkey.c
index 2995881..de0277e 100644
--- a/src/p11_pkey.c
+++ b/src/p11_pkey.c
@@ -545,7 +545,7 @@ static int pkcs11_try_pkey_ec_sign(EVP_PKEY_CTX *evp_pkey_ctx,
ossl_sig = ECDSA_SIG_new();
if (ossl_sig == NULL)
- return-1;
+ return -1;
pkey = EVP_PKEY_CTX_get0_pkey(evp_pkey_ctx);
if (pkey == NULL)
@@ -578,7 +578,6 @@ static int pkcs11_try_pkey_ec_sign(EVP_PKEY_CTX *evp_pkey_ctx,
return -1;
if (!cpriv->sign_initialized) {
- int padding;
CK_MECHANISM mechanism;
memset(&mechanism, 0, sizeof mechanism);
--
2.21.0

Просмотреть файл

@ -0,0 +1,394 @@
diff --git a/src/libp11-int.h b/src/libp11-int.h
index 2d4c48a..ffe0e2e 100644
--- a/src/libp11-int.h
+++ b/src/libp11-int.h
@@ -93,6 +93,8 @@ struct pkcs11_object_private {
EVP_PKEY *evp_key;
X509 *x509;
unsigned int forkid;
+ int refcnt;
+ pthread_mutex_t lock;
};
#define PRIVKEY(_key) ((PKCS11_OBJECT_private *) (_key)->_private)
#define PRIVCERT(_cert) ((PKCS11_OBJECT_private *) (_cert)->_private)
@@ -253,6 +255,9 @@ extern PKCS11_OBJECT_private *pkcs11_object_from_template(PKCS11_SLOT_private *s
extern PKCS11_OBJECT_private *pkcs11_object_from_object(PKCS11_OBJECT_private *obj,
CK_SESSION_HANDLE session, CK_OBJECT_CLASS object_class);
+/* Reference the private object */
+extern PKCS11_OBJECT_private *pkcs11_object_ref(PKCS11_OBJECT_private *obj);
+
/* Free an object */
extern void pkcs11_object_free(PKCS11_OBJECT_private *obj);
diff --git a/src/p11_ec.c b/src/p11_ec.c
index e108504..b6b336f 100644
--- a/src/p11_ec.c
+++ b/src/p11_ec.c
@@ -50,6 +50,7 @@ typedef int (*compute_key_fn)(void *, size_t,
#endif
static compute_key_fn ossl_ecdh_compute_key;
static void (*ossl_ec_finish)(EC_KEY *);
+static int (*ossl_ec_copy)(EC_KEY *, const EC_KEY *);
static int ec_ex_index = 0;
@@ -374,13 +375,16 @@ static EVP_PKEY *pkcs11_get_evp_key_ec(PKCS11_OBJECT_private *key)
ECDSA_set_method(ec, PKCS11_get_ecdsa_method());
ECDH_set_method(ec, PKCS11_get_ecdh_method());
#endif
+ /* This creates a new EC_KEY object which requires its own key object reference */
+ key = pkcs11_object_ref(key);
+ pkcs11_set_ex_data_ec(ec, key);
}
/* TODO: Retrieve the ECDSA private key object attributes instead,
* unless the key has the "sensitive" attribute set */
- pkcs11_set_ex_data_ec(ec, key);
EVP_PKEY_set1_EC_KEY(pk, ec); /* Also increments the ec ref count */
EC_KEY_free(ec); /* Drops our reference to it */
+
return pk;
}
@@ -681,6 +685,27 @@ static int pkcs11_ec_ckey(unsigned char **out, size_t *outlen,
return 1;
}
+/* Without this, the EC_KEY objects share the same PKCS11_OBJECT_private
+ * object in ex_data and when one of them is freed, the following frees
+ * result in crashes.
+ * We need to increase the reference to the private object.
+ */
+static int pkcs11_ec_copy(EC_KEY *dest, const EC_KEY *src)
+{
+ PKCS11_OBJECT_private *srckey = NULL;
+ PKCS11_OBJECT_private *destkey = NULL;
+
+ srckey = pkcs11_get_ex_data_ec(src);
+ destkey = pkcs11_object_ref(srckey);
+
+ pkcs11_set_ex_data_ec(dest, destkey);
+
+ if (ossl_ec_copy)
+ ossl_ec_copy(dest, src);
+
+ return 1;
+}
+
#else
/**
@@ -740,7 +765,6 @@ EC_KEY_METHOD *PKCS11_get_ec_key_method(void)
{
static EC_KEY_METHOD *ops = NULL;
int (*orig_init)(EC_KEY *);
- int (*orig_copy)(EC_KEY *, const EC_KEY *);
int (*orig_set_group)(EC_KEY *, const EC_GROUP *);
int (*orig_set_private)(EC_KEY *, const BIGNUM *);
int (*orig_set_public)(EC_KEY *, const EC_POINT *);
@@ -750,9 +774,9 @@ EC_KEY_METHOD *PKCS11_get_ec_key_method(void)
alloc_ec_ex_index();
if (!ops) {
ops = EC_KEY_METHOD_new((EC_KEY_METHOD *)EC_KEY_OpenSSL());
- EC_KEY_METHOD_get_init(ops, &orig_init, &ossl_ec_finish, &orig_copy,
+ EC_KEY_METHOD_get_init(ops, &orig_init, &ossl_ec_finish, &ossl_ec_copy,
&orig_set_group, &orig_set_private, &orig_set_public);
- EC_KEY_METHOD_set_init(ops, orig_init, pkcs11_ec_finish, orig_copy,
+ EC_KEY_METHOD_set_init(ops, orig_init, pkcs11_ec_finish, pkcs11_ec_copy,
orig_set_group, orig_set_private, orig_set_public);
EC_KEY_METHOD_get_sign(ops, &orig_sign, NULL, NULL);
EC_KEY_METHOD_set_sign(ops, orig_sign, NULL, pkcs11_ecdsa_sign_sig);
diff --git a/src/p11_key.c b/src/p11_key.c
index ec7f279..c253c91 100644
--- a/src/p11_key.c
+++ b/src/p11_key.c
@@ -115,6 +115,8 @@ PKCS11_OBJECT_private *pkcs11_object_from_handle(PKCS11_SLOT_private *slot,
return NULL;
memset(obj, 0, sizeof(*obj));
+ obj->refcnt = 1;
+ pthread_mutex_init(&obj->lock, 0);
obj->object_class = object_class;
obj->object = object;
obj->slot = pkcs11_slot_ref(slot);
@@ -178,6 +180,9 @@ PKCS11_OBJECT_private *pkcs11_object_from_object(PKCS11_OBJECT_private *obj,
void pkcs11_object_free(PKCS11_OBJECT_private *obj)
{
+ if (pkcs11_atomic_add(&obj->refcnt, -1, &obj->lock) != 0)
+ return;
+
if (obj->evp_key) {
/* When the EVP object is reference count goes to zero,
* it will call this function again. */
@@ -189,6 +194,7 @@ void pkcs11_object_free(PKCS11_OBJECT_private *obj)
pkcs11_slot_unref(obj->slot);
X509_free(obj->x509);
OPENSSL_free(obj->label);
+ pthread_mutex_destroy(&obj->lock);
OPENSSL_free(obj);
}
@@ -611,6 +617,12 @@ static int pkcs11_next_key(PKCS11_CTX_private *ctx, PKCS11_SLOT_private *slot,
return 0;
}
+PKCS11_OBJECT_private *pkcs11_object_ref(PKCS11_OBJECT_private *obj)
+{
+ pkcs11_atomic_add(&obj->refcnt, 1, &obj->lock);
+ return obj;
+}
+
static int pkcs11_init_key(PKCS11_SLOT_private *slot, CK_SESSION_HANDLE session,
CK_OBJECT_HANDLE object, CK_OBJECT_CLASS type, PKCS11_KEY **ret)
{
diff --git a/tests/Makefile.am b/tests/Makefile.am
index b1bc0fb..ba16448 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -17,7 +17,8 @@ check_PROGRAMS = \
rsa-pss-sign \
rsa-oaep \
check-privkey \
- store-cert
+ store-cert \
+ dup-key
dist_check_SCRIPTS = \
rsa-testpkcs11.softhsm \
rsa-testfork.softhsm \
@@ -33,7 +34,8 @@ dist_check_SCRIPTS = \
ec-check-privkey.softhsm \
pkcs11-uri-without-token.softhsm \
search-all-matching-tokens.softhsm \
- ec-cert-store.softhsm
+ ec-cert-store.softhsm \
+ ec-copy.softhsm
dist_check_DATA = \
rsa-cert.der rsa-prvkey.der rsa-pubkey.der \
ec-cert.der ec-prvkey.der ec-pubkey.der
diff --git a/tests/dup-key.c b/tests/dup-key.c
new file mode 100644
index 0000000..1284b46
--- /dev/null
+++ b/tests/dup-key.c
@@ -0,0 +1,175 @@
+/*
+* Copyright (C) 2019 - 2022 Red Hat, Inc.
+*
+* Authors: Anderson Toshiyuki Sasaki
+* Jakub Jelen <jjelen@redhat.com>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <openssl/engine.h>
+#include <openssl/conf.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+
+static void usage(char *argv[])
+{
+ fprintf(stderr, "%s [private key URL] [module] [conf]\n", argv[0]);
+}
+
+static void display_openssl_errors(int l)
+{
+ const char *file;
+ char buf[120];
+ int e, line;
+
+ if (ERR_peek_error() == 0)
+ return;
+ fprintf(stderr, "At dup-key.c:%d:\n", l);
+
+ while ((e = ERR_get_error_line(&file, &line))) {
+ ERR_error_string(e, buf);
+ fprintf(stderr, "- SSL %s: %s:%d\n", buf, file, line);
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ ENGINE *engine = NULL;
+ EVP_PKEY *pkey = NULL;
+ EC_KEY *ec = NULL, *ec_dup = NULL;
+
+ const char *module, *efile, *privkey;
+
+ int ret = 0;
+
+ if (argc < 3){
+ printf("Too few arguments\n");
+ usage(argv);
+ return 1;
+ }
+
+ privkey = argv[1];
+ module = argv[2];
+ efile = argv[3];
+
+ ret = CONF_modules_load_file(efile, "engines", 0);
+ if (ret <= 0) {
+ fprintf(stderr, "cannot load %s\n", efile);
+ display_openssl_errors(__LINE__);
+ exit(1);
+ }
+
+ ENGINE_add_conf_module();
+#if OPENSSL_VERSION_NUMBER>=0x10100000
+ OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \
+ | OPENSSL_INIT_ADD_ALL_DIGESTS \
+ | OPENSSL_INIT_LOAD_CONFIG, NULL);
+#else
+ OpenSSL_add_all_algorithms();
+ OpenSSL_add_all_digests();
+ ERR_load_crypto_strings();
+#endif
+ ERR_clear_error();
+
+ ENGINE_load_builtin_engines();
+
+ engine = ENGINE_by_id("pkcs11");
+ if (engine == NULL) {
+ printf("Could not get engine\n");
+ display_openssl_errors(__LINE__);
+ ret = 1;
+ goto end;
+ }
+
+ if (!ENGINE_ctrl_cmd_string(engine, "VERBOSE", NULL, 0)) {
+ display_openssl_errors(__LINE__);
+ exit(1);
+ }
+
+ if (!ENGINE_ctrl_cmd_string(engine, "MODULE_PATH", module, 0)) {
+ display_openssl_errors(__LINE__);
+ exit(1);
+ }
+
+ if (!ENGINE_init(engine)) {
+ printf("Could not initialize engine\n");
+ display_openssl_errors(__LINE__);
+ ret = 1;
+ goto end;
+ }
+
+ pkey = ENGINE_load_private_key(engine, privkey, 0, 0);
+
+ if (pkey == NULL) {
+ printf("Could not load key\n");
+ display_openssl_errors(__LINE__);
+ ret = 1;
+ goto end;
+ }
+
+ switch (EVP_PKEY_base_id(pkey)) {
+ case EVP_PKEY_RSA:
+ /* TODO */
+ break;
+ case EVP_PKEY_EC:
+ ec = EVP_PKEY_get1_EC_KEY(pkey);
+ if (ec == NULL) {
+ printf("Could not get the EC_KEY\n");
+ display_openssl_errors(__LINE__);
+ ret = 1;
+ goto end;
+ }
+
+ ec_dup = EC_KEY_dup(ec);
+ if (ec_dup == NULL) {
+ printf("Could not dup EC_KEY\n");
+ display_openssl_errors(__LINE__);
+ ret = 1;
+ goto end;
+ }
+ EC_KEY_free(ec);
+ EC_KEY_free(ec_dup);
+ break;
+ }
+
+ EVP_PKEY_free(pkey);
+ /* Do it one more time */
+ pkey = ENGINE_load_private_key(engine, privkey, 0, 0);
+
+ if (pkey == NULL) {
+ printf("Could not load key\n");
+ display_openssl_errors(__LINE__);
+ ret = 1;
+ goto end;
+ }
+
+ ENGINE_finish(engine);
+
+ ret = 0;
+
+ CONF_modules_unload(1);
+end:
+ EVP_PKEY_free(pkey);
+
+ return ret;
+}
+
diff --git a/tests/ec-copy.softhsm b/tests/ec-copy.softhsm
new file mode 100755
index 0000000..17b4cda
--- /dev/null
+++ b/tests/ec-copy.softhsm
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+# Copyright (C) 2022 Red Hat, Inc.
+#
+# Authors: Jakub Jelen <jjelen@redhat.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+outdir="output.$$"
+
+# Load common test functions
+. ${srcdir}/ec-no-pubkey.sh
+
+sed -e "s|@MODULE_PATH@|${MODULE}|g" -e "s|@ENGINE_PATH@|../src/.libs/pkcs11.so|g" <"${srcdir}/engines.cnf.in" >"${outdir}/engines.cnf"
+
+export OPENSSL_ENGINES="../src/.libs/"
+PRIVATE_KEY="pkcs11:token=libp11-test;id=%01%02%03%04;object=server-key;type=private;pin-value=1234"
+
+./dup-key ${PRIVATE_KEY} ${MODULE} "${outdir}/engines.cnf"
+if test $? != 0;then
+ echo "Could not duplicate private key"
+ exit 1;
+fi
+
+rm -rf "$outdir"
+
+exit 0

Просмотреть файл

@ -0,0 +1,293 @@
From 6efcf3c52db1857aaa18741a509741519b0c5775 Mon Sep 17 00:00:00 2001
From: Doug Engert <deengert@gmail.com>
Date: Fri, 29 Jul 2022 17:54:42 -0500
Subject: [PATCH 1/3] Deffer initializing crypto routines in PKCS11 engine
until needed
Fixes:#456
bind_helper in eng_font.c is split into bind_helper and bind_helper2
The calls to ENGINE_set_RSA, ENGINE_set_EC, ENGINE_set_ECDH and
ENGINE_set_pkey_meths are moved to bind_helper2.
bind_helper2 is called from load_pubkey and load_privkey.
This in effect gets around the problem OpenSSL 3.0.x has when
it loads the pkcs11 engine from openssl.cnf, and then tries to use it
as a default provider even when no engine was specified on
the command line.
On branch deffer_init_crypto
Changes to be committed:
modified: eng_front.c
---
src/eng_front.c | 28 ++++++++++++++++++++++++----
1 file changed, 24 insertions(+), 4 deletions(-)
diff --git a/src/eng_front.c b/src/eng_front.c
index 3a3c8910..bfc35025 100644
--- a/src/eng_front.c
+++ b/src/eng_front.c
@@ -82,6 +82,8 @@ static const ENGINE_CMD_DEFN engine_cmd_defns[] = {
{0, NULL, NULL, 0}
};
+static int bind_helper2(ENGINE *e);
+
static ENGINE_CTX *get_ctx(ENGINE *engine)
{
ENGINE_CTX *ctx;
@@ -174,6 +176,7 @@ static EVP_PKEY *load_pubkey(ENGINE *engine, const char *s_key_id,
ctx = get_ctx(engine);
if (!ctx)
return 0;
+ bind_helper2(engine);
return ctx_load_pubkey(ctx, s_key_id, ui_method, callback_data);
}
@@ -186,6 +189,7 @@ static EVP_PKEY *load_privkey(ENGINE *engine, const char *s_key_id,
ctx = get_ctx(engine);
if (!ctx)
return 0;
+ bind_helper2(engine);
pkey = ctx_load_privkey(ctx, s_key_id, ui_method, callback_data);
#ifdef EVP_F_EVP_PKEY_SET1_ENGINE
/* EVP_PKEY_set1_engine() is required for OpenSSL 1.1.x,
@@ -219,6 +223,25 @@ static int bind_helper(ENGINE *e)
!ENGINE_set_ctrl_function(e, engine_ctrl) ||
!ENGINE_set_cmd_defns(e, engine_cmd_defns) ||
!ENGINE_set_name(e, PKCS11_ENGINE_NAME) ||
+
+ !ENGINE_set_load_pubkey_function(e, load_pubkey) ||
+ !ENGINE_set_load_privkey_function(e, load_privkey)) {
+ return 0;
+ } else {
+ ERR_load_ENG_strings();
+ return 1;
+ }
+}
+
+/*
+ * With OpenSSL 3.x, engines might be used because defined in openssl.cnf
+ * which will cause problems
+ * only add engine routines after a call to load keys
+ */
+
+static int bind_helper2(ENGINE *e)
+{
+ if (
#ifndef OPENSSL_NO_RSA
!ENGINE_set_RSA(e, PKCS11_get_rsa_method()) ||
#endif
@@ -235,12 +258,9 @@ static int bind_helper(ENGINE *e)
!ENGINE_set_ECDH(e, PKCS11_get_ecdh_method()) ||
#endif
#endif /* OPENSSL_VERSION_NUMBER */
- !ENGINE_set_pkey_meths(e, PKCS11_pkey_meths) ||
- !ENGINE_set_load_pubkey_function(e, load_pubkey) ||
- !ENGINE_set_load_privkey_function(e, load_privkey)) {
+ !ENGINE_set_pkey_meths(e, PKCS11_pkey_meths)) {
return 0;
} else {
- ERR_load_ENG_strings();
return 1;
}
}
From d06388774ca3846c61354835fc0fef34013db91e Mon Sep 17 00:00:00 2001
From: Doug Engert <deengert@gmail.com>
Date: Tue, 2 Aug 2022 19:36:02 -0500
Subject: [PATCH 2/3] Suggested changes
rename bind_helper2 to bind_helper_methods
remove blank line
On branch deffer_init_crypto
Changes to be committed:
modified: eng_front.c
---
src/eng_front.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/src/eng_front.c b/src/eng_front.c
index bfc35025..556b170e 100644
--- a/src/eng_front.c
+++ b/src/eng_front.c
@@ -82,7 +82,7 @@ static const ENGINE_CMD_DEFN engine_cmd_defns[] = {
{0, NULL, NULL, 0}
};
-static int bind_helper2(ENGINE *e);
+static int bind_helper_methods(ENGINE *e);
static ENGINE_CTX *get_ctx(ENGINE *engine)
{
@@ -176,7 +176,7 @@ static EVP_PKEY *load_pubkey(ENGINE *engine, const char *s_key_id,
ctx = get_ctx(engine);
if (!ctx)
return 0;
- bind_helper2(engine);
+ bind_helper_methods(engine);
return ctx_load_pubkey(ctx, s_key_id, ui_method, callback_data);
}
@@ -189,7 +189,7 @@ static EVP_PKEY *load_privkey(ENGINE *engine, const char *s_key_id,
ctx = get_ctx(engine);
if (!ctx)
return 0;
- bind_helper2(engine);
+ bind_helper_methods(engine);
pkey = ctx_load_privkey(ctx, s_key_id, ui_method, callback_data);
#ifdef EVP_F_EVP_PKEY_SET1_ENGINE
/* EVP_PKEY_set1_engine() is required for OpenSSL 1.1.x,
@@ -223,7 +223,6 @@ static int bind_helper(ENGINE *e)
!ENGINE_set_ctrl_function(e, engine_ctrl) ||
!ENGINE_set_cmd_defns(e, engine_cmd_defns) ||
!ENGINE_set_name(e, PKCS11_ENGINE_NAME) ||
-
!ENGINE_set_load_pubkey_function(e, load_pubkey) ||
!ENGINE_set_load_privkey_function(e, load_privkey)) {
return 0;
@@ -239,7 +238,7 @@ static int bind_helper(ENGINE *e)
* only add engine routines after a call to load keys
*/
-static int bind_helper2(ENGINE *e)
+static int bind_helper_methods(ENGINE *e)
{
if (
#ifndef OPENSSL_NO_RSA
From 83c0091f5b07cf2be8036974695873fa82cf76e8 Mon Sep 17 00:00:00 2001
From: Doug Engert <deengert@gmail.com>
Date: Fri, 5 Aug 2022 20:47:24 -0500
Subject: [PATCH 3/3] Fix test for $OSTYPE in test scripts
$OSTYPE varies by shell and OS. Replace "if" by case.
On branch deffer_init_crypto
Changes to be committed:
modified: pkcs11-uri-without-token.softhsm
modified: search-all-matching-tokens.softhsm
---
tests/pkcs11-uri-without-token.softhsm | 13 ++++++++-----
tests/search-all-matching-tokens.softhsm | 14 +++++++++-----
2 files changed, 17 insertions(+), 10 deletions(-)
diff --git a/tests/pkcs11-uri-without-token.softhsm b/tests/pkcs11-uri-without-token.softhsm
index 8833fa8b..da95ebfe 100755
--- a/tests/pkcs11-uri-without-token.softhsm
+++ b/tests/pkcs11-uri-without-token.softhsm
@@ -29,11 +29,14 @@ common_init
echo "Detected system: ${OSTYPE}"
-if [[ "${OSTYPE}" == "darwin"* ]]; then
- SHARED_EXT=.dylib
-else
- SHARED_EXT=.so
-fi
+case "${OSTYPE}" in
+ darwin* )
+ SHARED_EXT=.dylib
+ ;;
+ *)
+ SHARED_EXT=.so
+ ;;
+esac
sed -e "s|@MODULE_PATH@|${MODULE}|g" -e \
"s|@ENGINE_PATH@|../src/.libs/pkcs11${SHARED_EXT}|g" \
diff --git a/tests/search-all-matching-tokens.softhsm b/tests/search-all-matching-tokens.softhsm
index 915e7c67..3cd26a66 100755
--- a/tests/search-all-matching-tokens.softhsm
+++ b/tests/search-all-matching-tokens.softhsm
@@ -45,11 +45,15 @@ create_devices $NUM_DEVICES $PIN $PUK "libp11-test" "label"
echo "Detected system: ${OSTYPE}"
-if [[ "${OSTYPE}" == "darwin"* ]]; then
- SHARED_EXT=.dylib
-else
- SHARED_EXT=.so
-fi
+
+case "${OSTYPE}" in
+ darwin* )
+ SHARED_EXT=.dylib
+ ;;
+ *)
+ SHARED_EXT=.so
+ ;;
+esac
sed -e "s|@MODULE_PATH@|${MODULE}|g" -e \
"s|@ENGINE_PATH@|../src/.libs/pkcs11${SHARED_EXT}|g" \
From feb22a666ca361adb6f454bcb541281f8e9615f8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Trojnara?= <Michal.Trojnara@stunnel.org>
Date: Sat, 6 Aug 2022 23:14:55 +0200
Subject: [PATCH] Also bind helper methods in engine_ctrl()
---
src/eng_front.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/eng_front.c b/src/eng_front.c
index 556b170..fd6940f 100644
--- a/src/eng_front.c
+++ b/src/eng_front.c
@@ -209,6 +209,7 @@ static int engine_ctrl(ENGINE *engine, int cmd, long i, void *p, void (*f) ())
ctx = get_ctx(engine);
if (!ctx)
return 0;
+ bind_helper_methods(engine);
return ctx_engine_ctrl(ctx, cmd, i, p, f);
}
commit 580c12b78b63d88010a6178d7c4c58186938c479
Author: Dominique Leuenberger <dimstar@opensuse.org>
Date: Tue Jun 6 14:27:46 2023 +0200
Detect openSSL 3.1; compatible to openSSL 3.0
diff --git a/configure.ac b/configure.ac
index d6b0ee9..b96979d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -33,7 +33,7 @@ AC_C_BIGENDIAN
# issues with applications linking to new openssl, old libp11, and vice versa
case "`$PKG_CONFIG --modversion --silence-errors libcrypto || \
$PKG_CONFIG --modversion openssl`" in
- 3.0.*) # Predicted engines directory prefix for OpenSSL 3.x
+ 3.1.*|3.0.*) # Predicted engines directory prefix for OpenSSL 3.x
LIBP11_LT_OLDEST="3"
debian_ssl_prefix="openssl-3.0.0";;
1.1.*) # Predicted engines directory prefix for OpenSSL 1.1.x
commit 74497e0fa5b69b15790d6697e1ebce13af842d4c
Author: Mike Gilbert <floppym@gentoo.org>
Date: Thu Jul 13 13:52:54 2023 -0400
configure: treat all openssl-3.x releases the same
OpenSSL's soversion will not change for any 3.x minor release.
https://www.openssl.org/policies/general/versioning-policy.html
diff --git a/configure.ac b/configure.ac
index b96979d..c344e84 100644
--- a/configure.ac
+++ b/configure.ac
@@ -33,7 +33,7 @@ AC_C_BIGENDIAN
# issues with applications linking to new openssl, old libp11, and vice versa
case "`$PKG_CONFIG --modversion --silence-errors libcrypto || \
$PKG_CONFIG --modversion openssl`" in
- 3.1.*|3.0.*) # Predicted engines directory prefix for OpenSSL 3.x
+ 3.*) # Predicted engines directory prefix for OpenSSL 3.x
LIBP11_LT_OLDEST="3"
debian_ssl_prefix="openssl-3.0.0";;
1.1.*) # Predicted engines directory prefix for OpenSSL 1.1.x

Просмотреть файл

@ -1,5 +1,5 @@
{
"Signatures": {
"libp11-0.4.10.tar.gz": "639ea43c3341e267214b712e1e5e12397fd2d350899e673dd1220f3c6b8e3db4"
"libp11-0.4.12.tar.gz": "1e1a2533b3fcc45fde4da64c9c00261b1047f14c3f911377ebd1b147b3321cfd"
}
}

Просмотреть файл

@ -1,35 +1,44 @@
Version: 0.4.12
Release: 1%{?dist}
# Define the directory where the OpenSSL engines are installed
%global enginesdir %{_libdir}/engines-1.1
Summary: A PKCS#11 engine for use with OpenSSL
%global enginesdir %{_libdir}/engines-3
Name: openssl-pkcs11
Version: 0.4.10
Release: 10%{?dist}
Summary: A PKCS#11 engine for use with OpenSSL
# The source code is LGPLv2+ except eng_back.c and eng_parse.c which are BSD
License: LGPLv2+ AND BSD
# There are parts licensed with OpenSSL license too
License: LGPL-2.1-or-later AND BSD-2-Clause AND OpenSSL
Vendor: Microsoft Corporation
Distribution: Azure Linux
URL: https://github.com/OpenSC/libp11
Source0: https://github.com/OpenSC/libp11/releases/download/libp11-%{version}/libp11-%{version}.tar.gz
Patch0: openssl-pkcs11-0.4.10-various-bug-fixes.patch
Patch1: openssl-pkcs11-0.4.10-search-objects-in-all-matching-tokens.patch
Patch2: openssl-pkcs11-0.4.10-add-support-pin-source.patch
Patch3: openssl-pkcs11-0.4.10-set-rsa-flag-ext-pkey.patch
# Downstream only for now to make RSA operations working in FIPS mode
Patch4: openssl-pkcs11-0.4.10-set-rsa-fips-method-flag.patch
BuildRequires: autoconf
BuildRequires: automake
BuildRequires: libtool
# unbreak operation when some other engine is present in openssl.cnf
# https://github.com/OpenSC/libp11/pull/460
# https://github.com/OpenSC/libp11/commit/feb22a66
# 580c12b78b63d88010a6178d7c4c58186938c479
# 74497e0fa5b69b15790d6697e1ebce13af842d4c
Patch5: openssl-pkcs11-ossl3.patch
Patch6: openssl-pkcs11-ec-copy.patch
BuildRequires: make
BuildRequires: autoconf automake libtool
BuildRequires: openssl-devel
BuildRequires: openssl >= 1.0.2
BuildRequires: openssl >= 3.0.0
BuildRequires: pkgconfig
BuildRequires: pkgconfig(p11-kit-1)
BuildRequires: doxygen
%if 0%{?with_check}
BuildRequires: procps-ng
BuildRequires: opensc
BuildRequires: softhsm
# Needed for testsuite
BuildRequires: softhsm opensc procps-ng
%endif
Requires: openssl-libs >= 1.0.2
BuildRequires: doxygen
Requires: p11-kit-trust
Requires: openssl-libs >= 3.0.0
# Package renamed from libp11 to openssl-pkcs11 in release 0.4.7-4
Provides: libp11%{?_isa} = %{version}-%{release}
@ -50,7 +59,6 @@ optional and can be loaded by configuration file, command line or through the
OpenSSL ENGINE API.
# The libp11-devel subpackage was reintroduced in libp11-0.4.7-7 for Fedora
%package -n libp11-devel
Summary: Files for developing with libp11
Requires: %{name} = %{version}-%{release}
@ -65,9 +73,7 @@ developing applications that use libp11.
%build
autoreconf -fvi
export CFLAGS="%{optflags}"
%configure --disable-static --enable-api-doc --with-enginesdir=%{enginesdir}
make V=1 %{?_smp_mflags}
%install
@ -82,7 +88,8 @@ rm -f %{buildroot}%{enginesdir}/*.la
rm -rf %{buildroot}%{_docdir}/libp11/
%check
make check %{?_smp_mflags} || { cat tests/*.log; false; }
# to run tests use "--with check". They crash now in softhsm
make check %{?_smp_mflags} || if [ $? -ne 0 ]; then cat tests/*.log; exit 1; fi;
%ldconfig_scriptlets
@ -99,6 +106,10 @@ make check %{?_smp_mflags} || { cat tests/*.log; false; }
%{_includedir}/*.h
%changelog
* Thu May 09 2024 Tobias Brick <tobiasb@microsoft.com> - 0.4.12-1
- Rebase from Fedora 40
- Removed fedora-based macros
* Tue Sep 26 2023 Pawel Winogrodzki <pawelwi@microsoft.com> - 0.4.10-10
- Removing 'exit' calls from the '%%check' section.

Просмотреть файл

@ -15233,8 +15233,8 @@
"type": "other",
"other": {
"name": "openssl-pkcs11",
"version": "0.4.10",
"downloadUrl": "https://github.com/OpenSC/libp11/releases/download/libp11-0.4.10/libp11-0.4.10.tar.gz"
"version": "0.4.12",
"downloadUrl": "https://github.com/OpenSC/libp11/releases/download/libp11-0.4.12/libp11-0.4.12.tar.gz"
}
}
},