From 22d5836aac2435f5fd9c0969ea017fcb9d554bf3 Mon Sep 17 00:00:00 2001 From: Tobias Deiminger Date: Fri, 27 Jun 2025 08:56:21 +0200 Subject: [PATCH 1/2] Skip trailing newlines in pin-source files Text editors usually append '\n' to the last line when saving a text file. Also 'echo "mypin" > ~/pinfile.txt' appends a newline. It's therefore likely we encounter PIN files where the PIN is delimited with '\n'. Currently, PIN validation would fail in such a case since libp11 passes on the newline to PKCS#11 modules as if it was part of the PIN. We now ignore trailing newlines. There's no specification mandating this, but since PINs are meant for interactive input it seems safe to assume PINs will never be allowed to contain a trailing newline. Further, the pkcs11-provider project is doing the same in their src/util.c:get_pin_file. The change is backwards compatible. PIN files without trailing newline will work as well. --- src/util_uri.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/util_uri.c b/src/util_uri.c index b8b6a3b0..ec345b0e 100644 --- a/src/util_uri.c +++ b/src/util_uri.c @@ -734,11 +734,23 @@ static int read_from_file(UTIL_CTX *ctx, return 0; } if (BIO_gets(fp, txt, (int)*field_len + 1) > 0) { - memcpy(field, txt, *field_len); *field_len = strlen(txt); } else { *field_len = 0; + goto done; } + + /* files may contain trailing newlines, remove them */ + while (*field_len > 0) { + if (txt[*field_len - 1] == '\n' || txt[*field_len - 1] == '\r') { + (*field_len)--; + } else { + break; + } + } + memcpy(field, txt, *field_len); + +done: OPENSSL_free(txt); BIO_free(fp); From a55a906ca6fb0357be498bde4f4fe130f70da7aa Mon Sep 17 00:00:00 2001 From: Tobias Deiminger Date: Fri, 27 Jun 2025 11:38:01 +0200 Subject: [PATCH 2/2] Add tests dedicated to pin-source --- tests/Makefile.am | 1 + tests/pkcs11-uri-pin-source.softhsm | 58 +++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100755 tests/pkcs11-uri-pin-source.softhsm diff --git a/tests/Makefile.am b/tests/Makefile.am index a7f4ecb5..b2597fa1 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -47,6 +47,7 @@ dist_check_SCRIPTS = \ ec-keygen.softhsm \ fork-change-slot.softhsm \ case-insensitive.softhsm \ + pkcs11-uri-pin-source.softhsm \ pkcs11-uri-without-token.softhsm \ search-all-matching-tokens.softhsm \ provider-rsa-evp-sign.softhsm \ diff --git a/tests/pkcs11-uri-pin-source.softhsm b/tests/pkcs11-uri-pin-source.softhsm new file mode 100755 index 00000000..036c8df0 --- /dev/null +++ b/tests/pkcs11-uri-pin-source.softhsm @@ -0,0 +1,58 @@ +#!/bin/bash + +# Copyright (C) 2025 Tobias Deiminger +# +# 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 + +outdir="output.$$" + +URL="pkcs11:token=libp11-0;id=%01%02%03%04;object=server-key-0" + +# Load common test functions +. ${srcdir}/common.sh + +# Generate test input files +printf ${PIN} > $outdir/pin.txt +printf "${PIN}\n" > $outdir/pin_with_trailing_newline.txt + +# Do the token initialization +init_token "rsa" "1" "libp11" ${ID} "server-key" "privkey" "pubkey" "cert" + +# Load openssl settings +TEMP_LD_LIBRARY_PATH=${LD_LIBRARY_PATH} +. ${srcdir}/openssl-settings.sh + +# Run the test +for PIN_SOURCE_ATTR in \ + "pin-source=$outdir/pin.txt" \ + "pin-source=$outdir/pin_with_trailing_newline.txt" \ + "pin-source=file:$outdir/pin.txt" \ + "pin-source=file:$outdir/pin_with_trailing_newline.txt" +do + + ${WRAPPER} ./check-privkey "${URL};type=cert" "${URL};type=private;${PIN_SOURCE_ATTR}" \ + ${MODULE} "${outdir}/engines.cnf" + if [[ $? -ne 0 ]]; then + echo "The private key loading couldn't get the public key from the certificate URL" + exit 1 + fi + +done + +# Restore settings +export LD_LIBRARY_PATH=${TEMP_LD_LIBRARY_PATH} + +rm -rf "$outdir" + +exit 0